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

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/AudioWorkletThreadTest.cpp

Issue 2372303002: [worklets] Add AudioWorkletGlobalScope and AudioWorkletThread (Closed)
Patch Set: Using WorkletBackingThreadHolder Created 4 years, 2 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "modules/webaudio/AudioWorkletThread.h"
6
7 #include "bindings/core/v8/ScriptSourceCode.h"
8 #include "bindings/core/v8/SourceLocation.h"
9 #include "bindings/core/v8/V8GCController.h"
10 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
11 #include "core/inspector/ConsoleMessage.h"
12 #include "core/workers/InProcessWorkerObjectProxy.h"
nhiroki 2016/10/12 02:27:44 Maybe core/workers/WorkerReportingProxy.h? InProce
hongchan 2016/10/12 17:24:05 I merely followed AnimationWorkletThread's test fi
13 #include "core/workers/WorkerBackingThread.h"
14 #include "core/workers/WorkerLoaderProxy.h"
15 #include "core/workers/WorkerOrWorkletGlobalScope.h"
16 #include "core/workers/WorkerThreadStartupData.h"
17 #include "platform/CrossThreadFunctional.h"
18 #include "platform/WaitableEvent.h"
19 #include "platform/WebThreadSupportingGC.h"
20 #include "platform/heap/Handle.h"
21 #include "platform/testing/TestingPlatformSupport.h"
22 #include "platform/testing/UnitTestHelpers.h"
23 #include "public/platform/Platform.h"
24 #include "public/platform/WebAddressSpace.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "wtf/PtrUtil.h"
27 #include <memory>
28
29 namespace blink {
30
31 namespace {
32
33 // A null WorkerReportingProxy, supplied when creating AudioWorkletThreads.
34 class TestAudioWorkletReportingProxy : public WorkerReportingProxy {
35 public:
36 static std::unique_ptr<TestAudioWorkletReportingProxy> create() {
37 return wrapUnique(new TestAudioWorkletReportingProxy());
38 }
39
40 // (Empty) WorkerReportingProxy implementation:
41 void reportException(const String& errorMessage,
42 std::unique_ptr<SourceLocation>,
43 int exceptionId) override {}
44 void reportConsoleMessage(MessageSource,
45 MessageLevel,
46 const String& message,
47 SourceLocation*) override {}
48 void postMessageToPageInspector(const String&) override {}
49
50 void didEvaluateWorkerScript(bool success) override {}
51 void didCloseWorkerGlobalScope() override {}
52 void willDestroyWorkerGlobalScope() override {}
53 void didTerminateWorkerThread() override {}
54
55 private:
56 TestAudioWorkletReportingProxy() {}
57 };
58
59 } // namespace
60
61 class AudioWorkletThreadTest : public ::testing::Test {
62 public:
63 void SetUp() override {
64 AudioWorkletThread::createSharedBackingThreadForTest();
65 m_reportingProxy = TestAudioWorkletReportingProxy::create();
66 m_securityOrigin =
67 SecurityOrigin::create(KURL(ParsedURLString, "http://fake.url/"));
68 }
69
70 void TearDown() override { AudioWorkletThread::clearSharedBackingThread(); }
71
72 std::unique_ptr<AudioWorkletThread> createAudioWorkletThread() {
73 std::unique_ptr<AudioWorkletThread> thread =
74 AudioWorkletThread::create(nullptr, *m_reportingProxy);
75 thread->start(WorkerThreadStartupData::create(
76 KURL(ParsedURLString, "http://fake.url/"), "fake user agent", "",
77 nullptr, DontPauseWorkerGlobalScopeOnStart, nullptr, "",
78 m_securityOrigin.get(), nullptr, WebAddressSpaceLocal, nullptr, nullptr,
79 V8CacheOptionsDefault));
80 return thread;
81 }
82
83 // Attempts to run some simple script for |thread|.
84 void checkWorkletCanExecuteScript(WorkerThread* thread) {
85 std::unique_ptr<WaitableEvent> waitEvent = wrapUnique(new WaitableEvent());
86 thread->workerBackingThread().backingThread().postTask(
87 BLINK_FROM_HERE,
88 crossThreadBind(&AudioWorkletThreadTest::executeScriptInWorklet,
89 crossThreadUnretained(this),
90 crossThreadUnretained(thread),
91 crossThreadUnretained(waitEvent.get())));
92 waitEvent->wait();
93 }
94
95 private:
96 void executeScriptInWorklet(WorkerThread* thread, WaitableEvent* waitEvent) {
97 WorkerOrWorkletScriptController* scriptController =
98 thread->globalScope()->scriptController();
99 scriptController->evaluate(ScriptSourceCode("var counter = 0; ++counter;"));
100 waitEvent->signal();
101 }
102
103 RefPtr<SecurityOrigin> m_securityOrigin;
104 std::unique_ptr<WorkerReportingProxy> m_reportingProxy;
105 };
106
107 TEST_F(AudioWorkletThreadTest, Basic) {
108 std::unique_ptr<AudioWorkletThread> worklet = createAudioWorkletThread();
109 checkWorkletCanExecuteScript(worklet.get());
110 worklet->terminateAndWait();
111 }
112
113 // Tests that the same WebThread is used for new worklets if the WebThread is
114 // still alive.
115 TEST_F(AudioWorkletThreadTest, CreateSecondAndTerminateFirst) {
116 // Create the first worklet and wait until it is initialized.
117 std::unique_ptr<AudioWorkletThread> firstWorklet = createAudioWorkletThread();
118 WebThreadSupportingGC* firstThread =
119 &firstWorklet->workerBackingThread().backingThread();
120 checkWorkletCanExecuteScript(firstWorklet.get());
121 v8::Isolate* firstIsolate = firstWorklet->isolate();
122 ASSERT_TRUE(firstIsolate);
123
124 // Create the second worklet and immediately destroy the first worklet.
125 std::unique_ptr<AudioWorkletThread> secondWorklet =
126 createAudioWorkletThread();
127 // We don't use terminateAndWait here to avoid forcible termination.
128 firstWorklet->terminate();
129 firstWorklet->waitForShutdownForTesting();
130
131 // Wait until the second worklet is initialized. Verify that the second
132 // worklet is using the same thread and Isolate as the first worklet.
133 WebThreadSupportingGC* secondThread =
134 &secondWorklet->workerBackingThread().backingThread();
135 ASSERT_EQ(firstThread, secondThread);
136
137 v8::Isolate* secondIsolate = secondWorklet->isolate();
138 ASSERT_TRUE(secondIsolate);
139 EXPECT_EQ(firstIsolate, secondIsolate);
140
141 // Verify that the worklet can still successfully execute script.
142 checkWorkletCanExecuteScript(secondWorklet.get());
143
144 secondWorklet->terminateAndWait();
145 }
146
147 // Tests that a new WebThread is created if all existing worklets are
148 // terminated before a new worklet is created.
149 TEST_F(AudioWorkletThreadTest, TerminateFirstAndCreateSecond) {
150 // Create the first worklet, wait until it is initialized, and terminate it.
151 std::unique_ptr<AudioWorkletThread> worklet = createAudioWorkletThread();
152 WebThreadSupportingGC* firstThread =
153 &worklet->workerBackingThread().backingThread();
154 checkWorkletCanExecuteScript(worklet.get());
155
156 // We don't use terminateAndWait here to avoid forcible termination.
157 worklet->terminate();
158 worklet->waitForShutdownForTesting();
159
160 // Create the second worklet. The backing thread is same.
161 worklet = createAudioWorkletThread();
162 WebThreadSupportingGC* secondThread =
163 &worklet->workerBackingThread().backingThread();
164 EXPECT_EQ(firstThread, secondThread);
165 checkWorkletCanExecuteScript(worklet.get());
166
167 worklet->terminateAndWait();
168 }
169
170 // Tests that v8::Isolate and WebThread are correctly set-up if a worklet is
171 // created while another is terminating.
172 TEST_F(AudioWorkletThreadTest, CreatingSecondDuringTerminationOfFirst) {
173 std::unique_ptr<AudioWorkletThread> firstWorklet = createAudioWorkletThread();
174 checkWorkletCanExecuteScript(firstWorklet.get());
175 v8::Isolate* firstIsolate = firstWorklet->isolate();
176 ASSERT_TRUE(firstIsolate);
177
178 // Request termination of the first worklet and create the second worklet
179 // as soon as possible. We don't wait for its termination.
180 // Note: We rely on the assumption that the termination steps don't run
181 // on the worklet thread so quickly. This could be a source of flakiness.
182 firstWorklet->terminate();
183 std::unique_ptr<AudioWorkletThread> secondWorklet =
184 createAudioWorkletThread();
185
186 v8::Isolate* secondIsolate = secondWorklet->isolate();
187 ASSERT_TRUE(secondIsolate);
188 EXPECT_EQ(firstIsolate, secondIsolate);
189
190 // Verify that the isolate can run some scripts correctly in the second
191 // worklet.
192 checkWorkletCanExecuteScript(secondWorklet.get());
193 secondWorklet->terminateAndWait();
194 }
195
196 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698