Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Unified Diff: third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp

Issue 2747163002: Bindings: Manage multiple DOMWrapperWorlds for worklets (2) (Closed)
Patch Set: address review comments & may fix use-after-free bug in the test Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3206ef0269173949caa9bb72da75ea14f8e6d2d6
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
@@ -0,0 +1,161 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "bindings/core/v8/DOMWrapperWorld.h"
+
+#include "bindings/core/v8/V8BindingForTesting.h"
+#include "bindings/core/v8/V8Initializer.h"
+#include "bindings/core/v8/V8PerIsolateData.h"
+#include "core/workers/WorkerBackingThread.h"
+#include "platform/CrossThreadFunctional.h"
+#include "platform/WebTaskRunner.h"
+#include "platform/WebThreadSupportingGC.h"
+#include "platform/testing/UnitTestHelpers.h"
+#include "public/platform/Platform.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+namespace {
+
+Vector<RefPtr<DOMWrapperWorld>> createIsolatedWorlds(v8::Isolate* isolate) {
+ Vector<RefPtr<DOMWrapperWorld>> worlds;
+ worlds.push_back(DOMWrapperWorld::ensureIsolatedWorld(
+ isolate, DOMWrapperWorld::WorldId::MainWorldId + 1));
+ worlds.push_back(DOMWrapperWorld::ensureIsolatedWorld(
+ isolate, DOMWrapperWorld::WorldId::IsolatedWorldIdLimit - 1));
+ EXPECT_TRUE(worlds[0]->isIsolatedWorld());
+ EXPECT_TRUE(worlds[1]->isIsolatedWorld());
+ EXPECT_EQ(worlds[0],
+ DOMWrapperWorld::fromWorldId(isolate, worlds[0]->worldId()));
+ EXPECT_EQ(worlds[1],
+ DOMWrapperWorld::fromWorldId(isolate, worlds[1]->worldId()));
+ return worlds;
+}
+
+Vector<RefPtr<DOMWrapperWorld>> createWorlds(v8::Isolate* isolate) {
+ Vector<RefPtr<DOMWrapperWorld>> worlds;
+ worlds.push_back(
+ DOMWrapperWorld::create(isolate, DOMWrapperWorld::WorldType::Worker));
+ worlds.push_back(
+ DOMWrapperWorld::create(isolate, DOMWrapperWorld::WorldType::Worker));
+ worlds.push_back(DOMWrapperWorld::create(
+ isolate, DOMWrapperWorld::WorldType::GarbageCollector));
+ EXPECT_TRUE(worlds[0]->isWorkerWorld());
+ EXPECT_TRUE(worlds[1]->isWorkerWorld());
+ EXPECT_FALSE(worlds[2]->isWorkerWorld());
+
+ // World ids should be unique.
+ HashSet<int> worldIds;
+ EXPECT_TRUE(worldIds.insert(worlds[0]->worldId()).isNewEntry);
+ EXPECT_TRUE(worldIds.insert(worlds[1]->worldId()).isNewEntry);
+ EXPECT_TRUE(worldIds.insert(worlds[2]->worldId()).isNewEntry);
+ EXPECT_EQ(worlds[0],
+ DOMWrapperWorld::fromWorldId(isolate, worlds[0]->worldId()));
+ EXPECT_EQ(worlds[1],
+ DOMWrapperWorld::fromWorldId(isolate, worlds[1]->worldId()));
+ EXPECT_EQ(worlds[2],
+ DOMWrapperWorld::fromWorldId(isolate, worlds[2]->worldId()));
+
+ return worlds;
+}
+
+void workerThreadFunc(WorkerBackingThread* thread,
+ RefPtr<WebTaskRunner> mainThreadTaskRunner) {
+ thread->initialize();
+
+ // Worlds on the main thread should not be visible from the worker thread.
+ Vector<RefPtr<DOMWrapperWorld>> retrievedWorlds;
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_TRUE(retrievedWorlds.isEmpty());
+
+ // Create worlds on the worker thread and verify them.
+ Vector<RefPtr<DOMWrapperWorld>> worlds = createWorlds(thread->isolate());
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_EQ(worlds.size(), retrievedWorlds.size());
+ retrievedWorlds.clear();
+
+ // Dispose of the last world.
+ worlds.pop_back();
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_EQ(worlds.size(), retrievedWorlds.size());
+
+ // Dispose of remaining worlds.
+ for (RefPtr<DOMWrapperWorld>& world : worlds) {
+ if (world->isWorkerWorld())
+ world->dispose();
+ }
+ worlds.clear();
+
+ thread->shutdown();
+ mainThreadTaskRunner->postTask(BLINK_FROM_HERE,
+ crossThreadBind(&testing::exitRunLoop));
+}
+
+TEST(DOMWrapperWorldTest, Basic) {
+ V8TestingScope scope;
+
+ // Create the main world and verify it.
+ DOMWrapperWorld& mainWorld = DOMWrapperWorld::mainWorld();
+ EXPECT_TRUE(mainWorld.isMainWorld());
+ EXPECT_FALSE(DOMWrapperWorld::nonMainWorldsExistInMainThread());
+ Vector<RefPtr<DOMWrapperWorld>> retrievedWorlds;
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_EQ(1u, retrievedWorlds.size());
+ EXPECT_TRUE(retrievedWorlds[0]->isMainWorld());
+ EXPECT_EQ(&mainWorld,
+ DOMWrapperWorld::fromWorldId(scope.isolate(), mainWorld.worldId()));
+ retrievedWorlds.clear();
+
+ // Create isolated worlds and verify them.
+ Vector<RefPtr<DOMWrapperWorld>> isolatedWorlds =
+ createIsolatedWorlds(scope.isolate());
+ EXPECT_TRUE(DOMWrapperWorld::nonMainWorldsExistInMainThread());
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_EQ(isolatedWorlds.size() + 1, retrievedWorlds.size());
+
+ // Create other worlds and verify them.
+ Vector<RefPtr<DOMWrapperWorld>> worlds = createWorlds(scope.isolate());
+ EXPECT_TRUE(DOMWrapperWorld::nonMainWorldsExistInMainThread());
+ retrievedWorlds.clear();
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_EQ(isolatedWorlds.size() + worlds.size() + 1, retrievedWorlds.size());
+ retrievedWorlds.clear();
+
+ // Start a worker thread and create worlds on that.
+ std::unique_ptr<WorkerBackingThread> thread =
+ WorkerBackingThread::create("DOMWrapperWorld test thread");
+ RefPtr<WebTaskRunner> mainThreadTaskRunner =
+ Platform::current()->currentThread()->getWebTaskRunner();
+ thread->backingThread().postTask(
+ BLINK_FROM_HERE,
+ crossThreadBind(&workerThreadFunc, crossThreadUnretained(thread.get()),
+ std::move(mainThreadTaskRunner)));
+ testing::enterRunLoop();
+
+ // Worlds on the worker thread should not be visible from the main thread.
+ EXPECT_TRUE(DOMWrapperWorld::nonMainWorldsExistInMainThread());
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_EQ(isolatedWorlds.size() + worlds.size() + 1, retrievedWorlds.size());
+ retrievedWorlds.clear();
+
+ // Dispose of the isolated worlds.
+ isolatedWorlds.clear();
+ EXPECT_TRUE(DOMWrapperWorld::nonMainWorldsExistInMainThread());
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_EQ(worlds.size() + 1, retrievedWorlds.size());
+ retrievedWorlds.clear();
+
+ // Dispose of the other worlds.
+ for (RefPtr<DOMWrapperWorld>& world : worlds) {
+ if (world->isWorkerWorld())
+ world->dispose();
+ }
+ worlds.clear();
+ EXPECT_FALSE(DOMWrapperWorld::nonMainWorldsExistInMainThread());
+ DOMWrapperWorld::allWorldsInCurrentThread(retrievedWorlds);
+ EXPECT_EQ(1u, retrievedWorlds.size());
+}
+
+} // namespace
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698