blob: b979310f5ca99f5a640cb923d5a6f4b34b77d3f7 [file] [log] [blame]
// Copyright 2016 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/dom/TaskRunnerHelper.h"
#include "core/inspector/ConsoleMessageStorage.h"
#include "core/testing/DummyPageHolder.h"
#include "core/workers/ThreadedWorkletGlobalScope.h"
#include "core/workers/ThreadedWorkletMessagingProxy.h"
#include "core/workers/ThreadedWorkletObjectProxy.h"
#include "core/workers/WorkerInspectorProxy.h"
#include "core/workers/WorkerThread.h"
#include "core/workers/WorkerThreadStartupData.h"
#include "core/workers/WorkerThreadTestHelper.h"
#include "core/workers/WorkletThreadHolder.h"
#include "platform/CrossThreadFunctional.h"
#include "platform/testing/UnitTestHelpers.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
class ThreadedWorkletThreadForTest : public WorkerThread {
public:
ThreadedWorkletThreadForTest(
WorkerLoaderProxyProvider* worker_loader_proxy_provider,
WorkerReportingProxy& worker_reporting_proxy)
: WorkerThread(WorkerLoaderProxy::Create(worker_loader_proxy_provider),
worker_reporting_proxy) {}
~ThreadedWorkletThreadForTest() override{};
WorkerBackingThread& GetWorkerBackingThread() override {
auto worklet_thread_holder =
WorkletThreadHolder<ThreadedWorkletThreadForTest>::GetInstance();
DCHECK(worklet_thread_holder);
return *worklet_thread_holder->GetThread();
}
void ClearWorkerBackingThread() override {}
WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope(
std::unique_ptr<WorkerThreadStartupData> startup_data) final {
RefPtr<SecurityOrigin> security_origin =
SecurityOrigin::Create(startup_data->script_url_);
return new ThreadedWorkletGlobalScope(
startup_data->script_url_, startup_data->user_agent_,
security_origin.Release(), this->GetIsolate(), this);
}
bool IsOwningBackingThread() const final { return false; }
static void EnsureSharedBackingThread() {
DCHECK(IsMainThread());
WorkletThreadHolder<ThreadedWorkletThreadForTest>::CreateForTest(
"ThreadedWorkletThreadForTest");
}
static void ClearSharedBackingThread() {
DCHECK(IsMainThread());
WorkletThreadHolder<ThreadedWorkletThreadForTest>::ClearInstance();
}
// Emulates API use on ThreadedWorkletGlobalScope.
void CountFeature(UseCounter::Feature feature) {
EXPECT_TRUE(IsCurrentThread());
GlobalScope()->CountFeature(feature);
GetParentFrameTaskRunners()
->Get(TaskType::kUnspecedTimer)
->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop));
}
// Emulates deprecated API use on ThreadedWorkletGlobalScope.
void CountDeprecation(UseCounter::Feature feature) {
EXPECT_TRUE(IsCurrentThread());
EXPECT_EQ(0u, GetConsoleMessageStorage()->size());
GlobalScope()->CountDeprecation(feature);
// countDeprecation() should add a warning message.
EXPECT_EQ(1u, GetConsoleMessageStorage()->size());
String console_message = GetConsoleMessageStorage()->at(0)->Message();
EXPECT_TRUE(console_message.Contains("deprecated"));
GetParentFrameTaskRunners()
->Get(TaskType::kUnspecedTimer)
->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop));
}
};
class ThreadedWorkletMessagingProxyForTest
: public ThreadedWorkletMessagingProxy {
public:
ThreadedWorkletMessagingProxyForTest(ExecutionContext* execution_context)
: ThreadedWorkletMessagingProxy(execution_context) {
worker_loader_proxy_provider_ =
WTF::MakeUnique<WorkerLoaderProxyProvider>();
worker_thread_ = WTF::MakeUnique<ThreadedWorkletThreadForTest>(
worker_loader_proxy_provider_.get(), WorkletObjectProxy());
ThreadedWorkletThreadForTest::EnsureSharedBackingThread();
}
~ThreadedWorkletMessagingProxyForTest() override {
worker_thread_->GetWorkerLoaderProxy()->DetachProvider(
worker_loader_proxy_provider_.get());
worker_thread_->TerminateAndWait();
ThreadedWorkletThreadForTest::ClearSharedBackingThread();
};
void Start() {
KURL script_url(kParsedURLString, "http://fake.url/");
std::unique_ptr<Vector<char>> cached_meta_data = nullptr;
Vector<CSPHeaderAndType> content_security_policy_headers;
String referrer_policy = "";
security_origin_ = SecurityOrigin::Create(script_url);
WorkerClients* worker_clients = nullptr;
Vector<String> origin_trial_tokens;
std::unique_ptr<WorkerSettings> worker_settings = nullptr;
worker_thread_->Start(
WorkerThreadStartupData::Create(
script_url, "fake user agent", "// fake source code",
std::move(cached_meta_data), kDontPauseWorkerGlobalScopeOnStart,
&content_security_policy_headers, referrer_policy,
security_origin_.Get(), worker_clients, kWebAddressSpaceLocal,
&origin_trial_tokens, std::move(worker_settings),
WorkerV8Settings::Default()),
GetParentFrameTaskRunners());
GetWorkerInspectorProxy()->WorkerThreadCreated(
ToDocument(GetExecutionContext()), worker_thread_.get(), script_url);
}
protected:
std::unique_ptr<WorkerThread> CreateWorkerThread(double origin_time) final {
NOTREACHED();
return nullptr;
}
private:
friend class ThreadedWorkletTest;
std::unique_ptr<WorkerLoaderProxyProvider> worker_loader_proxy_provider_;
RefPtr<SecurityOrigin> security_origin_;
};
class ThreadedWorkletTest : public ::testing::Test {
public:
void SetUp() override {
page_ = DummyPageHolder::Create();
messaging_proxy_ = WTF::MakeUnique<ThreadedWorkletMessagingProxyForTest>(
&page_->GetDocument());
}
ThreadedWorkletMessagingProxyForTest* MessagingProxy() {
return messaging_proxy_.get();
}
ThreadedWorkletThreadForTest* GetWorkerThread() {
return static_cast<ThreadedWorkletThreadForTest*>(
messaging_proxy_->GetWorkerThread());
}
Document& GetDocument() { return page_->GetDocument(); }
private:
std::unique_ptr<DummyPageHolder> page_;
std::unique_ptr<ThreadedWorkletMessagingProxyForTest> messaging_proxy_;
};
TEST_F(ThreadedWorkletTest, UseCounter) {
MessagingProxy()->Start();
// This feature is randomly selected.
const UseCounter::Feature kFeature1 = UseCounter::Feature::kRequestFileSystem;
// API use on the DedicatedWorkerGlobalScope should be recorded in UseCounter
// on the Document.
EXPECT_FALSE(UseCounter::IsCounted(GetDocument(), kFeature1));
TaskRunnerHelper::Get(TaskType::kUnspecedTimer, GetWorkerThread())
->PostTask(
BLINK_FROM_HERE,
CrossThreadBind(&ThreadedWorkletThreadForTest::CountFeature,
CrossThreadUnretained(GetWorkerThread()), kFeature1));
testing::EnterRunLoop();
EXPECT_TRUE(UseCounter::IsCounted(GetDocument(), kFeature1));
// This feature is randomly selected from Deprecation::deprecationMessage().
const UseCounter::Feature kFeature2 =
UseCounter::Feature::kPrefixedStorageInfo;
// Deprecated API use on the ThreadedWorkletGlobalScope should be recorded in
// UseCounter on the Document.
EXPECT_FALSE(UseCounter::IsCounted(GetDocument(), kFeature2));
TaskRunnerHelper::Get(TaskType::kUnspecedTimer, GetWorkerThread())
->PostTask(
BLINK_FROM_HERE,
CrossThreadBind(&ThreadedWorkletThreadForTest::CountDeprecation,
CrossThreadUnretained(GetWorkerThread()), kFeature2));
testing::EnterRunLoop();
EXPECT_TRUE(UseCounter::IsCounted(GetDocument(), kFeature2));
}
} // namespace blink