// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/workers/WorkerThread.h"

#include "core/workers/WorkerThreadTestHelper.h"
#include "platform/testing/UnitTestHelpers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "wtf/PtrUtil.h"
#include <memory>

using testing::_;
using testing::AtMost;

namespace blink {

namespace {

// Called from WorkerThread::startRunningDebuggerTasksOnPauseOnWorkerThread as a
// debugger task.
void waitForTermination(WorkerThread* workerThread)
{
    EXPECT_TRUE(workerThread->isCurrentThread());

    // Notify the main thread that the debugger task is waiting for termination.
    Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(&testing::exitRunLoop));
    workerThread->terminationEvent()->wait();
}

} // namespace

class WorkerThreadTest : public ::testing::Test {
public:
    void SetUp() override
    {
        m_mockWorkerLoaderProxyProvider = wrapUnique(new MockWorkerLoaderProxyProvider());
        m_mockWorkerReportingProxy = wrapUnique(new MockWorkerReportingProxy());
        m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http://fake.url/"));
        m_workerThread = wrapUnique(new WorkerThreadForTest(
            m_mockWorkerLoaderProxyProvider.get(),
            *m_mockWorkerReportingProxy));
        m_mockWorkerThreadLifecycleObserver = new MockWorkerThreadLifecycleObserver(m_workerThread->getWorkerThreadLifecycleContext());
    }

    void TearDown() override
    {
        m_workerThread->workerLoaderProxy()->detachProvider(m_mockWorkerLoaderProxyProvider.get());
    }

    void start()
    {
        m_workerThread->startWithSourceCode(m_securityOrigin.get(), "//fake source code");
    }

    void startWithSourceCodeNotToFinish()
    {
        // Use a JavaScript source code that makes an infinite loop so that we
        // can catch some kind of issues as a timeout.
        m_workerThread->startWithSourceCode(m_securityOrigin.get(), "while(true) {}");
    }

    void setForceTerminationDelayInMs(long long forceTerminationDelayInMs)
    {
        m_workerThread->m_forceTerminationDelayInMs = forceTerminationDelayInMs;
    }

    bool isForceTerminationTaskScheduled()
    {
        return m_workerThread->m_scheduledForceTerminationTask.get();
    }

protected:
    void expectReportingCalls()
    {
        EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Times(1);
        EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)).Times(1);
        EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times(1);
        EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(1);
        EXPECT_CALL(*m_mockWorkerThreadLifecycleObserver, contextDestroyed()).Times(1);
    }

    void expectReportingCallsForWorkerPossiblyTerminatedBeforeInitialization()
    {
        EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Times(AtMost(1));
        EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(_)).Times(AtMost(1));
        EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times(1);
        EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(AtMost(1));
        EXPECT_CALL(*m_mockWorkerThreadLifecycleObserver, contextDestroyed()).Times(1);
    }

    void expectReportingCallsForWorkerForciblyTerminated()
    {
        EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Times(1);
        EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(false)).Times(1);
        EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times(1);
        EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(1);
        EXPECT_CALL(*m_mockWorkerThreadLifecycleObserver, contextDestroyed()).Times(1);
    }

    RefPtr<SecurityOrigin> m_securityOrigin;
    std::unique_ptr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvider;
    std::unique_ptr<MockWorkerReportingProxy> m_mockWorkerReportingProxy;
    std::unique_ptr<WorkerThreadForTest> m_workerThread;
    Persistent<MockWorkerThreadLifecycleObserver> m_mockWorkerThreadLifecycleObserver;
};

TEST_F(WorkerThreadTest, StartAndTerminate_AsyncTerminate)
{
    expectReportingCalls();
    start();
    m_workerThread->waitForInit();

    // The worker thread is not being blocked, so the worker thread should be
    // gracefully shut down.
    m_workerThread->terminate();
    EXPECT_TRUE(isForceTerminationTaskScheduled());
    m_workerThread->waitForShutdownForTesting();
    EXPECT_EQ(WorkerThread::ExitCode::GracefullyTerminated, m_workerThread->getExitCode());
}

TEST_F(WorkerThreadTest, StartAndTerminate_SyncTerminate)
{
    expectReportingCalls();
    start();
    m_workerThread->waitForInit();
    m_workerThread->terminateAndWait();
    EXPECT_EQ(WorkerThread::ExitCode::SyncForciblyTerminated, m_workerThread->getExitCode());
}

TEST_F(WorkerThreadTest, StartAndTerminateImmediately_AsyncTerminate)
{
    expectReportingCallsForWorkerPossiblyTerminatedBeforeInitialization();
    start();

    // There are two possible cases depending on timing:
    // (1) If the thread hasn't been initialized on the worker thread yet,
    // terminate() should not attempt to shut down the thread.
    // (2) If the thread has already been initialized on the worker thread,
    // terminate() should gracefully shut down the thread.
    m_workerThread->terminate();
    m_workerThread->waitForShutdownForTesting();
    WorkerThread::ExitCode exitCode = m_workerThread->getExitCode();
    EXPECT_EQ(WorkerThread::ExitCode::GracefullyTerminated, exitCode);
}

TEST_F(WorkerThreadTest, StartAndTerminateImmediately_SyncTerminate)
{
    expectReportingCallsForWorkerPossiblyTerminatedBeforeInitialization();
    start();

    // There are two possible cases depending on timing:
    // (1) If the thread hasn't been initialized on the worker thread yet,
    // terminateAndWait() should not attempt to shut down the thread.
    // (2) If the thread has already been initialized on the worker thread,
    // terminateAndWait() should synchronously forcibly terminates the worker
    // execution.
    m_workerThread->terminateAndWait();
    WorkerThread::ExitCode exitCode = m_workerThread->getExitCode();
    EXPECT_TRUE(WorkerThread::ExitCode::GracefullyTerminated == exitCode || WorkerThread::ExitCode::SyncForciblyTerminated == exitCode);
}

TEST_F(WorkerThreadTest, StartAndTerminateOnInitialization_TerminateWhileDebuggerTaskIsRunning)
{
    EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Times(1);
    EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times(1);
    EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(1);
    EXPECT_CALL(*m_mockWorkerThreadLifecycleObserver, contextDestroyed()).Times(1);

    std::unique_ptr<Vector<CSPHeaderAndType>> headers = wrapUnique(new Vector<CSPHeaderAndType>());
    CSPHeaderAndType headerAndType("contentSecurityPolicy", ContentSecurityPolicyHeaderTypeReport);
    headers->append(headerAndType);

    // 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 */,
            V8CacheOptionsDefault);
    m_workerThread->start(std::move(startupData));

    m_workerThread->appendDebuggerTask(threadSafeBind(&waitForTermination, AllowCrossThreadAccess(m_workerThread.get())));

    // Wait for the debugger task.
    testing::enterRunLoop();

    // Start termination while the debugger task is running.
    EXPECT_TRUE(m_workerThread->m_runningDebuggerTask);
    m_workerThread->terminateAndWait();
    EXPECT_EQ(WorkerThread::ExitCode::GracefullyTerminated, m_workerThread->getExitCode());
}

TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_SyncForciblyTerminate)
{
    expectReportingCallsForWorkerForciblyTerminated();
    startWithSourceCodeNotToFinish();
    m_workerThread->waitUntilScriptLoaded();

    // terminateAndWait() synchronously terminates the worker execution.
    m_workerThread->terminateAndWait();
    EXPECT_EQ(WorkerThread::ExitCode::SyncForciblyTerminated, m_workerThread->getExitCode());
}

TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_AsyncForciblyTerminate)
{
    const long long kForceTerminationDelayInMs = 10;
    setForceTerminationDelayInMs(kForceTerminationDelayInMs);

    expectReportingCallsForWorkerForciblyTerminated();
    startWithSourceCodeNotToFinish();
    m_workerThread->waitUntilScriptLoaded();

    // terminate() schedules a force termination task.
    m_workerThread->terminate();
    EXPECT_TRUE(isForceTerminationTaskScheduled());
    EXPECT_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->getExitCode());

    // Wait until the force termination task runs.
    testing::runDelayedTasks(kForceTerminationDelayInMs);
    m_workerThread->waitForShutdownForTesting();
    EXPECT_EQ(WorkerThread::ExitCode::AsyncForciblyTerminated, m_workerThread->getExitCode());
}

TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_AsyncForciblyTerminate_MultipleTimes)
{
    const long long kForceTerminationDelayInMs = 10;
    setForceTerminationDelayInMs(kForceTerminationDelayInMs);

    expectReportingCallsForWorkerForciblyTerminated();
    startWithSourceCodeNotToFinish();
    m_workerThread->waitUntilScriptLoaded();

    // terminate() schedules a force termination task.
    m_workerThread->terminate();
    EXPECT_TRUE(isForceTerminationTaskScheduled());
    EXPECT_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->getExitCode());

    // Multiple terminate() calls should not take effect.
    m_workerThread->terminate();
    m_workerThread->terminate();
    EXPECT_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->getExitCode());

    // Wait until the force termination task runs.
    testing::runDelayedTasks(kForceTerminationDelayInMs);
    m_workerThread->waitForShutdownForTesting();
    EXPECT_EQ(WorkerThread::ExitCode::AsyncForciblyTerminated, m_workerThread->getExitCode());
}

TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_SyncForciblyTerminateAfterTerminationTaskIsScheduled)
{
    const long long kForceTerminationDelayInMs = 10;
    setForceTerminationDelayInMs(kForceTerminationDelayInMs);

    expectReportingCallsForWorkerForciblyTerminated();
    startWithSourceCodeNotToFinish();
    m_workerThread->waitUntilScriptLoaded();

    // terminate() schedules a force termination task.
    m_workerThread->terminate();
    EXPECT_TRUE(isForceTerminationTaskScheduled());
    EXPECT_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->getExitCode());

    // terminateAndWait() should overtake the scheduled force termination task.
    m_workerThread->terminateAndWait();
    EXPECT_FALSE(isForceTerminationTaskScheduled());
    EXPECT_EQ(WorkerThread::ExitCode::SyncForciblyTerminated, m_workerThread->getExitCode());
}

TEST_F(WorkerThreadTest, StartAndTerminateOnScriptLoaded_TerminateWhileDebuggerTaskIsRunning)
{
    expectReportingCallsForWorkerForciblyTerminated();
    startWithSourceCodeNotToFinish();
    m_workerThread->waitUntilScriptLoaded();

    // Simulate that a debugger task is running.
    m_workerThread->m_runningDebuggerTask = true;

    // terminate() should not schedule a force termination task because there is
    // a running debugger task.
    m_workerThread->terminate();
    EXPECT_FALSE(isForceTerminationTaskScheduled());
    EXPECT_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->getExitCode());

    // Multiple terminate() calls should not take effect.
    m_workerThread->terminate();
    m_workerThread->terminate();
    EXPECT_FALSE(isForceTerminationTaskScheduled());
    EXPECT_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->getExitCode());

    // Focible termination request should also respect the running debugger
    // task.
    m_workerThread->terminateInternal(WorkerThread::TerminationMode::Forcible);
    EXPECT_FALSE(isForceTerminationTaskScheduled());
    EXPECT_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->getExitCode());

    // Clean up in order to satisfy DCHECKs in dtors.
    m_workerThread->m_runningDebuggerTask = false;
    m_workerThread->forciblyTerminateExecution();
    m_workerThread->waitForShutdownForTesting();
}

// TODO(nhiroki): Add tests for terminateAndWaitForAllWorkers.

} // namespace blink
