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

Side by Side Diff: Source/core/workers/WorkerThreadTest.cpp

Issue 956333002: Refactor TimeBase to post tasks. Workers to use real Idle tasks. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Simplify now the quiescence is handled in chromium Created 5 years, 8 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 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 "core/workers/WorkerThread.h"
7
8 #include "bindings/core/v8/ScriptWrappable.h"
9 #include "core/inspector/ConsoleMessage.h"
10 #include "core/workers/SharedWorkerGlobalScope.h"
11 #include "core/workers/SharedWorkerThread.h"
12 #include "core/workers/WorkerGlobalScope.h"
13 #include "core/workers/WorkerReportingProxy.h"
14 #include "core/workers/WorkerThreadStartupData.h"
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17
18 using testing::_;
19 using testing::Invoke;
20 using testing::Return;
21 using testing::Mock;
22
23 namespace blink {
24
25 namespace {
26 class MockWorkerLoaderProxy : public WorkerLoaderProxy {
27 public:
28 MockWorkerLoaderProxy() : WorkerLoaderProxy(nullptr) { }
29 ~MockWorkerLoaderProxy() override { }
30
31 MOCK_METHOD1(postTaskToLoader, void(PassOwnPtr<ExecutionContextTask>));
32 MOCK_METHOD1(postTaskToWorkerGlobalScope, bool(PassOwnPtr<ExecutionContextTa sk>));
33 };
34
35 class MockWorkerReportingProxy : public WorkerReportingProxy {
36 public:
37 MockWorkerReportingProxy() { }
38 ~MockWorkerReportingProxy() override { }
39
40 MOCK_METHOD5(reportException, void(const String& errorMessage, int lineNumbe r, int columnNumber, const String& sourceURL, int exceptionId));
41 MOCK_METHOD1(reportConsoleMessage, void(PassRefPtrWillBeRawPtr<ConsoleMessag e>));
42 MOCK_METHOD1(postMessageToPageInspector, void(const String&));
43 MOCK_METHOD0(postWorkerConsoleAgentEnabled, void());
44 MOCK_METHOD1(didEvaluateWorkerScript, void(bool success));
45 MOCK_METHOD1(workerGlobalScopeStarted, void(WorkerGlobalScope*));
46 MOCK_METHOD0(workerGlobalScopeClosed, void());
47 MOCK_METHOD0(workerThreadTerminated, void());
48 MOCK_METHOD0(willDestroyWorkerGlobalScope, void());
49 };
50
51 class FakeWorkerGlobalScope : public WorkerGlobalScope {
52 public:
53 typedef WorkerGlobalScope Base;
54
55 FakeWorkerGlobalScope(const KURL& url, const String& userAgent, WorkerThread * thread, const SecurityOrigin* starterOrigin, PassOwnPtrWillBeRawPtr<WorkerClie nts> workerClients)
56 : WorkerGlobalScope(url, userAgent, thread, monotonicallyIncreasingTime( ), starterOrigin, workerClients)
57 {
58 }
59
60 ~FakeWorkerGlobalScope() override
61 {
62 }
63
64 virtual bool isSharedWorkerGlobalScope() const override { return true; }
65
66 // EventTarget
67 virtual const AtomicString& interfaceName() const override
68 {
69 return EventTargetNames::SharedWorkerGlobalScope;
70 }
71
72 virtual void logExceptionToConsole(const String&, int , const String&, int, int, PassRefPtrWillBeRawPtr<ScriptCallStack>) override
73 {
74 }
75
76 // Setters/Getters for attributes in SharedWorkerGlobalScope.idl
77 DEFINE_ATTRIBUTE_EVENT_LISTENER(connect);
78 String name() const { return "FakeWorkerGlobalScope"; }
79
80 DECLARE_VIRTUAL_TRACE();
81 };
82
83 DEFINE_TRACE(FakeWorkerGlobalScope)
84 {
85 WorkerGlobalScope::trace(visitor);
86 }
87
88 class WorkerThreadForTest : public WorkerThread {
89 public:
90 WorkerThreadForTest(
91 WorkerLoaderProxy* mockWorkerLoaderProxy,
92 WorkerReportingProxy& mockWorkerReportingProxy,
93 PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> workerThreadStartupData)
94 : WorkerThread(mockWorkerLoaderProxy, mockWorkerReportingProxy, workerTh readStartupData)
95 {
96 }
97
98 ~WorkerThreadForTest() override { }
99
100 using WorkerThread::threadForTesting;
101
102 MOCK_METHOD1(doIdleGc, bool(double deadlineSeconds));
103
104 PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr <WorkerThreadStartupData> startupData) override
105 {
106 return adoptRefWillBeNoop(new FakeWorkerGlobalScope(startupData->m_scrip tURL, startupData->m_userAgent, this, startupData->m_starterOrigin, startupData- >m_workerClients.release()));
107 }
108 };
109
110 class WakeupTask : public WebThread::Task {
111 public:
112 WakeupTask() { }
113
114 ~WakeupTask() override { }
115
116 void run() override { }
117 };
118
119 class PostDelayedWakeupTask : public WebThread::Task {
120 public:
121 PostDelayedWakeupTask(WebThreadSupportingGC* gc, long long delay) : m_gc(gc) , m_delay(delay) { }
122
123 ~PostDelayedWakeupTask() override { }
124
125 void run() override
126 {
127 m_gc->postDelayedTask(FROM_HERE, new WakeupTask(), m_delay);
128 }
129
130 WebThreadSupportingGC* m_gc;
131 long long m_delay;
132 };
133
134 } // namespace
135
136 class WorkerThreadTest : public testing::Test {
137 public:
138 void SetUp() override
139 {
140 m_mockWorkerLoaderProxy = new MockWorkerLoaderProxy();
141 m_mockWorkerReportingProxy = adoptPtr(new MockWorkerReportingProxy());
142 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/"));
143 m_workerThread = adoptRef(new WorkerThreadForTest(
144 m_mockWorkerLoaderProxy.get(),
145 *m_mockWorkerReportingProxy,
146 WorkerThreadStartupData::create(
147 KURL(ParsedURLString, "http://fake.url/"),
148 "fake user agent",
149 "//fake source code",
150 nullptr,
151 DontPauseWorkerGlobalScopeOnStart,
152 "contentSecurityPolicy",
153 ContentSecurityPolicyHeaderTypeReport,
154 m_securityOrigin.get(),
155 WorkerClients::create(),
156 V8CacheOptionsDefault)));
157 ExpectWorkerLifetimeReportingCalls();
158 }
159
160 void PostWakeUpTask(long long waitMs)
161 {
162 WebThreadSupportingGC* thread = m_workerThread->threadForTesting();
163
164 // The idle task will get posted on an after wake up queue, so we need a nother task
165 // posted at the right time to wake the system up. We don't know the ri ght delay here
166 // since the thread can take a variable length of time to be responsive, however this
167 // isn't a problem when posting a delayed task from within a task on the worker thread.
168 thread->postTask(FROM_HERE, new PostDelayedWakeupTask(thread, waitMs));
169 }
170
171 protected:
172 void ExpectWorkerLifetimeReportingCalls()
173 {
174 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Ti mes(1);
175 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)). Times(1);
176 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times (1);
177 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) .Times(1);
178 }
179
180 RefPtr<SecurityOrigin> m_securityOrigin;
181 RefPtr<MockWorkerLoaderProxy> m_mockWorkerLoaderProxy;
182 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy;
183 RefPtr<WorkerThreadForTest> m_workerThread;
184 };
185
186 TEST_F(WorkerThreadTest, GcOccursWhileIdle)
187 {
188 bool gcDone = false;
189
190 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke(
191 [&gcDone](double)
192 {
193 gcDone = true;
194 return false;
195 }));
196
197 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(1);
198
199 m_workerThread->start();
200
201 PostWakeUpTask(310ul);
202
203 while (!gcDone)
204 Platform::current()->yieldCurrentThread();
205
206 m_workerThread->terminateAndWait();
207 };
208
209 class RepeatingTask : public WebThread::Task {
210 public:
211 RepeatingTask(WebThreadSupportingGC* thread, int* taskCount)
212 : m_thread(thread)
213 , m_taskCount(taskCount)
214 { }
215
216 ~RepeatingTask() override { }
217
218 void run() override
219 {
220 (*m_taskCount)++;
221 m_thread->postDelayedTask(FROM_HERE, new RepeatingTask(m_thread, m_taskC ount), 50ul);
222 m_thread->postTask(FROM_HERE, new WakeupTask());
223 }
224
225 private:
226 WebThreadSupportingGC* m_thread; // NOT OWNED
227 int* m_taskCount;
228 };
229
230 TEST_F(WorkerThreadTest, GcDoesNotOccurIfGapBetweenDelayedTasksIsTooSmall)
231 {
232 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(0);
233
234 m_workerThread->start();
235
236 WebThreadSupportingGC* thread = m_workerThread->threadForTesting();
237
238 // Post a repeating task that should prevent any GC from happening.
239 int taskCount = 0;
240 thread->postTask(FROM_HERE, new RepeatingTask(thread, &taskCount));
241
242 while (taskCount < 10)
243 Platform::current()->yieldCurrentThread();
244
245 // Make sure doIdleGc has not been called by this stage.
246 Mock::VerifyAndClearExpectations(m_workerThread.get());
247 m_workerThread->terminateAndWait();
248 }
249
250 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698