Commit 9d50187c authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

v8binding: Stabilize DOMWrapperWorldTest

DOMWrapperWorld is implemented with a few thread static variables
and its behaviors depend on other threads.  Makes the test
expectations independent from other threads.

Bug: 874484
Change-Id: I3c93ab89c2fd4db67d3380251b9da06cd96991c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2420171Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809716}
parent 5e56b770
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include <algorithm>
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
...@@ -19,39 +21,6 @@ ...@@ -19,39 +21,6 @@
namespace blink { namespace blink {
namespace { namespace {
Vector<scoped_refptr<DOMWrapperWorld>> CreateIsolatedWorlds(
v8::Isolate* isolate) {
Vector<scoped_refptr<DOMWrapperWorld>> worlds;
worlds.push_back(DOMWrapperWorld::EnsureIsolatedWorld(
isolate, DOMWrapperWorld::kMainWorldId + 1));
worlds.push_back(DOMWrapperWorld::EnsureIsolatedWorld(
isolate, DOMWrapperWorld::kDOMWrapperWorldEmbedderWorldIdLimit - 1));
EXPECT_TRUE(worlds[0]->IsIsolatedWorld());
EXPECT_TRUE(worlds[1]->IsIsolatedWorld());
return worlds;
}
Vector<scoped_refptr<DOMWrapperWorld>> CreateWorlds(v8::Isolate* isolate) {
Vector<scoped_refptr<DOMWrapperWorld>> worlds;
worlds.push_back(
DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker));
worlds.push_back(
DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker));
worlds.push_back(
DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker));
EXPECT_TRUE(worlds[0]->IsWorkerWorld());
EXPECT_TRUE(worlds[1]->IsWorkerWorld());
EXPECT_TRUE(worlds[2]->IsWorkerWorld());
// World ids should be unique.
HashSet<int32_t> world_ids;
EXPECT_TRUE(world_ids.insert(worlds[0]->GetWorldId()).is_new_entry);
EXPECT_TRUE(world_ids.insert(worlds[1]->GetWorldId()).is_new_entry);
EXPECT_TRUE(world_ids.insert(worlds[2]->GetWorldId()).is_new_entry);
return worlds;
}
void WorkerThreadFunc( void WorkerThreadFunc(
WorkerBackingThread* thread, WorkerBackingThread* thread,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) { scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) {
...@@ -59,23 +28,26 @@ void WorkerThreadFunc( ...@@ -59,23 +28,26 @@ void WorkerThreadFunc(
WorkerBackingThreadStartupData::CreateDefault()); WorkerBackingThreadStartupData::CreateDefault());
// Worlds on the main thread should not be visible from the worker thread. // Worlds on the main thread should not be visible from the worker thread.
Vector<scoped_refptr<DOMWrapperWorld>> retrieved_worlds; Vector<scoped_refptr<DOMWrapperWorld>> initial_worlds;
DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds); DOMWrapperWorld::AllWorldsInCurrentThread(initial_worlds);
EXPECT_TRUE(retrieved_worlds.IsEmpty()); EXPECT_TRUE(initial_worlds.IsEmpty());
// Create worlds on the worker thread and verify them. // Create worlds on the worker thread and verify them.
Vector<scoped_refptr<DOMWrapperWorld>> worlds = v8::Isolate* isolate = thread->GetIsolate();
CreateWorlds(thread->GetIsolate()); auto worker_world1 =
DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds); DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
EXPECT_EQ(worlds.size(), retrieved_worlds.size()); auto worker_world2 =
retrieved_worlds.clear(); DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
Vector<scoped_refptr<DOMWrapperWorld>> worlds;
DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
EXPECT_EQ(worlds.size(), initial_worlds.size() + 2);
worlds.clear();
// Dispose of remaining worlds. // Dispose of remaining worlds.
for (scoped_refptr<DOMWrapperWorld>& world : worlds) { worker_world1->Dispose();
if (world->IsWorkerWorld()) worker_world2->Dispose();
world->Dispose(); worker_world1.reset();
} worker_world2.reset();
worlds.clear();
thread->ShutdownOnBackingThread(); thread->ShutdownOnBackingThread();
PostCrossThreadTask(*main_thread_task_runner, FROM_HERE, PostCrossThreadTask(*main_thread_task_runner, FROM_HERE,
...@@ -83,33 +55,70 @@ void WorkerThreadFunc( ...@@ -83,33 +55,70 @@ void WorkerThreadFunc(
} }
TEST(DOMWrapperWorldTest, Basic) { TEST(DOMWrapperWorldTest, Basic) {
// Create the main world and verify it. // Initial setup
DOMWrapperWorld& main_world = DOMWrapperWorld::MainWorld(); DOMWrapperWorld& main_world = DOMWrapperWorld::MainWorld();
EXPECT_TRUE(main_world.IsMainWorld()); EXPECT_TRUE(main_world.IsMainWorld());
EXPECT_FALSE(DOMWrapperWorld::NonMainWorldsExistInMainThread()); Vector<scoped_refptr<DOMWrapperWorld>> initial_worlds;
Vector<scoped_refptr<DOMWrapperWorld>> retrieved_worlds; DOMWrapperWorld::AllWorldsInCurrentThread(initial_worlds);
DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds); int32_t used_isolated_world_id = DOMWrapperWorld::kMainWorldId;
EXPECT_EQ(1u, retrieved_worlds.size()); for (const auto& world : initial_worlds) {
EXPECT_TRUE(retrieved_worlds[0]->IsMainWorld()); if (world->IsIsolatedWorld()) {
retrieved_worlds.clear(); used_isolated_world_id =
std::max(used_isolated_world_id, world->GetWorldId());
// Create isolated worlds and verify them. }
}
ASSERT_TRUE(DOMWrapperWorld::IsIsolatedWorldId(used_isolated_world_id + 1));
V8TestingScope scope; V8TestingScope scope;
Vector<scoped_refptr<DOMWrapperWorld>> isolated_worlds = v8::Isolate* isolate = scope.GetIsolate();
CreateIsolatedWorlds(scope.GetIsolate());
// Isolated worlds
auto isolated_world1 =
DOMWrapperWorld::EnsureIsolatedWorld(isolate, used_isolated_world_id + 1);
auto isolated_world2 =
DOMWrapperWorld::EnsureIsolatedWorld(isolate, used_isolated_world_id + 2);
EXPECT_TRUE(isolated_world1->IsIsolatedWorld());
EXPECT_TRUE(isolated_world2->IsIsolatedWorld());
Vector<scoped_refptr<DOMWrapperWorld>> worlds;
EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread()); EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds); DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
EXPECT_EQ(isolated_worlds.size() + 1, retrieved_worlds.size()); EXPECT_EQ(worlds.size(), initial_worlds.size() + 2);
worlds.clear();
isolated_world1.reset();
isolated_world2.reset();
DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
EXPECT_EQ(worlds.size(), initial_worlds.size());
worlds.clear();
// Create other worlds and verify them. // Worker worlds
Vector<scoped_refptr<DOMWrapperWorld>> worlds = auto worker_world1 =
CreateWorlds(scope.GetIsolate()); DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
auto worker_world2 =
DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
auto worker_world3 =
DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
EXPECT_TRUE(worker_world1->IsWorkerWorld());
EXPECT_TRUE(worker_world2->IsWorkerWorld());
EXPECT_TRUE(worker_world3->IsWorkerWorld());
HashSet<int32_t> worker_world_ids;
EXPECT_TRUE(
worker_world_ids.insert(worker_world1->GetWorldId()).is_new_entry);
EXPECT_TRUE(
worker_world_ids.insert(worker_world2->GetWorldId()).is_new_entry);
EXPECT_TRUE(
worker_world_ids.insert(worker_world3->GetWorldId()).is_new_entry);
EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread()); EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
retrieved_worlds.clear(); DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds); EXPECT_EQ(worlds.size(), initial_worlds.size() + 3);
EXPECT_EQ(isolated_worlds.size() + worlds.size() + 1, worlds.clear();
retrieved_worlds.size()); worker_world1->Dispose();
retrieved_worlds.clear(); worker_world2->Dispose();
worker_world3->Dispose();
worker_world1.reset();
worker_world2.reset();
worker_world3.reset();
DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
EXPECT_EQ(worlds.size(), initial_worlds.size());
worlds.clear();
// Start a worker thread and create worlds on that. // Start a worker thread and create worlds on that.
std::unique_ptr<WorkerBackingThread> thread = std::unique_ptr<WorkerBackingThread> thread =
...@@ -125,28 +134,9 @@ TEST(DOMWrapperWorldTest, Basic) { ...@@ -125,28 +134,9 @@ TEST(DOMWrapperWorldTest, Basic) {
test::EnterRunLoop(); test::EnterRunLoop();
// Worlds on the worker thread should not be visible from the main thread. // Worlds on the worker thread should not be visible from the main thread.
EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread()); DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds); EXPECT_EQ(worlds.size(), initial_worlds.size());
EXPECT_EQ(isolated_worlds.size() + worlds.size() + 1,
retrieved_worlds.size());
retrieved_worlds.clear();
// Dispose of the isolated worlds.
isolated_worlds.clear();
EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
EXPECT_EQ(worlds.size() + 1, retrieved_worlds.size());
retrieved_worlds.clear();
// Dispose of the other worlds.
for (scoped_refptr<DOMWrapperWorld>& world : worlds) {
if (world->IsWorkerWorld())
world->Dispose();
}
worlds.clear(); worlds.clear();
EXPECT_FALSE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
EXPECT_EQ(1u, retrieved_worlds.size());
} }
} // namespace } // namespace
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment