Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/workers/WorkerThread.h" | 6 #include "core/workers/WorkerThread.h" |
| 7 | 7 |
| 8 #include "core/inspector/ConsoleMessage.h" | 8 #include "core/inspector/ConsoleMessage.h" |
| 9 #include "core/workers/WorkerReportingProxy.h" | 9 #include "core/workers/WorkerReportingProxy.h" |
| 10 #include "core/workers/WorkerThreadStartupData.h" | 10 #include "core/workers/WorkerThreadStartupData.h" |
| 11 #include "platform/NotImplemented.h" | 11 #include "platform/NotImplemented.h" |
| 12 #include "public/platform/WebScheduler.h" | 12 #include "public/platform/WebScheduler.h" |
| 13 #include "public/platform/WebWaitableEvent.h" | 13 #include "public/platform/WebWaitableEvent.h" |
| 14 #include <gmock/gmock.h> | 14 #include <gmock/gmock.h> |
| 15 #include <gtest/gtest.h> | 15 #include <gtest/gtest.h> |
| 16 | 16 |
| 17 using testing::_; | 17 using testing::_; |
| 18 using testing::AnyNumber; | |
| 18 using testing::Invoke; | 19 using testing::Invoke; |
| 19 using testing::Return; | 20 using testing::Return; |
| 20 using testing::Mock; | 21 using testing::Mock; |
| 21 | 22 |
| 22 namespace blink { | 23 namespace blink { |
| 23 | 24 |
| 24 namespace { | 25 namespace { |
| 25 class MockWorkerLoaderProxyProvider : public WorkerLoaderProxyProvider { | 26 class MockWorkerLoaderProxyProvider : public WorkerLoaderProxyProvider { |
| 26 public: | 27 public: |
| 27 MockWorkerLoaderProxyProvider() { } | 28 MockWorkerLoaderProxyProvider() { } |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 class WorkerThreadTest : public testing::Test { | 153 class WorkerThreadTest : public testing::Test { |
| 153 public: | 154 public: |
| 154 void SetUp() override | 155 void SetUp() override |
| 155 { | 156 { |
| 156 m_mockWorkerLoaderProxyProvider = adoptPtr(new MockWorkerLoaderProxyProv ider()); | 157 m_mockWorkerLoaderProxyProvider = adoptPtr(new MockWorkerLoaderProxyProv ider()); |
| 157 m_mockWorkerReportingProxy = adoptPtr(new MockWorkerReportingProxy()); | 158 m_mockWorkerReportingProxy = adoptPtr(new MockWorkerReportingProxy()); |
| 158 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/")); | 159 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/")); |
| 159 m_workerThread = adoptRef(new WorkerThreadForTest( | 160 m_workerThread = adoptRef(new WorkerThreadForTest( |
| 160 m_mockWorkerLoaderProxyProvider.get(), | 161 m_mockWorkerLoaderProxyProvider.get(), |
| 161 *m_mockWorkerReportingProxy)); | 162 *m_mockWorkerReportingProxy)); |
| 162 ExpectWorkerLifetimeReportingCalls(); | |
| 163 } | 163 } |
| 164 | 164 |
| 165 void TearDown() override | 165 void TearDown() override |
| 166 { | 166 { |
| 167 m_workerThread->workerLoaderProxy()->detachProvider(m_mockWorkerLoaderPr oxyProvider.get()); | 167 m_workerThread->workerLoaderProxy()->detachProvider(m_mockWorkerLoaderPr oxyProvider.get()); |
| 168 } | 168 } |
| 169 | 169 |
| 170 void startAndWaitForInit() | 170 void start() |
| 171 { | 171 { |
| 172 OwnPtr<WebWaitableEvent> completionEvent = adoptPtr(Platform::current()- >createWaitableEvent()); | |
| 173 | |
| 174 OwnPtr<Vector<CSPHeaderAndType>> headers = adoptPtr(new Vector<CSPHeader AndType>()); | 172 OwnPtr<Vector<CSPHeaderAndType>> headers = adoptPtr(new Vector<CSPHeader AndType>()); |
| 175 CSPHeaderAndType headerAndType("contentSecurityPolicy", ContentSecurityP olicyHeaderTypeReport); | 173 CSPHeaderAndType headerAndType("contentSecurityPolicy", ContentSecurityP olicyHeaderTypeReport); |
| 176 headers->append(headerAndType); | 174 headers->append(headerAndType); |
| 177 | 175 |
| 178 OwnPtrWillBeRawPtr<WorkerClients> clients = nullptr; | 176 OwnPtrWillBeRawPtr<WorkerClients> clients = nullptr; |
| 179 | 177 |
| 180 m_workerThread->start(WorkerThreadStartupData::create( | 178 m_workerThread->start(WorkerThreadStartupData::create( |
| 181 KURL(ParsedURLString, "http://fake.url/"), | 179 KURL(ParsedURLString, "http://fake.url/"), |
| 182 "fake user agent", | 180 "fake user agent", |
| 183 "//fake source code", | 181 "//fake source code", |
| 184 nullptr, | 182 nullptr, |
| 185 DontPauseWorkerGlobalScopeOnStart, | 183 DontPauseWorkerGlobalScopeOnStart, |
| 186 headers.release(), | 184 headers.release(), |
| 187 m_securityOrigin.get(), | 185 m_securityOrigin.get(), |
| 188 clients.release(), | 186 clients.release(), |
| 189 V8CacheOptionsDefault)); | 187 V8CacheOptionsDefault)); |
| 188 } | |
| 189 | |
| 190 void waitForInit() | |
| 191 { | |
| 192 OwnPtr<WebWaitableEvent> completionEvent = adoptPtr(Platform::current()- >createWaitableEvent()); | |
| 190 m_workerThread->backingThread().postTask(FROM_HERE, new SignalTask(compl etionEvent.get())); | 193 m_workerThread->backingThread().postTask(FROM_HERE, new SignalTask(compl etionEvent.get())); |
| 191 completionEvent->wait(); | 194 completionEvent->wait(); |
| 192 } | 195 } |
| 193 | 196 |
| 194 void postWakeUpTask(long long waitMs) | 197 void postWakeUpTask(long long waitMs) |
| 195 { | 198 { |
| 196 WebScheduler* scheduler = m_workerThread->backingThread().platformThread ().scheduler(); | 199 WebScheduler* scheduler = m_workerThread->backingThread().platformThread ().scheduler(); |
| 197 | 200 |
| 198 // The idle task will get posted on an after wake up queue, so we need a nother task | 201 // The idle task will get posted on an after wake up queue, so we need a nother task |
| 199 // posted at the right time to wake the system up. We don't know the ri ght delay here | 202 // posted at the right time to wake the system up. We don't know the ri ght delay here |
| 200 // since the thread can take a variable length of time to be responsive, however this | 203 // since the thread can take a variable length of time to be responsive, however this |
| 201 // isn't a problem when posting a delayed task from within a task on the worker thread. | 204 // isn't a problem when posting a delayed task from within a task on the worker thread. |
| 202 scheduler->postLoadingTask(FROM_HERE, new PostDelayedWakeupTask(schedule r, waitMs)); | 205 scheduler->postLoadingTask(FROM_HERE, new PostDelayedWakeupTask(schedule r, waitMs)); |
| 203 } | 206 } |
| 204 | 207 |
| 205 protected: | 208 protected: |
| 206 void ExpectWorkerLifetimeReportingCalls() | 209 void expectWorkerLifetimeReportingCalls() |
| 207 { | 210 { |
| 208 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Ti mes(1); | 211 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Ti mes(1); |
| 209 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)). Times(1); | 212 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)). Times(1); |
| 210 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times (1); | 213 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times (1); |
| 211 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) .Times(1); | 214 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) .Times(1); |
| 212 } | 215 } |
| 213 | 216 |
| 214 RefPtr<SecurityOrigin> m_securityOrigin; | 217 RefPtr<SecurityOrigin> m_securityOrigin; |
| 215 OwnPtr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvider; | 218 OwnPtr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvider; |
| 216 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy; | 219 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy; |
| 217 RefPtr<WorkerThreadForTest> m_workerThread; | 220 RefPtr<WorkerThreadForTest> m_workerThread; |
| 218 }; | 221 }; |
| 219 | 222 |
| 220 TEST_F(WorkerThreadTest, StartAndStop) | 223 TEST_F(WorkerThreadTest, StartAndStop) |
| 221 { | 224 { |
| 222 startAndWaitForInit(); | 225 expectWorkerLifetimeReportingCalls(); |
| 226 start(); | |
| 227 waitForInit(); | |
| 223 m_workerThread->terminateAndWait(); | 228 m_workerThread->terminateAndWait(); |
| 224 } | 229 } |
| 225 | 230 |
| 231 TEST_F(WorkerThreadTest, StartAndStopImmediately) | |
| 232 { | |
| 233 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Times( AnyNumber()); | |
|
kinuko
2015/06/16 01:35:19
AnyNumber() -> AtMostOne(1) ?
Sami
2015/06/16 16:03:45
Ah, neat, I didn't know that!
| |
| 234 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)).Time s(AnyNumber()); | |
| 235 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times(Any Number()); | |
| 236 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Tim es(AnyNumber()); | |
| 237 start(); | |
| 238 m_workerThread->terminateAndWait(); | |
| 239 } | |
| 240 | |
| 226 TEST_F(WorkerThreadTest, GcOccursWhileIdle) | 241 TEST_F(WorkerThreadTest, GcOccursWhileIdle) |
| 227 { | 242 { |
| 228 OwnPtr<WebWaitableEvent> gcDone = adoptPtr(Platform::current()->createWaitab leEvent()); | 243 OwnPtr<WebWaitableEvent> gcDone = adoptPtr(Platform::current()->createWaitab leEvent()); |
| 229 | 244 |
| 230 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke( | 245 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke( |
| 231 [&gcDone](double) | 246 [&gcDone](double) |
| 232 { | 247 { |
| 233 gcDone->signal(); | 248 gcDone->signal(); |
| 234 return false; | 249 return false; |
| 235 })); | 250 })); |
| 236 | 251 |
| 237 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(testing::AtLeast(1)); | 252 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(testing::AtLeast(1)); |
| 238 | 253 |
| 239 startAndWaitForInit(); | 254 expectWorkerLifetimeReportingCalls(); |
| 255 start(); | |
| 256 waitForInit(); | |
| 240 postWakeUpTask(500ul); | 257 postWakeUpTask(500ul); |
| 241 | 258 |
| 242 gcDone->wait(); | 259 gcDone->wait(); |
| 243 m_workerThread->terminateAndWait(); | 260 m_workerThread->terminateAndWait(); |
| 244 }; | 261 }; |
| 245 | 262 |
| 246 class RepeatingTask : public WebThread::Task { | 263 class RepeatingTask : public WebThread::Task { |
| 247 public: | 264 public: |
| 248 RepeatingTask(WebScheduler* scheduler, WebWaitableEvent* completion) | 265 RepeatingTask(WebScheduler* scheduler, WebWaitableEvent* completion) |
| 249 : RepeatingTask(scheduler, completion, 0) { } | 266 : RepeatingTask(scheduler, completion, 0) { } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 273 WebWaitableEvent* m_completion; | 290 WebWaitableEvent* m_completion; |
| 274 int m_taskCount; | 291 int m_taskCount; |
| 275 }; | 292 }; |
| 276 | 293 |
| 277 TEST_F(WorkerThreadTest, GcDoesNotOccurWhenNotIdle) | 294 TEST_F(WorkerThreadTest, GcDoesNotOccurWhenNotIdle) |
| 278 { | 295 { |
| 279 OwnPtr<WebWaitableEvent> completion = adoptPtr(Platform::current()->createWa itableEvent()); | 296 OwnPtr<WebWaitableEvent> completion = adoptPtr(Platform::current()->createWa itableEvent()); |
| 280 | 297 |
| 281 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(0); | 298 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(0); |
| 282 | 299 |
| 283 startAndWaitForInit(); | 300 expectWorkerLifetimeReportingCalls(); |
| 301 start(); | |
| 302 waitForInit(); | |
| 284 | 303 |
| 285 WebScheduler* scheduler = m_workerThread->backingThread().platformThread().s cheduler(); | 304 WebScheduler* scheduler = m_workerThread->backingThread().platformThread().s cheduler(); |
| 286 | 305 |
| 287 // Post a repeating task that should prevent any GC from happening. | 306 // Post a repeating task that should prevent any GC from happening. |
| 288 scheduler->postLoadingTask(FROM_HERE, new RepeatingTask(scheduler, completio n.get())); | 307 scheduler->postLoadingTask(FROM_HERE, new RepeatingTask(scheduler, completio n.get())); |
| 289 | 308 |
| 290 completion->wait(); | 309 completion->wait(); |
| 291 | 310 |
| 292 // Make sure doIdleGc has not been called by this stage. | 311 // Make sure doIdleGc has not been called by this stage. |
| 293 Mock::VerifyAndClearExpectations(m_workerThread.get()); | 312 Mock::VerifyAndClearExpectations(m_workerThread.get()); |
| 294 | 313 |
| 295 m_workerThread->terminateAndWait(); | 314 m_workerThread->terminateAndWait(); |
| 296 } | 315 } |
| 297 | 316 |
| 298 } // namespace blink | 317 } // namespace blink |
| OLD | NEW |