| Index: third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
|
| diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
|
| index f9f6886d1e5ee1d55c5c465c5d3550e583667bd9..03322ed79abe776de72eb3681954f70dd6d74a2a 100644
|
| --- a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
|
| +++ b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
|
| @@ -21,61 +21,32 @@ using ExitCode = WorkerThread::ExitCode;
|
|
|
| namespace {
|
|
|
| -// Called from WorkerThread::startRunningDebuggerTasksOnPauseOnWorkerThread as a
|
| -// debugger task.
|
| -void waitForTermination(WorkerThread* workerThread, WaitableEvent* waitableEvent)
|
| +// Used as a debugger task. Waits for a signal from the main thread.
|
| +void waitForSignalTask(WorkerThread* workerThread, WaitableEvent* waitableEvent)
|
| {
|
| EXPECT_TRUE(workerThread->isCurrentThread());
|
|
|
| - // Notify the main thread that the debugger task is waiting for termination.
|
| + // Notify the main thread that the debugger task is waiting for the signal.
|
| Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(&testing::exitRunLoop));
|
| waitableEvent->wait();
|
| }
|
|
|
| } // namespace
|
|
|
| -class WorkerThreadLifecycleObserverForTest final : public GarbageCollectedFinalized<WorkerThreadLifecycleObserverForTest>, public WorkerThreadLifecycleObserver {
|
| - USING_GARBAGE_COLLECTED_MIXIN(WorkerThreadLifecycleObserverForTest);
|
| - WTF_MAKE_NONCOPYABLE(WorkerThreadLifecycleObserverForTest);
|
| -public:
|
| - explicit WorkerThreadLifecycleObserverForTest(WorkerThreadLifecycleContext* context)
|
| - : WorkerThreadLifecycleObserver(context)
|
| - {
|
| - DCHECK(!wasContextDestroyedBeforeObserverCreation());
|
| - }
|
| - ~WorkerThreadLifecycleObserverForTest() override {}
|
| -
|
| - void contextDestroyed() override
|
| - {
|
| - if (m_closure)
|
| - (*m_closure)();
|
| - }
|
| -
|
| - void setClosure(std::unique_ptr<WTF::Closure> closure)
|
| - {
|
| - m_closure = std::move(closure);
|
| - }
|
| -
|
| -private:
|
| - std::unique_ptr<WTF::Closure> m_closure;
|
| -};
|
| -
|
| class WorkerThreadTest : public ::testing::Test {
|
| public:
|
| void SetUp() override
|
| {
|
| - m_mockWorkerLoaderProxyProvider = wrapUnique(new MockWorkerLoaderProxyProvider());
|
| - m_mockWorkerReportingProxy = wrapUnique(new MockWorkerReportingProxy());
|
| + m_loaderProxyProvider = wrapUnique(new MockWorkerLoaderProxyProvider());
|
| + m_reportingProxy = wrapUnique(new MockWorkerReportingProxy());
|
| m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http://fake.url/"));
|
| - m_workerThread = wrapUnique(new WorkerThreadForTest(
|
| - m_mockWorkerLoaderProxyProvider.get(),
|
| - *m_mockWorkerReportingProxy));
|
| - m_workerThreadLifecycleObserver = new WorkerThreadLifecycleObserverForTest(m_workerThread->getWorkerThreadLifecycleContext());
|
| + m_workerThread = wrapUnique(new WorkerThreadForTest(m_loaderProxyProvider.get(), *m_reportingProxy));
|
| + m_lifecycleObserver = new MockWorkerThreadLifecycleObserver(m_workerThread->getWorkerThreadLifecycleContext());
|
| }
|
|
|
| void TearDown() override
|
| {
|
| - m_workerThread->workerLoaderProxy()->detachProvider(m_mockWorkerLoaderProxyProvider.get());
|
| + m_workerThread->workerLoaderProxy()->detachProvider(m_loaderProxyProvider.get());
|
| }
|
|
|
| void start()
|
| @@ -103,32 +74,35 @@ public:
|
| protected:
|
| void expectReportingCalls()
|
| {
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didLoadWorkerScriptMock(_, _)).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didCreateWorkerGlobalScope(_)).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didInitializeWorkerContext()).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didTerminateWorkerThread()).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didLoadWorkerScriptMock(_, _)).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didCreateWorkerGlobalScope(_)).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didInitializeWorkerContext()).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didEvaluateWorkerScript(true)).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, willDestroyWorkerGlobalScope()).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didTerminateWorkerThread()).Times(1);
|
| + EXPECT_CALL(*m_lifecycleObserver, contextDestroyed()).Times(1);
|
| }
|
|
|
| void expectReportingCallsForWorkerPossiblyTerminatedBeforeInitialization()
|
| {
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didLoadWorkerScriptMock(_, _)).Times(AtMost(1));
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didCreateWorkerGlobalScope(_)).Times(AtMost(1));
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didInitializeWorkerContext()).Times(AtMost(1));
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(_)).Times(AtMost(1));
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(AtMost(1));
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didTerminateWorkerThread()).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didLoadWorkerScriptMock(_, _)).Times(AtMost(1));
|
| + EXPECT_CALL(*m_reportingProxy, didCreateWorkerGlobalScope(_)).Times(AtMost(1));
|
| + EXPECT_CALL(*m_reportingProxy, didInitializeWorkerContext()).Times(AtMost(1));
|
| + EXPECT_CALL(*m_reportingProxy, didEvaluateWorkerScript(_)).Times(AtMost(1));
|
| + EXPECT_CALL(*m_reportingProxy, willDestroyWorkerGlobalScope()).Times(AtMost(1));
|
| + EXPECT_CALL(*m_reportingProxy, didTerminateWorkerThread()).Times(1);
|
| + EXPECT_CALL(*m_lifecycleObserver, contextDestroyed()).Times(1);
|
| }
|
|
|
| void expectReportingCallsForWorkerForciblyTerminated()
|
| {
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didLoadWorkerScriptMock(_, _)).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didCreateWorkerGlobalScope(_)).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didInitializeWorkerContext()).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(false)).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didTerminateWorkerThread()).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didLoadWorkerScriptMock(_, _)).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didCreateWorkerGlobalScope(_)).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didInitializeWorkerContext()).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didEvaluateWorkerScript(false)).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, willDestroyWorkerGlobalScope()).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didTerminateWorkerThread()).Times(1);
|
| + EXPECT_CALL(*m_lifecycleObserver, contextDestroyed()).Times(1);
|
| }
|
|
|
| ExitCode getExitCode()
|
| @@ -137,10 +111,10 @@ protected:
|
| }
|
|
|
| RefPtr<SecurityOrigin> m_securityOrigin;
|
| - std::unique_ptr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvider;
|
| - std::unique_ptr<MockWorkerReportingProxy> m_mockWorkerReportingProxy;
|
| + std::unique_ptr<MockWorkerLoaderProxyProvider> m_loaderProxyProvider;
|
| + std::unique_ptr<MockWorkerReportingProxy> m_reportingProxy;
|
| std::unique_ptr<WorkerThreadForTest> m_workerThread;
|
| - Persistent<WorkerThreadLifecycleObserverForTest> m_workerThreadLifecycleObserver;
|
| + Persistent<MockWorkerThreadLifecycleObserver> m_lifecycleObserver;
|
| };
|
|
|
| TEST_F(WorkerThreadTest, ShouldScheduleToTerminateExecution)
|
| @@ -165,10 +139,13 @@ TEST_F(WorkerThreadTest, ShouldScheduleToTerminateExecution)
|
| m_workerThread->setExitCode(dummyLock, ExitCode::GracefullyTerminated);
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminate_AsyncTerminate)
|
| +TEST_F(WorkerThreadTest, AsyncTerminate_OnIdle)
|
| {
|
| expectReportingCalls();
|
| start();
|
| +
|
| + // Wait until the initialization completes and the worker thread becomes
|
| + // idle.
|
| m_workerThread->waitForInit();
|
|
|
| // The worker thread is not being blocked, so the worker thread should be
|
| @@ -179,16 +156,20 @@ TEST_F(WorkerThreadTest, StartAndTerminate_AsyncTerminate)
|
| EXPECT_EQ(ExitCode::GracefullyTerminated, getExitCode());
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminate_SyncTerminate)
|
| +TEST_F(WorkerThreadTest, SyncTerminate_OnIdle)
|
| {
|
| expectReportingCalls();
|
| start();
|
| +
|
| + // Wait until the initialization completes and the worker thread becomes
|
| + // idle.
|
| m_workerThread->waitForInit();
|
| +
|
| m_workerThread->terminateAndWait();
|
| EXPECT_EQ(ExitCode::SyncForciblyTerminated, getExitCode());
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminateImmediately_AsyncTerminate)
|
| +TEST_F(WorkerThreadTest, AsyncTerminate_ImmediatelyAfterStart)
|
| {
|
| expectReportingCallsForWorkerPossiblyTerminatedBeforeInitialization();
|
| start();
|
| @@ -204,7 +185,7 @@ TEST_F(WorkerThreadTest, StartAndTerminateImmediately_AsyncTerminate)
|
| EXPECT_EQ(ExitCode::GracefullyTerminated, exitCode);
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminateImmediately_SyncTerminate)
|
| +TEST_F(WorkerThreadTest, SyncTerminate_ImmediatelyAfterStart)
|
| {
|
| expectReportingCallsForWorkerPossiblyTerminatedBeforeInitialization();
|
| start();
|
| @@ -220,136 +201,139 @@ TEST_F(WorkerThreadTest, StartAndTerminateImmediately_SyncTerminate)
|
| EXPECT_TRUE(ExitCode::GracefullyTerminated == exitCode || ExitCode::SyncForciblyTerminated == exitCode);
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminateOnInitialization_TerminateWhileDebuggerTaskIsRunning)
|
| +TEST_F(WorkerThreadTest, AsyncTerminate_WhileTaskIsRunning)
|
| {
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didLoadWorkerScriptMock(_, _)).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didCreateWorkerGlobalScope(_)).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(1);
|
| - EXPECT_CALL(*m_mockWorkerReportingProxy, didTerminateWorkerThread()).Times(1);
|
| -
|
| - std::unique_ptr<Vector<CSPHeaderAndType>> headers = wrapUnique(new Vector<CSPHeaderAndType>());
|
| - CSPHeaderAndType headerAndType("contentSecurityPolicy", ContentSecurityPolicyHeaderTypeReport);
|
| - headers->append(headerAndType);
|
| + const long long kForceTerminationDelayInMs = 10;
|
| + setForceTerminationDelayInMs(kForceTerminationDelayInMs);
|
|
|
| - // Specify PauseWorkerGlobalScopeOnStart so that the worker thread can pause
|
| - // on initialziation to run debugger tasks.
|
| - std::unique_ptr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create(
|
| - KURL(ParsedURLString, "http://fake.url/"),
|
| - "fake user agent",
|
| - "//fake source code",
|
| - nullptr, /* cachedMetaData */
|
| - PauseWorkerGlobalScopeOnStart,
|
| - headers.get(),
|
| - "",
|
| - m_securityOrigin.get(),
|
| - nullptr, /* workerClients */
|
| - WebAddressSpaceLocal,
|
| - nullptr /* originTrialToken */,
|
| - nullptr /* WorkerSettings */,
|
| - V8CacheOptionsDefault);
|
| - m_workerThread->start(std::move(startupData));
|
| + expectReportingCallsForWorkerForciblyTerminated();
|
| + startWithSourceCodeNotToFinish();
|
| + m_reportingProxy->waitUntilScriptLoaded();
|
|
|
| - // Used to wait for worker thread termination in a debugger task on the
|
| - // worker thread. Signaled when WorkerThreadLifecycleContext is destroyed on
|
| - // the main thread.
|
| - WaitableEvent waitableEvent(WaitableEvent::ResetPolicy::Manual, WaitableEvent::InitialState::NonSignaled);
|
| - m_workerThread->appendDebuggerTask(crossThreadBind(&waitForTermination, crossThreadUnretained(m_workerThread.get()), crossThreadUnretained(&waitableEvent)));
|
| - m_workerThreadLifecycleObserver->setClosure(WTF::bind(&WaitableEvent::signal, unretained(&waitableEvent)));
|
| + // terminate() schedules a force termination task.
|
| + m_workerThread->terminate();
|
| + EXPECT_TRUE(isForceTerminationTaskScheduled());
|
| + EXPECT_EQ(ExitCode::NotTerminated, getExitCode());
|
|
|
| - // Wait for the debugger task.
|
| - testing::enterRunLoop();
|
| + // Multiple terminate() calls should not take effect.
|
| + m_workerThread->terminate();
|
| + m_workerThread->terminate();
|
| + EXPECT_EQ(ExitCode::NotTerminated, getExitCode());
|
|
|
| - // Start termination while the debugger task is running.
|
| - EXPECT_TRUE(m_workerThread->m_runningDebuggerTask);
|
| - m_workerThread->terminateAndWait();
|
| - EXPECT_EQ(ExitCode::GracefullyTerminated, getExitCode());
|
| + // Wait until the force termination task runs.
|
| + testing::runDelayedTasks(kForceTerminationDelayInMs);
|
| + m_workerThread->waitForShutdownForTesting();
|
| + EXPECT_EQ(ExitCode::AsyncForciblyTerminated, getExitCode());
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_SyncForciblyTerminate)
|
| +TEST_F(WorkerThreadTest, SyncTerminate_WhileTaskIsRunning)
|
| {
|
| expectReportingCallsForWorkerForciblyTerminated();
|
| startWithSourceCodeNotToFinish();
|
| - m_mockWorkerReportingProxy->waitUntilScriptLoaded();
|
| + m_reportingProxy->waitUntilScriptLoaded();
|
|
|
| // terminateAndWait() synchronously terminates the worker execution.
|
| m_workerThread->terminateAndWait();
|
| EXPECT_EQ(ExitCode::SyncForciblyTerminated, getExitCode());
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_AsyncForciblyTerminate)
|
| +TEST_F(WorkerThreadTest, AsyncTerminateAndThenSyncTerminate_WhileTaskIsRunning)
|
| {
|
| const long long kForceTerminationDelayInMs = 10;
|
| setForceTerminationDelayInMs(kForceTerminationDelayInMs);
|
|
|
| expectReportingCallsForWorkerForciblyTerminated();
|
| startWithSourceCodeNotToFinish();
|
| - m_mockWorkerReportingProxy->waitUntilScriptLoaded();
|
| + m_reportingProxy->waitUntilScriptLoaded();
|
|
|
| // terminate() schedules a force termination task.
|
| m_workerThread->terminate();
|
| EXPECT_TRUE(isForceTerminationTaskScheduled());
|
| EXPECT_EQ(ExitCode::NotTerminated, getExitCode());
|
|
|
| - // Wait until the force termination task runs.
|
| - testing::runDelayedTasks(kForceTerminationDelayInMs);
|
| - m_workerThread->waitForShutdownForTesting();
|
| - EXPECT_EQ(ExitCode::AsyncForciblyTerminated, getExitCode());
|
| + // terminateAndWait() should overtake the scheduled force termination task.
|
| + m_workerThread->terminateAndWait();
|
| + EXPECT_FALSE(isForceTerminationTaskScheduled());
|
| + EXPECT_EQ(ExitCode::SyncForciblyTerminated, getExitCode());
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_AsyncForciblyTerminate_MultipleTimes)
|
| +TEST_F(WorkerThreadTest, Terminate_WhileDebuggerTaskIsRunningOnInitialization)
|
| {
|
| - const long long kForceTerminationDelayInMs = 10;
|
| - setForceTerminationDelayInMs(kForceTerminationDelayInMs);
|
| + EXPECT_CALL(*m_reportingProxy, didLoadWorkerScriptMock(_, _)).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didCreateWorkerGlobalScope(_)).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, willDestroyWorkerGlobalScope()).Times(1);
|
| + EXPECT_CALL(*m_reportingProxy, didTerminateWorkerThread()).Times(1);
|
| + EXPECT_CALL(*m_lifecycleObserver, contextDestroyed()).Times(1);
|
|
|
| - expectReportingCallsForWorkerForciblyTerminated();
|
| - startWithSourceCodeNotToFinish();
|
| - m_mockWorkerReportingProxy->waitUntilScriptLoaded();
|
| + std::unique_ptr<Vector<CSPHeaderAndType>> headers = wrapUnique(new Vector<CSPHeaderAndType>());
|
| + CSPHeaderAndType headerAndType("contentSecurityPolicy", ContentSecurityPolicyHeaderTypeReport);
|
| + headers->append(headerAndType);
|
|
|
| - // terminate() schedules a force termination task.
|
| + // Specify PauseWorkerGlobalScopeOnStart so that the worker thread can pause
|
| + // on initialziation to run debugger tasks.
|
| + std::unique_ptr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create(
|
| + KURL(ParsedURLString, "http://fake.url/"),
|
| + "fake user agent",
|
| + "//fake source code",
|
| + nullptr, /* cachedMetaData */
|
| + PauseWorkerGlobalScopeOnStart,
|
| + headers.get(),
|
| + "",
|
| + m_securityOrigin.get(),
|
| + nullptr, /* workerClients */
|
| + WebAddressSpaceLocal,
|
| + nullptr /* originTrialToken */,
|
| + nullptr /* WorkerSettings */,
|
| + V8CacheOptionsDefault);
|
| + m_workerThread->start(std::move(startupData));
|
| +
|
| + // Used to wait for worker thread termination in a debugger task on the
|
| + // worker thread.
|
| + WaitableEvent waitableEvent;
|
| + m_workerThread->appendDebuggerTask(crossThreadBind(&waitForSignalTask, crossThreadUnretained(m_workerThread.get()), crossThreadUnretained(&waitableEvent)));
|
| +
|
| + // Wait for the debugger task.
|
| + testing::enterRunLoop();
|
| + EXPECT_TRUE(m_workerThread->m_runningDebuggerTask);
|
| +
|
| + // terminate() should not schedule a force termination task because there is
|
| + // a running debugger task.
|
| m_workerThread->terminate();
|
| - EXPECT_TRUE(isForceTerminationTaskScheduled());
|
| + EXPECT_FALSE(isForceTerminationTaskScheduled());
|
| EXPECT_EQ(ExitCode::NotTerminated, getExitCode());
|
|
|
| // Multiple terminate() calls should not take effect.
|
| m_workerThread->terminate();
|
| m_workerThread->terminate();
|
| + EXPECT_FALSE(isForceTerminationTaskScheduled());
|
| EXPECT_EQ(ExitCode::NotTerminated, getExitCode());
|
|
|
| - // Wait until the force termination task runs.
|
| - testing::runDelayedTasks(kForceTerminationDelayInMs);
|
| - m_workerThread->waitForShutdownForTesting();
|
| - EXPECT_EQ(ExitCode::AsyncForciblyTerminated, getExitCode());
|
| -}
|
| -
|
| -TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_SyncForciblyTerminateAfterTerminationTaskIsScheduled)
|
| -{
|
| - const long long kForceTerminationDelayInMs = 10;
|
| - setForceTerminationDelayInMs(kForceTerminationDelayInMs);
|
| -
|
| - expectReportingCallsForWorkerForciblyTerminated();
|
| - startWithSourceCodeNotToFinish();
|
| - m_mockWorkerReportingProxy->waitUntilScriptLoaded();
|
| -
|
| - // terminate() schedules a force termination task.
|
| - m_workerThread->terminate();
|
| - EXPECT_TRUE(isForceTerminationTaskScheduled());
|
| + // Focible termination request should also respect the running debugger
|
| + // task.
|
| + m_workerThread->terminateInternal(WorkerThread::TerminationMode::Forcible);
|
| + EXPECT_FALSE(isForceTerminationTaskScheduled());
|
| EXPECT_EQ(ExitCode::NotTerminated, getExitCode());
|
|
|
| - // terminateAndWait() should overtake the scheduled force termination task.
|
| - m_workerThread->terminateAndWait();
|
| - EXPECT_FALSE(isForceTerminationTaskScheduled());
|
| - EXPECT_EQ(ExitCode::SyncForciblyTerminated, getExitCode());
|
| + // Resume the debugger task. Shutdown starts after that.
|
| + waitableEvent.signal();
|
| + m_workerThread->waitForShutdownForTesting();
|
| + EXPECT_EQ(ExitCode::GracefullyTerminated, getExitCode());
|
| }
|
|
|
| -TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_TerminateWhileDebuggerTaskIsRunning)
|
| +TEST_F(WorkerThreadTest, Terminate_WhileDebuggerTaskIsRunning)
|
| {
|
| - expectReportingCallsForWorkerForciblyTerminated();
|
| - startWithSourceCodeNotToFinish();
|
| - m_mockWorkerReportingProxy->waitUntilScriptLoaded();
|
| + expectReportingCalls();
|
| + start();
|
| + m_workerThread->waitForInit();
|
|
|
| - // Simulate that a debugger task is running.
|
| - // TODO(nhiroki): Run a real debugger task instead of simulation.
|
| - m_workerThread->m_runningDebuggerTask = true;
|
| + // Used to wait for worker thread termination in a debugger task on the
|
| + // worker thread.
|
| + WaitableEvent waitableEvent;
|
| + m_workerThread->appendDebuggerTask(crossThreadBind(&waitForSignalTask, crossThreadUnretained(m_workerThread.get()), crossThreadUnretained(&waitableEvent)));
|
| +
|
| + // Wait for the debugger task.
|
| + testing::enterRunLoop();
|
| + EXPECT_TRUE(m_workerThread->m_runningDebuggerTask);
|
|
|
| // terminate() should not schedule a force termination task because there is
|
| // a running debugger task.
|
| @@ -369,10 +353,10 @@ TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_TerminateWhileDebuggerT
|
| EXPECT_FALSE(isForceTerminationTaskScheduled());
|
| EXPECT_EQ(ExitCode::NotTerminated, getExitCode());
|
|
|
| - // Clean up in order to satisfy DCHECK in the dtor of WorkerThread.
|
| - m_workerThread->m_runningDebuggerTask = false;
|
| - m_workerThread->isolate()->TerminateExecution();
|
| + // Resume the debugger task. Shutdown starts after that.
|
| + waitableEvent.signal();
|
| m_workerThread->waitForShutdownForTesting();
|
| + EXPECT_EQ(ExitCode::GracefullyTerminated, getExitCode());
|
| }
|
|
|
| // TODO(nhiroki): Add tests for terminateAndWaitForAllWorkers.
|
|
|