OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
Sami
2015/04/09 10:52:29
If we want to make this patch smaller, landing thi
alex clarke (OOO till 29th)
2015/04/10 15:29:39
Acknowledged.
| |
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 | |
22 namespace blink { | |
23 | |
24 namespace { | |
25 class MockWorkerLoaderProxy : public WorkerLoaderProxy { | |
26 public: | |
27 MockWorkerLoaderProxy() : WorkerLoaderProxy(nullptr) { } | |
28 ~MockWorkerLoaderProxy() override { } | |
29 | |
30 MOCK_METHOD1(postTaskToLoader, void(PassOwnPtr<ExecutionContextTask>)); | |
31 MOCK_METHOD1(postTaskToWorkerGlobalScope, bool(PassOwnPtr<ExecutionContextTa sk>)); | |
32 }; | |
33 | |
34 class MockWorkerReportingProxy : public WorkerReportingProxy { | |
35 public: | |
36 MockWorkerReportingProxy() { } | |
37 ~MockWorkerReportingProxy() override { } | |
38 | |
39 MOCK_METHOD5(reportException, void(const String& errorMessage, int lineNumbe r, int columnNumber, const String& sourceURL, int exceptionId)); | |
40 MOCK_METHOD1(reportConsoleMessage, void(PassRefPtrWillBeRawPtr<ConsoleMessag e>)); | |
41 MOCK_METHOD1(postMessageToPageInspector, void(const String&)); | |
42 MOCK_METHOD0(postWorkerConsoleAgentEnabled, void()); | |
43 MOCK_METHOD1(didEvaluateWorkerScript, void(bool success)); | |
44 MOCK_METHOD1(workerGlobalScopeStarted, void(WorkerGlobalScope*)); | |
45 MOCK_METHOD0(workerGlobalScopeClosed, void()); | |
46 MOCK_METHOD0(workerThreadTerminated, void()); | |
47 MOCK_METHOD0(willDestroyWorkerGlobalScope, void()); | |
48 }; | |
49 | |
50 class FakeWorkerGlobalScope : public WorkerGlobalScope { | |
51 public: | |
52 typedef WorkerGlobalScope Base; | |
53 | |
54 FakeWorkerGlobalScope(const KURL& url, const String& userAgent, WorkerThread * thread, const SecurityOrigin* starterOrigin, PassOwnPtrWillBeRawPtr<WorkerClie nts> workerClients) | |
55 : WorkerGlobalScope(url, userAgent, thread, monotonicallyIncreasingTime( ), starterOrigin, workerClients) | |
56 { | |
57 } | |
58 | |
59 ~FakeWorkerGlobalScope() override | |
60 { | |
61 } | |
62 | |
63 virtual bool isSharedWorkerGlobalScope() const override { return true; } | |
64 | |
65 // EventTarget | |
66 virtual const AtomicString& interfaceName() const override | |
67 { | |
68 return EventTargetNames::SharedWorkerGlobalScope; | |
69 } | |
70 | |
71 virtual void logExceptionToConsole(const String&, int , const String&, int, int, PassRefPtrWillBeRawPtr<ScriptCallStack>) override | |
72 { | |
73 } | |
74 | |
75 // Setters/Getters for attributes in SharedWorkerGlobalScope.idl | |
76 DEFINE_ATTRIBUTE_EVENT_LISTENER(connect); | |
77 String name() const { return "FakeWorkerGlobalScope"; } | |
78 | |
79 DECLARE_VIRTUAL_TRACE(); | |
80 }; | |
81 | |
82 DEFINE_TRACE(FakeWorkerGlobalScope) | |
83 { | |
84 WorkerGlobalScope::trace(visitor); | |
85 } | |
86 | |
87 class WorkerThreadForTest : public WorkerThread { | |
88 public: | |
89 WorkerThreadForTest( | |
90 WorkerLoaderProxy* mockWorkerLoaderProxy, | |
91 WorkerReportingProxy& mockWorkerReportingProxy, | |
92 PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> workerThreadStartupData) | |
93 : WorkerThread(mockWorkerLoaderProxy, mockWorkerReportingProxy, workerTh readStartupData) | |
94 { | |
95 } | |
96 | |
97 ~WorkerThreadForTest() override { } | |
98 | |
99 using WorkerThread::threadForTesting; | |
100 using WorkerThread::setMinQuietPeriodBeforeDoingIdleGcForTesting; | |
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 } | |
158 | |
159 RefPtr<SecurityOrigin> m_securityOrigin; | |
160 RefPtr<MockWorkerLoaderProxy> m_mockWorkerLoaderProxy; | |
161 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy; | |
162 RefPtr<WorkerThreadForTest> m_workerThread; | |
163 }; | |
164 | |
165 TEST_F(WorkerThreadTest, GcOccursWhileIdle) | |
166 { | |
167 bool gcDone = false; | |
168 | |
169 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke( | |
170 [&gcDone](double) | |
171 { | |
172 gcDone = true; | |
173 return false; | |
174 })); | |
175 | |
176 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(1); | |
177 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Times( 1); | |
Sami
2015/04/09 10:52:29
Could these be moved to a helper setup function? T
alex clarke (OOO till 29th)
2015/04/10 15:29:38
Done.
| |
178 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)).Time s(1); | |
179 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times(1); | |
180 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Tim es(1); | |
181 | |
182 m_workerThread->setMinQuietPeriodBeforeDoingIdleGcForTesting(100ul); | |
183 m_workerThread->start(); | |
184 WebThreadSupportingGC* thread = m_workerThread->threadForTesting(); | |
185 | |
186 // The idle task will get posted on an after wake up queue, so we need anoth er task | |
187 // posted at the right time to wake the system up. We don't know the right delay here | |
188 // since the thread can take a variable length of time to be responsive, how ever this | |
189 // isn't a problem when posting a delayed task from within a task on the wor ker thread. | |
190 thread->postTask(FROM_HERE, new PostDelayedWakeupTask(thread, 110ul)); | |
191 | |
192 while (!gcDone) | |
193 Platform::current()->yieldCurrentThread(); | |
194 | |
195 m_workerThread->terminateAndWait(); | |
196 }; | |
197 | |
198 } // namespace blink | |
OLD | NEW |