| Index: content/browser/background_sync/background_sync_manager_unittest.cc
|
| diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc
|
| index d65dbb7dd81b5b3a15fbf9f6e6557627952cf402..13413bce7aa6d449fbefd2c6fdd57eac83d1354a 100644
|
| --- a/content/browser/background_sync/background_sync_manager_unittest.cc
|
| +++ b/content/browser/background_sync/background_sync_manager_unittest.cc
|
| @@ -14,6 +14,7 @@
|
| #include "content/browser/service_worker/service_worker_context_wrapper.h"
|
| #include "content/browser/service_worker/service_worker_storage.h"
|
| #include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "net/base/network_change_notifier.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace content {
|
| @@ -50,13 +51,41 @@ void UnregisterServiceWorkerCallback(bool* called,
|
| *called = true;
|
| }
|
|
|
| +void OneShotSuccessfulCallback(
|
| + int* count,
|
| + const scoped_refptr<ServiceWorkerVersion>& active_version,
|
| + const ServiceWorkerVersion::StatusCallback& callback) {
|
| + *count += 1;
|
| + callback.Run(SERVICE_WORKER_OK);
|
| +}
|
| +
|
| +void OneShotFailedCallback(
|
| + int* count,
|
| + const scoped_refptr<ServiceWorkerVersion>& active_version,
|
| + const ServiceWorkerVersion::StatusCallback& callback) {
|
| + *count += 1;
|
| + callback.Run(SERVICE_WORKER_ERROR_FAILED);
|
| +}
|
| +
|
| +void OneShotDelayedCallback(
|
| + int* count,
|
| + ServiceWorkerVersion::StatusCallback* out_callback,
|
| + const scoped_refptr<ServiceWorkerVersion>& active_version,
|
| + const ServiceWorkerVersion::StatusCallback& callback) {
|
| + *count += 1;
|
| + *out_callback = callback;
|
| +}
|
| +
|
| } // namespace
|
|
|
| -// A BackgroundSyncManager that can simulate delaying and corrupting the
|
| -// backend. This class assumes (and verifies) that only one operation runs at a
|
| -// time.
|
| +// A BackgroundSyncManager that can simulate delaying and corrupting the backend
|
| +// storage and service worker onsync events.
|
| class TestBackgroundSyncManager : public BackgroundSyncManager {
|
| public:
|
| + using OneShotCallback =
|
| + base::Callback<void(const scoped_refptr<ServiceWorkerVersion>&,
|
| + const ServiceWorkerVersion::StatusCallback&)>;
|
| +
|
| explicit TestBackgroundSyncManager(
|
| const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
|
| : BackgroundSyncManager(service_worker_context) {}
|
| @@ -89,6 +118,9 @@ class TestBackgroundSyncManager : public BackgroundSyncManager {
|
| corrupt_backend_ = corrupt_backend;
|
| }
|
| void set_delay_backend(bool delay_backend) { delay_backend_ = delay_backend; }
|
| + void set_one_shot_callback(const OneShotCallback& callback) {
|
| + one_shot_callback_ = callback;
|
| + }
|
|
|
| protected:
|
| void StoreDataInBackend(
|
| @@ -134,25 +166,48 @@ class TestBackgroundSyncManager : public BackgroundSyncManager {
|
| Continue();
|
| }
|
|
|
| + void FireOneShotSync(
|
| + const scoped_refptr<ServiceWorkerVersion>& active_version,
|
| + const ServiceWorkerVersion::StatusCallback& callback) override {
|
| + if (one_shot_callback_.is_null()) {
|
| + BackgroundSyncManager::FireOneShotSync(active_version, callback);
|
| + } else {
|
| + one_shot_callback_.Run(active_version, callback);
|
| + }
|
| + }
|
| +
|
| private:
|
| bool corrupt_backend_ = false;
|
| bool delay_backend_ = false;
|
| base::Closure continuation_;
|
| + OneShotCallback one_shot_callback_;
|
| };
|
|
|
| class BackgroundSyncManagerTest : public testing::Test {
|
| public:
|
| BackgroundSyncManagerTest()
|
| : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
|
| + network_change_notifier_(net::NetworkChangeNotifier::CreateMock()),
|
| + test_background_sync_manager_(nullptr),
|
| sync_reg_1_(BackgroundSyncManager::BackgroundSyncRegistration()),
|
| sync_reg_2_(BackgroundSyncManager::BackgroundSyncRegistration()),
|
| callback_error_(BackgroundSyncManager::ERROR_TYPE_OK),
|
| - callback_sw_status_code_(SERVICE_WORKER_OK) {
|
| + callback_sw_status_code_(SERVICE_WORKER_OK),
|
| + sync_events_called_(0) {
|
| sync_reg_1_.tag = "foo";
|
| + sync_reg_1_.periodicity = SYNC_ONE_SHOT;
|
| + sync_reg_1_.network_state = NETWORK_STATE_ONLINE;
|
| + sync_reg_1_.power_state = POWER_STATE_AUTO;
|
| +
|
| sync_reg_2_.tag = "bar";
|
| + sync_reg_2_.periodicity = SYNC_ONE_SHOT;
|
| + sync_reg_2_.network_state = NETWORK_STATE_ONLINE;
|
| + sync_reg_2_.power_state = POWER_STATE_AUTO;
|
| }
|
|
|
| void SetUp() override {
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
| +
|
| helper_.reset(
|
| new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
|
|
|
| @@ -195,6 +250,12 @@ class BackgroundSyncManagerTest : public testing::Test {
|
| EXPECT_TRUE(sw_registration_2_);
|
| }
|
|
|
| + void SetNetwork(net::NetworkChangeNotifier::ConnectionType connection_type) {
|
| + net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
|
| + connection_type);
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| void StatusAndRegistrationCallback(
|
| bool* was_called,
|
| BackgroundSyncManager::ErrorType error,
|
| @@ -211,12 +272,11 @@ class BackgroundSyncManagerTest : public testing::Test {
|
| }
|
|
|
| protected:
|
| - TestBackgroundSyncManager* UseTestBackgroundSyncManager() {
|
| - TestBackgroundSyncManager* manager =
|
| + void UseTestBackgroundSyncManager() {
|
| + test_background_sync_manager_ =
|
| new TestBackgroundSyncManager(helper_->context_wrapper());
|
| - background_sync_manager_.reset(manager);
|
| - manager->DoInit();
|
| - return manager;
|
| + test_background_sync_manager_->DoInit();
|
| + background_sync_manager_.reset(test_background_sync_manager_);
|
| }
|
|
|
| bool Register(const BackgroundSyncManager::BackgroundSyncRegistration&
|
| @@ -306,9 +366,45 @@ class BackgroundSyncManagerTest : public testing::Test {
|
| return sw_id == sw_registration_id_1_ ? GURL(kPattern1) : GURL(kPattern2);
|
| }
|
|
|
| + void InitSyncEventTest() {
|
| + UseTestBackgroundSyncManager();
|
| + test_background_sync_manager_->set_one_shot_callback(
|
| + base::Bind(OneShotSuccessfulCallback, &sync_events_called_));
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + void InitFailedSyncEventTest() {
|
| + UseTestBackgroundSyncManager();
|
| + test_background_sync_manager_->set_one_shot_callback(
|
| + base::Bind(OneShotFailedCallback, &sync_events_called_));
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + void InitDelayedSyncEventTest() {
|
| + UseTestBackgroundSyncManager();
|
| + test_background_sync_manager_->set_one_shot_callback(base::Bind(
|
| + OneShotDelayedCallback, &sync_events_called_, &sync_fired_callback_));
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + void RegisterAndVerifySyncEventDelayed(
|
| + const BackgroundSyncManager::BackgroundSyncRegistration&
|
| + sync_registration) {
|
| + int sync_events_called = sync_events_called_;
|
| + EXPECT_TRUE(sync_fired_callback_.is_null());
|
| +
|
| + EXPECT_TRUE(Register(sync_registration));
|
| +
|
| + EXPECT_EQ(sync_events_called + 1, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| + EXPECT_FALSE(sync_fired_callback_.is_null());
|
| + }
|
| +
|
| TestBrowserThreadBundle browser_thread_bundle_;
|
| + scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
|
| scoped_ptr<EmbeddedWorkerTestHelper> helper_;
|
| scoped_ptr<BackgroundSyncManager> background_sync_manager_;
|
| + TestBackgroundSyncManager* test_background_sync_manager_;
|
|
|
| int64 sw_registration_id_1_;
|
| int64 sw_registration_id_2_;
|
| @@ -322,6 +418,8 @@ class BackgroundSyncManagerTest : public testing::Test {
|
| BackgroundSyncManager::ErrorType callback_error_;
|
| BackgroundSyncManager::BackgroundSyncRegistration callback_registration_;
|
| ServiceWorkerStatusCode callback_sw_status_code_;
|
| + int sync_events_called_;
|
| + ServiceWorkerVersion::StatusCallback sync_fired_callback_;
|
| };
|
|
|
| TEST_F(BackgroundSyncManagerTest, Register) {
|
| @@ -386,10 +484,10 @@ TEST_F(BackgroundSyncManagerTest, RegisterOverlappingPeriodicAndOneShotTags) {
|
| }
|
|
|
| TEST_F(BackgroundSyncManagerTest, RegisterBadBackend) {
|
| - TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
|
| - manager->set_corrupt_backend(true);
|
| + UseTestBackgroundSyncManager();
|
| + test_background_sync_manager_->set_corrupt_backend(true);
|
| EXPECT_FALSE(Register(sync_reg_1_));
|
| - manager->set_corrupt_backend(false);
|
| + test_background_sync_manager_->set_corrupt_backend(false);
|
| EXPECT_FALSE(Register(sync_reg_1_));
|
| EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| }
|
| @@ -410,15 +508,15 @@ TEST_F(BackgroundSyncManagerTest, GetRegistrationExisting) {
|
| }
|
|
|
| TEST_F(BackgroundSyncManagerTest, GetRegistrationBadBackend) {
|
| - TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
|
| + UseTestBackgroundSyncManager();
|
| EXPECT_TRUE(Register(sync_reg_1_));
|
| - manager->set_corrupt_backend(true);
|
| + test_background_sync_manager_->set_corrupt_backend(true);
|
| EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| EXPECT_FALSE(Register(sync_reg_2_));
|
| // Registration should have discovered the bad backend and disabled the
|
| // BackgroundSyncManager.
|
| EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| - manager->set_corrupt_backend(false);
|
| + test_background_sync_manager_->set_corrupt_backend(false);
|
| EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| }
|
|
|
| @@ -454,15 +552,15 @@ TEST_F(BackgroundSyncManagerTest, UnregisterSecond) {
|
| }
|
|
|
| TEST_F(BackgroundSyncManagerTest, UnregisterBadBackend) {
|
| - TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
|
| + UseTestBackgroundSyncManager();
|
| sync_reg_1_.min_period += 1;
|
| EXPECT_TRUE(Register(sync_reg_1_));
|
| EXPECT_TRUE(Register(sync_reg_2_));
|
| - manager->set_corrupt_backend(true);
|
| + test_background_sync_manager_->set_corrupt_backend(true);
|
| EXPECT_FALSE(Unregister(callback_registration_));
|
| // Unregister should have discovered the bad backend and disabled the
|
| // BackgroundSyncManager.
|
| - manager->set_corrupt_backend(false);
|
| + test_background_sync_manager_->set_corrupt_backend(false);
|
| EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| EXPECT_FALSE(GetRegistration(sync_reg_2_));
|
| }
|
| @@ -785,4 +883,196 @@ TEST_F(BackgroundSyncManagerTest, OverlappingPeriodicAndOneShotTags) {
|
| EXPECT_FALSE(GetRegistration(sync_reg_2_));
|
| }
|
|
|
| +TEST_F(BackgroundSyncManagerTest, OneShotFiresOnRegistration) {
|
| + InitSyncEventTest();
|
| +
|
| + EXPECT_TRUE(Register(sync_reg_1_));
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, OneShotFiresOnNetworkChange) {
|
| + InitSyncEventTest();
|
| +
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
|
| + EXPECT_TRUE(Register(sync_reg_1_));
|
| + EXPECT_EQ(0, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| +
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, MultipleOneShotsFireOnNetworkChange) {
|
| + InitSyncEventTest();
|
| +
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
|
| + EXPECT_TRUE(Register(sync_reg_1_));
|
| + EXPECT_TRUE(Register(sync_reg_2_));
|
| + EXPECT_EQ(0, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| + EXPECT_TRUE(GetRegistration(sync_reg_2_));
|
| +
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(2, sync_events_called_);
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| + EXPECT_FALSE(GetRegistration(sync_reg_2_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, OneShotFiresOnManagerRestart) {
|
| + InitSyncEventTest();
|
| +
|
| + // Initially the event won't run because there is no network.
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
|
| + EXPECT_TRUE(Register(sync_reg_1_));
|
| + EXPECT_EQ(0, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| +
|
| + // Simulate closing the browser.
|
| + background_sync_manager_.reset();
|
| +
|
| + // The next time the manager is started, the network is good.
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
| + InitSyncEventTest();
|
| +
|
| + // The event should have fired.
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, FailedOneShotStillExists) {
|
| + InitFailedSyncEventTest();
|
| +
|
| + EXPECT_TRUE(Register(sync_reg_1_));
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| +
|
| + // The failed one-shot should stay registered but not fire until the
|
| + // ServiceWorker is reloaded with an active client. Therefore, changing the
|
| + // network should not cause the event to run again.
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_2G);
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, DelayOneShotMidSync) {
|
| + InitDelayedSyncEventTest();
|
| +
|
| + RegisterAndVerifySyncEventDelayed(sync_reg_1_);
|
| +
|
| + // Finish firing the event and verify that the registration is removed.
|
| + sync_fired_callback_.Run(SERVICE_WORKER_OK);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, OverwriteRegistrationMidSync) {
|
| + InitDelayedSyncEventTest();
|
| +
|
| + sync_reg_1_.network_state = NETWORK_STATE_ANY;
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
|
| +
|
| + RegisterAndVerifySyncEventDelayed(sync_reg_1_);
|
| +
|
| + // Don't delay the next sync.
|
| + test_background_sync_manager_->set_one_shot_callback(
|
| + base::Bind(OneShotSuccessfulCallback, &sync_events_called_));
|
| +
|
| + // Register a different sync event with the same tag, overwriting the first.
|
| + sync_reg_1_.network_state = NETWORK_STATE_ONLINE;
|
| + EXPECT_TRUE(Register(sync_reg_1_));
|
| +
|
| + // The new sync event won't run as the network requirements aren't met.
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| +
|
| + // Finish the first event, note that the second is still registered.
|
| + sync_fired_callback_.Run(SERVICE_WORKER_OK);
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| +
|
| + // Change the network and the second should run.
|
| + SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(2, sync_events_called_);
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, ReregisterOneShotMidSync) {
|
| + InitDelayedSyncEventTest();
|
| +
|
| + RegisterAndVerifySyncEventDelayed(sync_reg_1_);
|
| +
|
| + // Register the same sync, but don't delay it. It shouldn't run as it's
|
| + // already firing.
|
| + test_background_sync_manager_->set_one_shot_callback(
|
| + base::Bind(OneShotSuccessfulCallback, &sync_events_called_));
|
| + EXPECT_TRUE(Register(sync_reg_1_));
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_TRUE(GetRegistration(sync_reg_1_));
|
| +
|
| + // Finish the original event, note that the second never runs.
|
| + sync_fired_callback_.Run(SERVICE_WORKER_OK);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(1, sync_events_called_);
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, UnregisterOneShotMidSync) {
|
| + InitDelayedSyncEventTest();
|
| +
|
| + RegisterAndVerifySyncEventDelayed(sync_reg_1_);
|
| +
|
| + EXPECT_TRUE(Unregister(callback_registration_));
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| +
|
| + sync_fired_callback_.Run(SERVICE_WORKER_OK);
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, BadBackendMidSync) {
|
| + InitDelayedSyncEventTest();
|
| +
|
| + RegisterAndVerifySyncEventDelayed(sync_reg_1_);
|
| +
|
| + test_background_sync_manager_->set_corrupt_backend(true);
|
| + sync_fired_callback_.Run(SERVICE_WORKER_OK);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // The backend should now be disabled because it couldn't unregister the
|
| + // one-shot.
|
| + EXPECT_FALSE(Register(sync_reg_2_));
|
| + EXPECT_FALSE(RegisterWithServiceWorkerId(sw_registration_id_2_, sync_reg_2_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, UnregisterServiceWorkerMidSync) {
|
| + InitDelayedSyncEventTest();
|
| +
|
| + RegisterAndVerifySyncEventDelayed(sync_reg_1_);
|
| + UnregisterServiceWorker(sw_registration_id_1_);
|
| +
|
| + sync_fired_callback_.Run(SERVICE_WORKER_OK);
|
| +
|
| + // The backend isn't disabled, but the first service worker registration is
|
| + // gone.
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| + EXPECT_FALSE(Register(sync_reg_1_));
|
| + EXPECT_TRUE(RegisterWithServiceWorkerId(sw_registration_id_2_, sync_reg_1_));
|
| +}
|
| +
|
| +TEST_F(BackgroundSyncManagerTest, KillManagerMidSync) {
|
| + InitDelayedSyncEventTest();
|
| +
|
| + RegisterAndVerifySyncEventDelayed(sync_reg_1_);
|
| +
|
| + // Create a new manager which should fire the sync again on init.
|
| + InitSyncEventTest();
|
| + EXPECT_FALSE(GetRegistration(sync_reg_1_));
|
| + EXPECT_EQ(2, sync_events_called_);
|
| +}
|
| +
|
| } // namespace content
|
|
|