chromium/components/performance_manager/worker_watcher_unittest.cc

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

#include "components/performance_manager/worker_watcher.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/containers/contains.h"
#include "base/functional/callback_helpers.h"
#include "base/not_fatal_until.h"
#include "base/observer_list.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/uuid.h"
#include "components/performance_manager/frame_node_source.h"
#include "components/performance_manager/graph/frame_node_impl.h"
#include "components/performance_manager/graph/page_node_impl.h"
#include "components/performance_manager/graph/process_node_impl.h"
#include "components/performance_manager/graph/worker_node_impl.h"
#include "components/performance_manager/performance_manager_impl.h"
#include "components/performance_manager/process_node_source.h"
#include "components/performance_manager/public/features.h"
#include "components/performance_manager/public/render_process_host_id.h"
#include "components/performance_manager/public/render_process_host_proxy.h"
#include "components/performance_manager/test_support/run_in_graph.h"
#include "content/public/browser/dedicated_worker_creator.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/service_worker_running_info.h"
#include "content/public/browser/shared_worker_service.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/fake_service_worker_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace performance_manager {

namespace {

// Generates a new sequential int ID. Used for things that need a unique ID
// and don't have a more specific generator.
int GenerateNextId() {}

// Generates a unique URL for a fake worker node.
GURL GenerateWorkerUrl() {}

// Generates a URL in a unique domain, which can be used to create identifiable
// origins or scope URL's for service workers.
GURL GenerateUniqueDomainUrl() {}

// Helper function to check that |worker_node| and |client_frame_node| are
// correctly hooked up together.
bool IsWorkerClient(WorkerNodeImpl* worker_node,
                    FrameNodeImpl* client_frame_node) {}

// Helper function to check that |worker_node| and |client_worker_node| are
// correctly hooked up together.
bool IsWorkerClient(WorkerNodeImpl* worker_node,
                    WorkerNodeImpl* client_worker_node) {}

// TestDedicatedWorkerService --------------------------------------------------

// A test DedicatedWorkerService that allows to simulate creating and destroying
// dedicated workers.
class TestDedicatedWorkerService : public content::DedicatedWorkerService {};

TestDedicatedWorkerService::TestDedicatedWorkerService() = default;

TestDedicatedWorkerService::~TestDedicatedWorkerService() = default;

void TestDedicatedWorkerService::AddObserver(Observer* observer) {}

void TestDedicatedWorkerService::RemoveObserver(Observer* observer) {}

void TestDedicatedWorkerService::EnumerateDedicatedWorkers(Observer* observer) {}

const blink::DedicatedWorkerToken&
TestDedicatedWorkerService::CreateDedicatedWorker(
    int worker_process_id,
    content::DedicatedWorkerCreator creator,
    const url::Origin& origin) {}

void TestDedicatedWorkerService::DestroyDedicatedWorker(
    const blink::DedicatedWorkerToken& token) {}

// TestSharedWorkerService -----------------------------------------------------

// A test SharedWorkerService that allows to simulate creating and destroying
// shared workers and adding clients to existing workers.
class TestSharedWorkerService : public content::SharedWorkerService {};

TestSharedWorkerService::TestSharedWorkerService() = default;

TestSharedWorkerService::~TestSharedWorkerService() = default;

void TestSharedWorkerService::AddObserver(Observer* observer) {}

void TestSharedWorkerService::RemoveObserver(Observer* observer) {}

void TestSharedWorkerService::EnumerateSharedWorkers(Observer* observer) {}

bool TestSharedWorkerService::TerminateWorker(
    const GURL& url,
    const std::string& name,
    const blink::StorageKey& storage_key,
    const blink::mojom::SharedWorkerSameSiteCookies same_site_cookies) {}

void TestSharedWorkerService::Shutdown() {}

blink::SharedWorkerToken TestSharedWorkerService::CreateSharedWorker(
    int worker_process_id,
    const url::Origin& origin) {}

void TestSharedWorkerService::DestroySharedWorker(
    const blink::SharedWorkerToken& shared_worker_token) {}

void TestSharedWorkerService::AddClient(
    const blink::SharedWorkerToken& shared_worker_token,
    content::GlobalRenderFrameHostId client_render_frame_host_id) {}

void TestSharedWorkerService::RemoveClient(
    const blink::SharedWorkerToken& shared_worker_token,
    content::GlobalRenderFrameHostId client_render_frame_host_id) {}

// TestServiceWorkerContextAdapter ---------------------------------------------

// A test ServiceWorkerContext that allows to simulate a worker starting and
// stopping and adding clients to running workers.
//
// Extends content::FakeServiceWorkerContext to avoid reimplementing all the
// unused virtual functions.
class TestServiceWorkerContextAdapter : public ServiceWorkerContextAdapter {};

TestServiceWorkerContextAdapter::TestServiceWorkerContextAdapter() = default;

TestServiceWorkerContextAdapter::~TestServiceWorkerContextAdapter() = default;

void TestServiceWorkerContextAdapter::AddObserver(
    content::ServiceWorkerContextObserver* observer) {}

void TestServiceWorkerContextAdapter::RemoveObserver(
    content::ServiceWorkerContextObserver* observer) {}

int64_t TestServiceWorkerContextAdapter::CreateServiceWorker() {}

void TestServiceWorkerContextAdapter::DestroyServiceWorker(int64_t version_id) {}

void TestServiceWorkerContextAdapter::StartServiceWorker(
    int64_t version_id,
    int worker_process_id,
    const GURL& worker_url,
    const GURL& scope_url) {}

void TestServiceWorkerContextAdapter::StopServiceWorker(int64_t version_id) {}

std::string TestServiceWorkerContextAdapter::AddClient(
    int64_t version_id,
    const content::ServiceWorkerClientInfo& client_info) {}

std::string TestServiceWorkerContextAdapter::AddClientWithClientID(
    int64_t version_id,
    std::string client_uuid,
    const content::ServiceWorkerClientInfo& client_info) {}

void TestServiceWorkerContextAdapter::RemoveClient(
    int64_t version_id,
    const std::string& client_uuid) {}

void TestServiceWorkerContextAdapter::OnControlleeNavigationCommitted(
    int64_t version_id,
    const std::string& client_uuid,
    content::GlobalRenderFrameHostId render_frame_host_id) {}

// TestProcessNodeSource -------------------------------------------------------

// A test ProcessNodeSource that allows creating process nodes on demand to
// "host" frames and workers.
class TestProcessNodeSource : public ProcessNodeSource {};

TestProcessNodeSource::TestProcessNodeSource() = default;

TestProcessNodeSource::~TestProcessNodeSource() {}

ProcessNodeImpl* TestProcessNodeSource::GetProcessNode(int render_process_id) {}

int TestProcessNodeSource::CreateProcessNode() {}

// TestFrameNodeSource ---------------------------------------------------------

class TestFrameNodeSource : public FrameNodeSource {};

TestFrameNodeSource::TestFrameNodeSource()
    :{}

TestFrameNodeSource::~TestFrameNodeSource() {}

FrameNodeImpl* TestFrameNodeSource::GetFrameNode(
    content::GlobalRenderFrameHostId render_frame_host_id) {}

void TestFrameNodeSource::SubscribeToFrameNode(
    content::GlobalRenderFrameHostId render_frame_host_id,
    OnbeforeFrameNodeRemovedCallback on_before_frame_node_removed_callback) {}

void TestFrameNodeSource::UnsubscribeFromFrameNode(
    content::GlobalRenderFrameHostId render_frame_host_id) {}

content::GlobalRenderFrameHostId TestFrameNodeSource::CreateFrameNode(
    int render_process_id,
    ProcessNodeImpl* process_node) {}

void TestFrameNodeSource::DeleteFrameNode(
    content::GlobalRenderFrameHostId render_frame_host_id) {}

void TestFrameNodeSource::InvokeAndRemoveCallback(FrameNodeImpl* frame_node) {}

}  // namespace

class WorkerWatcherTest : public testing::Test {};

WorkerWatcherTest::WorkerWatcherTest() = default;

WorkerWatcherTest::~WorkerWatcherTest() = default;

void WorkerWatcherTest::SetUp() {}

void WorkerWatcherTest::TearDown() {}

WorkerNodeImpl* WorkerWatcherTest::GetDedicatedWorkerNode(
    const blink::DedicatedWorkerToken& token) {}

WorkerNodeImpl* WorkerWatcherTest::GetSharedWorkerNode(
    const blink::SharedWorkerToken& shared_worker_token) {}

WorkerNodeImpl* WorkerWatcherTest::GetServiceWorkerNode(int64_t version_id) {}

// This test creates one dedicated worker with a frame client.
TEST_F(WorkerWatcherTest, SimpleDedicatedWorker) {}

TEST_F(WorkerWatcherTest, NestedDedicatedWorker) {}

// This test creates one shared worker with one client frame.
TEST_F(WorkerWatcherTest, SimpleSharedWorker) {}

// This test creates one service worker with one client frame.
TEST_F(WorkerWatcherTest, ServiceWorkerFrameClient) {}

// Ensures that the WorkerWatcher handles the case where a frame with a service
// worker is (briefly?) an uncommitted client of two versions. This presumably
// happens on version update or some such, or perhaps when a frame is a
// bona-fide client of two service workers. Apparently this happens quite
// rarely in the field.
TEST_F(WorkerWatcherTest, ServiceWorkerFrameClientOfTwoWorkers) {}

// Ensures that the WorkerWatcher handles the case where a frame with a service
// worker has a double client relationship with a service worker.
// This appears to be happening out in the real world, if quite rarely.
// See https://crbug.com/1143281#c33.
TEST_F(WorkerWatcherTest, ServiceWorkerTwoFrameClientRelationships) {}

// Ensures that the WorkerWatcher handles the case where a frame with a service
// worker is created but it's navigation is never committed before the
// FrameTreeNode is destroyed.
TEST_F(WorkerWatcherTest, ServiceWorkerFrameClientDestroyedBeforeCommit) {}

TEST_F(WorkerWatcherTest, AllTypesOfServiceWorkerClients) {}

// Tests that the WorkerWatcher can handle the case where the service worker
// starts after it has been assigned a client. In this case, the clients are not
// connected to the service worker until it starts. It also tests that when the
// service worker stops, its existing clients are also disconnected.
TEST_F(WorkerWatcherTest, ServiceWorkerStartsAndStopsWithExistingClients) {}

TEST_F(WorkerWatcherTest, SharedWorkerCrossProcessClient) {}

// Tests that the WorkerWatcher can handle the case where the service worker
// starts after it has been assigned a worker client, but the client has
// already died by the time the service worker starts.
TEST_F(WorkerWatcherTest, SharedWorkerStartsWithDeadWorkerClients) {}

TEST_F(WorkerWatcherTest, SharedWorkerDiesAsServiceWorkerClient) {}

TEST_F(WorkerWatcherTest, OneSharedWorkerTwoClients) {}

TEST_F(WorkerWatcherTest, OneClientTwoSharedWorkers) {}

TEST_F(WorkerWatcherTest, FrameDestroyed) {}

}  // namespace performance_manager