blob: 41bbe372ed5198916ca3d54820aee4869895dd91 [file] [log] [blame]
// Copyright 2019 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 "content/browser/background_sync/background_sync_launcher.h"
#include <map>
#include <vector>
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/background_sync_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#if defined(OS_ANDROID)
#include "base/run_loop.h"
#endif
namespace content {
namespace {
const char kUrl_1[] = "https://example.com";
const char kUrl_2[] = "https://whereswaldo.com";
class TestBrowserClient : public ContentBrowserClient {
public:
TestBrowserClient() = default;
~TestBrowserClient() override = default;
void GetStoragePartitionConfigForSite(BrowserContext* browser_context,
const GURL& site,
bool can_be_default,
std::string* partition_domain,
std::string* partition_name,
bool* in_memory) override {
DCHECK(browser_context);
DCHECK(partition_domain);
DCHECK(partition_name);
auto partition_num = std::to_string(++partition_count_);
*partition_domain = std::string("PartitionDomain") + partition_num;
*partition_name = std::string("Partition") + partition_num;
*in_memory = false;
}
private:
int partition_count_ = 0;
};
} // namespace
class BackgroundSyncLauncherTest : public testing::Test {
public:
BackgroundSyncLauncherTest()
: browser_thread_bundle_(TestBrowserThreadBundle::MainThreadType::UI) {}
void SetUpBrowserContext(const std::vector<GURL>& urls,
const std::map<GURL, int>& wakeup_deltas = {}) {
DCHECK(!urls.empty());
for (const auto& url : urls) {
auto* storage_partition = BrowserContext::GetStoragePartitionForSite(
&test_browser_context_, url);
auto iter = wakeup_deltas.find(url);
if (iter == wakeup_deltas.end())
continue;
static_cast<StoragePartitionImpl*>(storage_partition)
->GetBackgroundSyncContext()
->set_wakeup_delta_for_testing(
base::TimeDelta::FromMilliseconds(iter->second));
}
}
void SetUp() override {
original_client_ = SetBrowserClientForTesting(&browser_client_);
}
void TearDown() override { SetBrowserClientForTesting(original_client_); }
base::TimeDelta GetSoonestWakeupDelta() {
base::TimeDelta to_return;
BackgroundSyncLauncher::GetSoonestWakeupDelta(
&test_browser_context_,
base::BindLambdaForTesting(
[&to_return](base::TimeDelta soonest_wakeup_delta) {
to_return = soonest_wakeup_delta;
}));
browser_thread_bundle_.RunUntilIdle();
return to_return;
}
#if defined(OS_ANDROID)
void FireBackgroundSyncEventsForAllPartitions() {
num_invocations_fire_background_sync_events_ = 0;
auto done_closure = base::BindLambdaForTesting(
[&]() { num_invocations_fire_background_sync_events_++; });
BrowserContext::ForEachStoragePartition(
&test_browser_context_,
base::BindRepeating(
[](base::OnceClosure done_closure,
StoragePartition* storage_partition) {
BackgroundSyncContext* sync_context =
storage_partition->GetBackgroundSyncContext();
sync_context->FireBackgroundSyncEvents(std::move(done_closure));
},
std::move(done_closure)));
browser_thread_bundle_.RunUntilIdle();
}
int NumInvocationsOfFireBackgroundSyncEvents() {
return num_invocations_fire_background_sync_events_;
}
#endif
protected:
void DidFireBackgroundSyncEvents() {
num_invocations_fire_background_sync_events_++;
}
TestBrowserThreadBundle browser_thread_bundle_;
TestBrowserClient browser_client_;
ContentBrowserClient* original_client_;
TestBrowserContext test_browser_context_;
int num_invocations_fire_background_sync_events_ = 0;
};
// Tests that we pick the correct wake up delta for the one-shot Background
// Sync wake up task, across all storage partitions.
TEST_F(BackgroundSyncLauncherTest, CorrectSoonestWakeupDeltaIsPicked) {
std::vector<GURL> urls = {GURL(kUrl_1), GURL(kUrl_2)};
// Add two storage partitions. Verify that we set the soonest wake up delta
// to base::TimeDelta::Max(). This will cause cancellation of the wakeup
// task.
SetUpBrowserContext(urls);
EXPECT_TRUE(GetSoonestWakeupDelta().is_max());
// Add two more storage partitions, this time with wakeup_deltas.
// Verify that we pick the smaller of the two.
int delta_ms = 0;
std::map<GURL, int> wakeup_deltas;
for (const auto& url : urls)
wakeup_deltas[url] = delta_ms += 1000;
SetUpBrowserContext(urls, wakeup_deltas);
EXPECT_EQ(GetSoonestWakeupDelta().InMilliseconds(), 1000);
}
#if defined(OS_ANDROID)
TEST_F(BackgroundSyncLauncherTest, FireBackgroundSyncEvents) {
std::vector<GURL> urls = {GURL(kUrl_1), GURL(kUrl_2)};
SetUpBrowserContext(urls);
ASSERT_NO_FATAL_FAILURE(FireBackgroundSyncEventsForAllPartitions());
EXPECT_EQ(NumInvocationsOfFireBackgroundSyncEvents(), 2);
}
#endif
} // namespace content