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

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

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

Powered by Google App Engine
This is Rietveld 408576698