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 |