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

Side by Side Diff: third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp

Issue 1494483002: Revert of compositor-worker: Refactor CompositorWorkerManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "modules/compositorworker/CompositorWorkerThread.h"
7
8 #include "bindings/core/v8/ScriptSourceCode.h"
9 #include "bindings/core/v8/V8GCController.h"
10 #include "core/inspector/ConsoleMessage.h"
11 #include "core/testing/DummyPageHolder.h"
12 #include "core/workers/WorkerLoaderProxy.h"
13 #include "core/workers/WorkerObjectProxy.h"
14 #include "core/workers/WorkerThreadStartupData.h"
15 #include "platform/NotImplemented.h"
16 #include "platform/ThreadSafeFunctional.h"
17 #include "platform/heap/Handle.h"
18 #include "platform/testing/TestingPlatformSupport.h"
19 #include "platform/testing/UnitTestHelpers.h"
20 #include "public/platform/Platform.h"
21 #include "public/platform/WebWaitableEvent.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace blink {
25 namespace {
26
27 class TestCompositorWorkerThread : public CompositorWorkerThread {
28 public:
29 TestCompositorWorkerThread(WorkerLoaderProxyProvider* loaderProxyProvider, W orkerObjectProxy& objectProxy, double timeOrigin, WebWaitableEvent* startEvent)
30 : CompositorWorkerThread(WorkerLoaderProxy::create(loaderProxyProvider), objectProxy, timeOrigin)
31 , m_startEvent(startEvent)
32 {
33 }
34
35 ~TestCompositorWorkerThread() override {}
36
37 void setCallbackAfterV8Termination(PassOwnPtr<Function<void()>> callback)
38 {
39 m_v8TerminationCallback = callback;
40 }
41
42 private:
43 // WorkerThread:
44 void didStartRunLoop() override
45 {
46 m_startEvent->signal();
47 }
48 void terminateV8Execution() override
49 {
50 CompositorWorkerThread::terminateV8Execution();
51 if (m_v8TerminationCallback)
52 (*m_v8TerminationCallback)();
53 }
54
55 void willDestroyIsolate() override
56 {
57 v8::Isolate::GetCurrent()->RequestGarbageCollectionForTesting(v8::Isolat e::kFullGarbageCollection);
58 Heap::collectAllGarbage();
59 CompositorWorkerThread::willDestroyIsolate();
60 }
61
62 WebWaitableEvent* m_startEvent;
63 OwnPtr<Function<void()>> m_v8TerminationCallback;
64 };
65
66 // A null WorkerObjectProxy, supplied when creating CompositorWorkerThreads.
67 class TestCompositorWorkerObjectProxy : public WorkerObjectProxy {
68 public:
69 static PassOwnPtr<TestCompositorWorkerObjectProxy> create(ExecutionContext* context)
70 {
71 return adoptPtr(new TestCompositorWorkerObjectProxy(context));
72 }
73
74 // (Empty) WorkerReportingProxy implementation:
75 virtual void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, int exceptionId) {}
76 void reportConsoleMessage(PassRefPtrWillBeRawPtr<ConsoleMessage>) override { }
77 void postMessageToPageInspector(const String&) override {}
78 void postWorkerConsoleAgentEnabled() override {}
79
80 void didEvaluateWorkerScript(bool success) override {}
81 void workerGlobalScopeStarted(WorkerGlobalScope*) override {}
82 void workerGlobalScopeClosed() override {}
83 void workerThreadTerminated() override {}
84 void willDestroyWorkerGlobalScope() override {}
85
86 ExecutionContext* executionContext() override { return m_executionContext.ge t(); }
87
88 private:
89 TestCompositorWorkerObjectProxy(ExecutionContext* context)
90 : WorkerObjectProxy(nullptr)
91 , m_executionContext(context)
92 {
93 }
94
95 RefPtrWillBePersistent<ExecutionContext> m_executionContext;
96 };
97
98 class CompositorWorkerTestPlatform : public TestingPlatformSupport {
99 public:
100 CompositorWorkerTestPlatform()
101 : m_thread(adoptPtr(m_oldPlatform->createThread("Compositor")))
102 {
103 }
104
105 WebThread* compositorThread() const override
106 {
107 return m_thread.get();
108 }
109
110 WebWaitableEvent* createWaitableEvent(
111 WebWaitableEvent::ResetPolicy policy,
112 WebWaitableEvent::InitialState state) override
113 {
114 return m_oldPlatform->createWaitableEvent(policy, state);
115 }
116
117 private:
118 OwnPtr<WebThread> m_thread;
119 };
120
121 } // namespace
122
123 class CompositorWorkerThreadTest : public ::testing::Test {
124 public:
125 void SetUp() override
126 {
127 m_page = DummyPageHolder::create();
128 m_objectProxy = TestCompositorWorkerObjectProxy::create(&m_page->documen t());
129 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/"));
130 }
131
132 void TearDown() override
133 {
134 ASSERT(!hasThread());
135 ASSERT(!hasIsolate());
136 m_page.clear();
137 }
138
139 PassRefPtr<TestCompositorWorkerThread> createCompositorWorker(WebWaitableEve nt* startEvent)
140 {
141 TestCompositorWorkerThread* workerThread = new TestCompositorWorkerThrea d(nullptr, *m_objectProxy, 0, startEvent);
142 OwnPtrWillBeRawPtr<WorkerClients> clients = nullptr;
143 workerThread->start(WorkerThreadStartupData::create(
144 KURL(ParsedURLString, "http://fake.url/"),
145 "fake user agent",
146 "//fake source code",
147 nullptr,
148 DontPauseWorkerGlobalScopeOnStart,
149 adoptPtr(new Vector<CSPHeaderAndType>()),
150 m_securityOrigin.get(),
151 clients.release(),
152 V8CacheOptionsDefault));
153 return adoptRef(workerThread);
154 }
155
156 void createWorkerAdapter(RefPtr<CompositorWorkerThread>* workerThread, WebWa itableEvent* creationEvent)
157 {
158 *workerThread = createCompositorWorker(creationEvent);
159 }
160
161 // Attempts to run some simple script for |worker|.
162 void checkWorkerCanExecuteScript(WorkerThread* worker)
163 {
164 OwnPtr<WebWaitableEvent> waitEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
165 worker->backingThread().platformThread().taskRunner()->postTask(BLINK_FR OM_HERE, threadSafeBind(&CompositorWorkerThreadTest::executeScriptInWorker, Allo wCrossThreadAccess(this),
166 AllowCrossThreadAccess(worker), AllowCrossThreadAccess(waitEvent.get ())));
167 waitEvent->wait();
168 }
169
170 void waitForWaitableEventAfterIteratingCurrentLoop(WebWaitableEvent* waitEve nt)
171 {
172 testing::runPendingTasks();
173 waitEvent->wait();
174 }
175
176 bool hasThread() const
177 {
178 return CompositorWorkerThread::hasThreadForTest();
179 }
180
181 bool hasIsolate() const
182 {
183 return CompositorWorkerThread::hasIsolateForTest();
184 }
185
186 private:
187 void executeScriptInWorker(WorkerThread* worker, WebWaitableEvent* waitEvent )
188 {
189 WorkerScriptController* scriptController = worker->workerGlobalScope()-> script();
190 bool evaluateResult = scriptController->evaluate(ScriptSourceCode("var c ounter = 0; ++counter;"));
191 ASSERT_UNUSED(evaluateResult, evaluateResult);
192 waitEvent->signal();
193 }
194
195 OwnPtr<DummyPageHolder> m_page;
196 RefPtr<SecurityOrigin> m_securityOrigin;
197 OwnPtr<WorkerObjectProxy> m_objectProxy;
198 CompositorWorkerTestPlatform m_testPlatform;
199 };
200
201 TEST_F(CompositorWorkerThreadTest, Basic)
202 {
203 OwnPtr<WebWaitableEvent> creationEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
204 RefPtr<CompositorWorkerThread> compositorWorker = createCompositorWorker(cre ationEvent.get());
205 waitForWaitableEventAfterIteratingCurrentLoop(creationEvent.get());
206 checkWorkerCanExecuteScript(compositorWorker.get());
207 compositorWorker->terminateAndWait();
208 }
209
210 // Tests that the same WebThread is used for new workers if the WebThread is sti ll alive.
211 TEST_F(CompositorWorkerThreadTest, CreateSecondAndTerminateFirst)
212 {
213 // Create the first worker and wait until it is initialized.
214 OwnPtr<WebWaitableEvent> firstCreationEvent = adoptPtr(Platform::current()-> createWaitableEvent());
215 RefPtr<CompositorWorkerThread> firstWorker = createCompositorWorker(firstCre ationEvent.get());
216 WebThreadSupportingGC* firstThread = CompositorWorkerThread::sharedBackingTh read();
217 ASSERT(firstThread);
218 waitForWaitableEventAfterIteratingCurrentLoop(firstCreationEvent.get());
219 v8::Isolate* firstIsolate = firstWorker->isolate();
220 ASSERT(firstIsolate);
221
222 // Create the second worker and immediately destroy the first worker.
223 OwnPtr<WebWaitableEvent> secondCreationEvent = adoptPtr(Platform::current()- >createWaitableEvent());
224 RefPtr<CompositorWorkerThread> secondWorker = createCompositorWorker(secondC reationEvent.get());
225 firstWorker->terminateAndWait();
226
227 // Wait until the second worker is initialized. Verify that the second worke r is using the same
228 // thread and Isolate as the first worker.
229 WebThreadSupportingGC* secondThread = CompositorWorkerThread::sharedBackingT hread();
230 ASSERT(secondThread);
231 waitForWaitableEventAfterIteratingCurrentLoop(secondCreationEvent.get());
232 EXPECT_EQ(firstThread, secondThread);
233
234 v8::Isolate* secondIsolate = secondWorker->isolate();
235 ASSERT(secondIsolate);
236 EXPECT_EQ(firstIsolate, secondIsolate);
237
238 // Verify that the worker can still successfully execute script.
239 checkWorkerCanExecuteScript(secondWorker.get());
240
241 secondWorker->terminateAndWait();
242 }
243
244 static void checkCurrentIsolate(v8::Isolate* isolate, WebWaitableEvent* event)
245 {
246 EXPECT_EQ(v8::Isolate::GetCurrent(), isolate);
247 event->signal();
248 }
249
250 // Tests that a new WebThread is created if all existing workers are terminated before a new worker is created.
251 TEST_F(CompositorWorkerThreadTest, TerminateFirstAndCreateSecond)
252 {
253 // Create the first worker, wait until it is initialized, and terminate it.
254 OwnPtr<WebWaitableEvent> creationEvent = adoptPtr(Platform::current()->creat eWaitableEvent());
255 RefPtr<CompositorWorkerThread> compositorWorker = createCompositorWorker(cre ationEvent.get());
256 WebThreadSupportingGC* firstThread = CompositorWorkerThread::sharedBackingTh read();
257 waitForWaitableEventAfterIteratingCurrentLoop(creationEvent.get());
258 ASSERT(compositorWorker->isolate());
259 compositorWorker->terminateAndWait();
260
261 // Create the second worker. Verify that the second worker lives in a differ ent WebThread since the first
262 // thread will have been destroyed after destroying the first worker.
263 creationEvent = adoptPtr(Platform::current()->createWaitableEvent());
264 compositorWorker = createCompositorWorker(creationEvent.get());
265 WebThreadSupportingGC* secondThread = CompositorWorkerThread::sharedBackingT hread();
266 EXPECT_NE(firstThread, secondThread);
267 waitForWaitableEventAfterIteratingCurrentLoop(creationEvent.get());
268
269 // Jump over to the worker's thread to verify that the Isolate is set up cor rectly and execute script.
270 OwnPtr<WebWaitableEvent> checkEvent = adoptPtr(Platform::current()->createWa itableEvent());
271 secondThread->platformThread().taskRunner()->postTask(BLINK_FROM_HERE, threa dSafeBind(&checkCurrentIsolate, AllowCrossThreadAccess(compositorWorker->isolate ()), AllowCrossThreadAccess(checkEvent.get())));
272 waitForWaitableEventAfterIteratingCurrentLoop(checkEvent.get());
273 checkWorkerCanExecuteScript(compositorWorker.get());
274
275 compositorWorker->terminateAndWait();
276 }
277
278 // Tests that v8::Isolate and WebThread are correctly set-up if a worker is crea ted while another is terminating.
279 TEST_F(CompositorWorkerThreadTest, CreatingSecondDuringTerminationOfFirst)
280 {
281 OwnPtr<WebWaitableEvent> firstCreationEvent = adoptPtr(Platform::current()-> createWaitableEvent());
282 RefPtr<TestCompositorWorkerThread> firstWorker = createCompositorWorker(firs tCreationEvent.get());
283 waitForWaitableEventAfterIteratingCurrentLoop(firstCreationEvent.get());
284 v8::Isolate* firstIsolate = firstWorker->isolate();
285 ASSERT(firstIsolate);
286
287 // Request termination of the first worker, and set-up to make sure the seco nd worker is created right as
288 // the first worker terminates its isolate.
289 OwnPtr<WebWaitableEvent> secondCreationEvent = adoptPtr(Platform::current()- >createWaitableEvent());
290 RefPtr<CompositorWorkerThread> secondWorker;
291 firstWorker->setCallbackAfterV8Termination(bind(&CompositorWorkerThreadTest: :createWorkerAdapter, this, &secondWorker, secondCreationEvent.get()));
292 firstWorker->terminateAndWait();
293 ASSERT(secondWorker);
294
295 waitForWaitableEventAfterIteratingCurrentLoop(secondCreationEvent.get());
296 v8::Isolate* secondIsolate = secondWorker->isolate();
297 ASSERT(secondIsolate);
298 EXPECT_EQ(firstIsolate, secondIsolate);
299
300 // Verify that the isolate can run some scripts correctly in the second work er.
301 checkWorkerCanExecuteScript(secondWorker.get());
302 secondWorker->terminateAndWait();
303 }
304
305 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698