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 "core/workers/WorkerThread.h" | 5 #include "core/workers/WorkerThread.h" |
| 6 | 6 |
| 7 #include "core/workers/WorkerThreadTestHelper.h" | 7 #include "core/workers/WorkerThreadTestHelper.h" |
| 8 #include "platform/testing/UnitTestHelpers.h" | |
| 8 #include "public/platform/WebScheduler.h" | 9 #include "public/platform/WebScheduler.h" |
| 9 #include "testing/gmock/include/gmock/gmock.h" | 10 #include "testing/gmock/include/gmock/gmock.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 11 | 12 |
| 12 using testing::_; | 13 using testing::_; |
| 13 using testing::AtMost; | 14 using testing::AtMost; |
| 14 using testing::Invoke; | 15 using testing::Invoke; |
| 15 using testing::Return; | 16 using testing::Return; |
| 16 using testing::Mock; | 17 using testing::Mock; |
| 17 | 18 |
| 18 namespace blink { | 19 namespace blink { |
| 19 | 20 |
| 20 class WorkerThreadTest : public testing::Test { | 21 class WorkerThreadTest : public ::testing::Test { |
| 21 public: | 22 public: |
| 22 void SetUp() override | 23 void SetUp() override |
| 23 { | 24 { |
| 24 m_mockWorkerLoaderProxyProvider = adoptPtr(new MockWorkerLoaderProxyProv ider()); | 25 m_mockWorkerLoaderProxyProvider = adoptPtr(new MockWorkerLoaderProxyProv ider()); |
| 25 m_mockWorkerReportingProxy = adoptPtr(new MockWorkerReportingProxy()); | 26 m_mockWorkerReportingProxy = adoptPtr(new MockWorkerReportingProxy()); |
| 26 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/")); | 27 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/")); |
| 27 m_workerThread = adoptPtr(new WorkerThreadForTest( | 28 m_workerThread = adoptPtr(new WorkerThreadForTest( |
| 28 m_mockWorkerLoaderProxyProvider.get(), | 29 m_mockWorkerLoaderProxyProvider.get(), |
| 29 *m_mockWorkerReportingProxy)); | 30 *m_mockWorkerReportingProxy)); |
| 30 } | 31 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 42 void startWithSourceCode(const String& source) | 43 void startWithSourceCode(const String& source) |
| 43 { | 44 { |
| 44 m_workerThread->startWithSourceCode(m_securityOrigin.get(), source); | 45 m_workerThread->startWithSourceCode(m_securityOrigin.get(), source); |
| 45 } | 46 } |
| 46 | 47 |
| 47 void waitForInit() | 48 void waitForInit() |
| 48 { | 49 { |
| 49 m_workerThread->waitForInit(); | 50 m_workerThread->waitForInit(); |
| 50 } | 51 } |
| 51 | 52 |
| 53 void waitForShutdown() | |
| 54 { | |
| 55 m_workerThread->m_shutdownEvent->wait(); | |
| 56 } | |
| 57 | |
| 58 void setForceTerminationDelayInMs(long long forceTerminationDelayInMs) | |
| 59 { | |
| 60 m_workerThread->setForceTerminationDelayInMs(forceTerminationDelayInMs); | |
| 61 } | |
| 62 | |
| 52 protected: | 63 protected: |
| 53 void expectWorkerLifetimeReportingCalls() | 64 void expectWorkerLifetimeReportingCalls() |
| 54 { | 65 { |
| 55 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Ti mes(1); | 66 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Ti mes(1); |
| 56 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)). Times(1); | 67 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)). Times(1); |
| 57 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times (1); | 68 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times (1); |
| 58 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) .Times(1); | 69 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) .Times(1); |
| 59 } | 70 } |
| 60 | 71 |
| 61 RefPtr<SecurityOrigin> m_securityOrigin; | 72 RefPtr<SecurityOrigin> m_securityOrigin; |
| 62 OwnPtr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvider; | 73 OwnPtr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvider; |
| 63 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy; | 74 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy; |
| 64 OwnPtr<WorkerThreadForTest> m_workerThread; | 75 OwnPtr<WorkerThreadForTest> m_workerThread; |
| 65 }; | 76 }; |
| 66 | 77 |
| 67 TEST_F(WorkerThreadTest, StartAndStop) | 78 TEST_F(WorkerThreadTest, StartAndStop) |
| 68 { | 79 { |
| 69 expectWorkerLifetimeReportingCalls(); | 80 expectWorkerLifetimeReportingCalls(); |
| 70 start(); | 81 start(); |
| 71 waitForInit(); | 82 waitForInit(); |
| 72 m_workerThread->terminateAndWait(); | 83 m_workerThread->terminateAndWait(); |
| 84 EXPECT_EQ(WorkerThread::ExitCode::SyncForciblyTerminated, m_workerThread->ex itCode()); | |
| 73 } | 85 } |
| 74 | 86 |
| 75 TEST_F(WorkerThreadTest, StartAndStopImmediately) | 87 TEST_F(WorkerThreadTest, StartAndStopImmediately) |
| 76 { | 88 { |
| 77 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)) | 89 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)) |
| 78 .Times(AtMost(1)); | 90 .Times(AtMost(1)); |
| 79 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(_)) | 91 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(_)) |
| 80 .Times(AtMost(1)); | 92 .Times(AtMost(1)); |
| 81 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()) | 93 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()) |
| 82 .Times(AtMost(1)); | 94 .Times(AtMost(1)); |
| 83 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) | 95 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) |
| 84 .Times(AtMost(1)); | 96 .Times(AtMost(1)); |
| 85 start(); | 97 start(); |
| 98 | |
| 99 // terminateAndWait() does not attempt to terminate the isolate because it | |
| 100 // has not started yet at this point. | |
| 86 m_workerThread->terminateAndWait(); | 101 m_workerThread->terminateAndWait(); |
| 102 EXPECT_EQ(WorkerThread::ExitCode::GracefullyTerminated, m_workerThread->exit Code()); | |
| 87 } | 103 } |
| 88 | 104 |
| 89 TEST_F(WorkerThreadTest, StartAndStopOnScriptLoaded) | 105 TEST_F(WorkerThreadTest, StartAndStopOnScriptLoaded_GracefullyTerminate) |
| 106 { | |
| 107 expectWorkerLifetimeReportingCalls(); | |
| 108 start(); | |
| 109 waitForInit(); | |
| 110 | |
| 111 // The worker thread is not being blocked, so the worker thread should be | |
| 112 // gracefully shut down without any forcible isolate termination. | |
| 113 m_workerThread->terminate(); | |
| 114 waitForShutdown(); | |
| 115 EXPECT_EQ(WorkerThread::ExitCode::GracefullyTerminated, m_workerThread->exit Code()); | |
| 116 } | |
| 117 | |
| 118 TEST_F(WorkerThreadTest, StartAndStopOnScriptLoaded_SyncForciblyTerminate) | |
| 90 { | 119 { |
| 91 // Use a JavaScript source code that makes an infinite loop so that we can | 120 // Use a JavaScript source code that makes an infinite loop so that we can |
| 92 // catch some kind of issues as a timeout. | 121 // catch some kind of issues as a timeout. |
| 93 const String source("while(true) {}"); | 122 const String source("while(true) {}"); |
| 94 | 123 |
| 95 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)) | 124 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)) |
| 96 .Times(AtMost(1)); | 125 .Times(AtMost(1)); |
| 97 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(_)) | 126 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(_)) |
| 98 .Times(AtMost(1)); | 127 .Times(AtMost(1)); |
| 99 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()) | 128 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()) |
| 100 .Times(AtMost(1)); | 129 .Times(AtMost(1)); |
| 101 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) | 130 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) |
| 102 .Times(AtMost(1)); | 131 .Times(AtMost(1)); |
| 103 startWithSourceCode(source); | 132 startWithSourceCode(source); |
| 104 m_workerThread->waitUntilScriptLoaded(); | 133 m_workerThread->waitUntilScriptLoaded(); |
| 134 | |
| 135 // terminateAndWait() synchronously terminates the isolate. | |
| 105 m_workerThread->terminateAndWait(); | 136 m_workerThread->terminateAndWait(); |
| 137 EXPECT_EQ(WorkerThread::ExitCode::SyncForciblyTerminated, m_workerThread->ex itCode()); | |
| 138 } | |
| 139 | |
| 140 TEST_F(WorkerThreadTest, StartAndStopOnScriptLoaded_AsyncForciblyTerminate) | |
|
yhirano
2016/05/27 11:04:43
Can you add a test case for the case that a thread
nhiroki
2016/05/30 06:18:47
Good point. The patchset 1 couldn't handle this ca
| |
| 141 { | |
| 142 const long long kForceTerminationDelayInMs = 10; | |
| 143 setForceTerminationDelayInMs(kForceTerminationDelayInMs); | |
| 144 | |
| 145 // Use a JavaScript source code that makes an infinite loop so that we can | |
| 146 // catch some kind of issues as a timeout. | |
| 147 const String source("while(true) {}"); | |
| 148 | |
| 149 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)) | |
| 150 .Times(AtMost(1)); | |
| 151 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(_)) | |
| 152 .Times(AtMost(1)); | |
| 153 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()) | |
| 154 .Times(AtMost(1)); | |
| 155 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()) | |
| 156 .Times(AtMost(1)); | |
| 157 startWithSourceCode(source); | |
| 158 m_workerThread->waitUntilScriptLoaded(); | |
| 159 | |
| 160 // terminate() schedules a force termination task. | |
| 161 m_workerThread->terminate(); | |
| 162 EXPECT_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->exitCode()) ; | |
| 163 | |
| 164 // Wait until the force termination task runs. | |
| 165 testing::runDelayedTasks(kForceTerminationDelayInMs); | |
| 166 waitForShutdown(); | |
| 167 EXPECT_EQ(WorkerThread::ExitCode::AsyncForciblyTerminated, m_workerThread->e xitCode()); | |
| 106 } | 168 } |
| 107 | 169 |
| 108 } // namespace blink | 170 } // namespace blink |
| OLD | NEW |