Chromium Code Reviews| Index: components/gcm_driver/gcm_driver_desktop_unittest.cc |
| diff --git a/components/gcm_driver/gcm_driver_desktop_unittest.cc b/components/gcm_driver/gcm_driver_desktop_unittest.cc |
| index cec87efab94d97f113a47c54d7ceb6cf29928143..a9e01b40a2ba5c7d188f35456c68e0674f011e7f 100644 |
| --- a/components/gcm_driver/gcm_driver_desktop_unittest.cc |
| +++ b/components/gcm_driver/gcm_driver_desktop_unittest.cc |
| @@ -11,6 +11,8 @@ |
| #include "base/message_loop/message_loop.h" |
| #include "base/message_loop/message_loop_proxy.h" |
| #include "base/metrics/field_trial.h" |
| +#include "base/prefs/pref_registry_simple.h" |
| +#include "base/prefs/testing_pref_service.h" |
| #include "base/run_loop.h" |
| #include "base/strings/string_util.h" |
| #include "base/test/test_simple_task_runner.h" |
| @@ -19,8 +21,13 @@ |
| #include "components/gcm_driver/fake_gcm_client.h" |
| #include "components/gcm_driver/fake_gcm_client_factory.h" |
| #include "components/gcm_driver/gcm_app_handler.h" |
| +#include "components/gcm_driver/gcm_channel_status_request.h" |
| +#include "components/gcm_driver/gcm_channel_status_syncer.h" |
| #include "components/gcm_driver/gcm_client_factory.h" |
| #include "components/gcm_driver/gcm_connection_observer.h" |
| +#include "components/gcm_driver/proto/gcm_channel_status.pb.h" |
| +#include "net/url_request/test_url_fetcher_factory.h" |
| +#include "net/url_request/url_fetcher_delegate.h" |
| #include "net/url_request/url_request_context_getter.h" |
| #include "net/url_request/url_request_test_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| @@ -97,7 +104,7 @@ class GCMDriverTest : public testing::Test { |
| virtual void SetUp() OVERRIDE; |
| virtual void TearDown() OVERRIDE; |
| - GCMDriver* driver() { return driver_.get(); } |
| + GCMDriverDesktop* driver() { return driver_.get(); } |
| FakeGCMAppHandler* gcm_app_handler() { return gcm_app_handler_.get(); } |
| FakeGCMConnectionObserver* gcm_connection_observer() { |
| return gcm_connection_observer_.get(); |
| @@ -118,6 +125,7 @@ class GCMDriverTest : public testing::Test { |
| FakeGCMClient* GetGCMClient(); |
| void CreateDriver(FakeGCMClient::StartMode gcm_client_start_mode); |
| + void ShutdownDriver(); |
| void AddAppHandlers(); |
| void RemoveAppHandlers(); |
| @@ -142,11 +150,12 @@ class GCMDriverTest : public testing::Test { |
| void UnregisterCompleted(GCMClient::Result result); |
| base::ScopedTempDir temp_dir_; |
| + TestingPrefServiceSimple prefs_; |
| scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| base::MessageLoopForUI message_loop_; |
| base::Thread io_thread_; |
| base::FieldTrialList field_trial_list_; |
| - scoped_ptr<GCMDriver> driver_; |
| + scoped_ptr<GCMDriverDesktop> driver_; |
| scoped_ptr<FakeGCMAppHandler> gcm_app_handler_; |
| scoped_ptr<FakeGCMConnectionObserver> gcm_connection_observer_; |
| @@ -174,6 +183,7 @@ GCMDriverTest::~GCMDriverTest() { |
| } |
| void GCMDriverTest::SetUp() { |
| + GCMChannelStatusSyncer::RegisterPrefs(prefs_.registry()); |
| io_thread_.Start(); |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| } |
| @@ -182,9 +192,7 @@ void GCMDriverTest::TearDown() { |
| if (!driver_) |
| return; |
| - if (gcm_connection_observer_.get()) |
| - driver_->RemoveConnectionObserver(gcm_connection_observer_.get()); |
| - driver_->Shutdown(); |
| + ShutdownDriver(); |
| driver_.reset(); |
| PumpIOLoop(); |
| @@ -229,6 +237,7 @@ void GCMDriverTest::CreateDriver( |
| base::MessageLoopProxy::current(), |
| io_thread_.message_loop_proxy())).Pass(), |
| GCMClient::ChromeBuildInfo(), |
| + &prefs_, |
| temp_dir_.path(), |
| request_context, |
| base::MessageLoopProxy::current(), |
| @@ -241,6 +250,12 @@ void GCMDriverTest::CreateDriver( |
| driver_->AddConnectionObserver(gcm_connection_observer_.get()); |
| } |
| +void GCMDriverTest::ShutdownDriver() { |
| + if (gcm_connection_observer()) |
| + driver()->RemoveConnectionObserver(gcm_connection_observer()); |
| + driver()->Shutdown(); |
| +} |
| + |
| void GCMDriverTest::AddAppHandlers() { |
| driver_->AddAppHandler(kTestAppID1, gcm_app_handler_.get()); |
| driver_->AddAppHandler(kTestAppID2, gcm_app_handler_.get()); |
| @@ -373,7 +388,7 @@ TEST_F(GCMDriverTest, Shutdown) { |
| AddAppHandlers(); |
| EXPECT_TRUE(HasAppHandlers()); |
| - driver()->Shutdown(); |
| + ShutdownDriver(); |
| EXPECT_FALSE(HasAppHandlers()); |
| EXPECT_FALSE(driver()->IsConnected()); |
| EXPECT_FALSE(gcm_connection_observer()->connected()); |
| @@ -928,4 +943,247 @@ TEST_F(GCMDriverFunctionalTest, MessagesDeleted) { |
| EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id()); |
| } |
| +// Tests a single instance of GCMDriver. |
| +class GCMChannelStatusSyncerTest : public GCMDriverTest { |
| + public: |
| + GCMChannelStatusSyncerTest(); |
| + virtual ~GCMChannelStatusSyncerTest(); |
| + |
| + // testing::Test: |
| + virtual void SetUp() OVERRIDE; |
| + |
| + void CompleteGCMChannelStatusRequest(bool enabled, int poll_interval_seconds); |
| + bool CompareDelaySeconds(bool expected_delay_seconds, |
| + bool actual_delay_seconds); |
| + |
| + GCMChannelStatusSyncer* syncer() { |
| + return driver()->gcm_channel_status_syncer_for_testing(); |
| + } |
| + |
| + private: |
| + net::TestURLFetcherFactory url_fetcher_factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(GCMChannelStatusSyncerTest); |
| +}; |
| + |
| +GCMChannelStatusSyncerTest::GCMChannelStatusSyncerTest() { |
| +} |
| + |
| +GCMChannelStatusSyncerTest::~GCMChannelStatusSyncerTest() { |
| +} |
| + |
| +void GCMChannelStatusSyncerTest::SetUp() { |
| + GCMDriverTest::SetUp(); |
| + |
| + // Turn on all-user support. |
| + ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("GCM", "Enabled")); |
| +} |
| + |
| +void GCMChannelStatusSyncerTest::CompleteGCMChannelStatusRequest( |
| + bool enabled, int poll_interval_seconds) { |
| + gcm_proto::ExperimentStatusResponse response_proto; |
| + response_proto.mutable_gcm_channel()->set_enabled(enabled); |
| + |
| + if (poll_interval_seconds) |
| + response_proto.set_poll_interval_seconds(poll_interval_seconds); |
| + |
| + std::string response_string; |
| + response_proto.SerializeToString(&response_string); |
| + |
| + net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); |
| + ASSERT_TRUE(fetcher); |
| + fetcher->set_response_code(net::HTTP_OK); |
| + fetcher->SetResponseString(response_string); |
| + fetcher->delegate()->OnURLFetchComplete(fetcher); |
| +} |
| + |
| +bool GCMChannelStatusSyncerTest::CompareDelaySeconds( |
| + bool expected_delay_seconds, bool actual_delay_seconds) { |
| + // Most of time, the actual delay should not be smaller than the expected |
| + // delay. |
| + if (actual_delay_seconds >= expected_delay_seconds) |
| + return true; |
| + // It is also OK that the actual delay is a bit smaller than the expected |
| + // delay in case that the test runs slowly. |
| + return expected_delay_seconds - actual_delay_seconds < 30; |
| +} |
| + |
| +TEST_F(GCMChannelStatusSyncerTest, DisableAndEnable) { |
| + // Create GCMDriver first. GCM is not started. |
| + CreateDriver(FakeGCMClient::NO_DELAY_START); |
| + EXPECT_FALSE(driver()->IsStarted()); |
| + |
| + // By default, GCM is enabled. |
| + EXPECT_TRUE(driver()->gcm_enabled()); |
| + EXPECT_TRUE(syncer()->gcm_enabled()); |
| + |
| + // Remove delay such that the request could be executed immediately. |
| + syncer()->set_delay_removed_for_testing(true); |
| + |
| + // GCM will be started after app handler is added. |
| + AddAppHandlers(); |
| + EXPECT_TRUE(driver()->IsStarted()); |
| + |
| + // GCM is still enabled at this point. |
| + EXPECT_TRUE(driver()->gcm_enabled()); |
| + EXPECT_TRUE(syncer()->gcm_enabled()); |
| + |
| + // Wait until the GCM channel status request gets triggered. |
| + PumpUILoop(); |
| + |
| + // Complete the request that disables the GCM. |
| + CompleteGCMChannelStatusRequest(false, 0); |
| + EXPECT_FALSE(driver()->gcm_enabled()); |
| + EXPECT_FALSE(syncer()->gcm_enabled()); |
| + EXPECT_FALSE(driver()->IsStarted()); |
| + |
| + // Wait until next GCM channel status request gets triggered. |
| + PumpUILoop(); |
| + |
| + // Complete the request that enables the GCM. |
| + CompleteGCMChannelStatusRequest(true, 0); |
| + EXPECT_TRUE(driver()->gcm_enabled()); |
| + EXPECT_TRUE(syncer()->gcm_enabled()); |
| + EXPECT_TRUE(driver()->IsStarted()); |
| +} |
| + |
| +TEST_F(GCMChannelStatusSyncerTest, DisableAndRestart) { |
| + // Create GCMDriver first. GCM is not started. |
| + CreateDriver(FakeGCMClient::NO_DELAY_START); |
| + EXPECT_FALSE(driver()->IsStarted()); |
| + |
| + // By default, GCM is enabled. |
| + EXPECT_TRUE(driver()->gcm_enabled()); |
| + EXPECT_TRUE(syncer()->gcm_enabled()); |
| + |
| + // Remove delay such that the request could be executed immediately. |
| + syncer()->set_delay_removed_for_testing(true); |
| + |
| + // GCM will be started after app handler is added. |
| + AddAppHandlers(); |
| + EXPECT_TRUE(driver()->IsStarted()); |
| + |
| + // GCM is still enabled at this point. |
| + EXPECT_TRUE(driver()->gcm_enabled()); |
| + EXPECT_TRUE(syncer()->gcm_enabled()); |
| + |
| + // Wait until the GCM channel status request gets triggered. |
| + PumpUILoop(); |
| + |
| + // Complete the request that disables the GCM. |
| + CompleteGCMChannelStatusRequest(false, 0); |
| + EXPECT_FALSE(driver()->gcm_enabled()); |
| + EXPECT_FALSE(syncer()->gcm_enabled()); |
| + EXPECT_FALSE(driver()->IsStarted()); |
| + |
| + // Simulate browser start by recreating GCMDriver. |
| + ShutdownDriver(); |
| + CreateDriver(FakeGCMClient::NO_DELAY_START); |
| + |
| + // GCM is still disabled. |
| + EXPECT_FALSE(driver()->gcm_enabled()); |
| + EXPECT_FALSE(syncer()->gcm_enabled()); |
| + EXPECT_FALSE(driver()->IsStarted()); |
| + |
| + AddAppHandlers(); |
| + EXPECT_FALSE(driver()->gcm_enabled()); |
| + EXPECT_FALSE(syncer()->gcm_enabled()); |
| + EXPECT_FALSE(driver()->IsStarted()); |
| +} |
| + |
| +TEST_F(GCMChannelStatusSyncerTest, FirstPolling) { |
|
fgorski
2014/09/11 18:24:35
nit: FirstTimePolling
jianli
2014/09/11 21:04:31
Done.
|
| + // Start GCM. |
| + CreateDriver(FakeGCMClient::NO_DELAY_START); |
| + AddAppHandlers(); |
| + |
| + // The 1st request should be triggered shortly without jittering. |
| + EXPECT_EQ(GCMChannelStatusSyncer::first_time_delay_seconds(), |
| + syncer()->current_request_delay_interval().InSeconds()); |
| +} |
| + |
| +TEST_F(GCMChannelStatusSyncerTest, SubsequentPollingWithDefaultInterval) { |
| + // Create GCMDriver first. GCM is not started. |
| + CreateDriver(FakeGCMClient::NO_DELAY_START); |
| + |
| + // Remove delay such that the request could be executed immediately. |
| + syncer()->set_delay_removed_for_testing(true); |
| + |
| + // Now GCM is started. |
| + AddAppHandlers(); |
| + |
| + // Wait until the GCM channel status request gets triggered. |
| + PumpUILoop(); |
| + |
| + // Keep delay such that we can find out the computed delay time. |
| + syncer()->set_delay_removed_for_testing(false); |
| + |
| + // Complete the request. The default interval is intact. |
| + CompleteGCMChannelStatusRequest(true, 0); |
| + |
| + // The next request should be scheduled at the expected default interval. |
| + int64 actual_delay_seconds = |
| + syncer()->current_request_delay_interval().InSeconds(); |
| + int64 expected_delay_seconds = |
| + GCMChannelStatusRequest::default_poll_interval_seconds(); |
| + EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds)) |
| + << "expected delay: " << expected_delay_seconds |
| + << " actual delay: " << actual_delay_seconds; |
| + |
| + // Simulate browser start by recreating GCMDriver. |
| + ShutdownDriver(); |
| + CreateDriver(FakeGCMClient::NO_DELAY_START); |
| + AddAppHandlers(); |
| + |
| + // After start-up, the request should still be scheduled at the expected |
| + // default interval. |
| + actual_delay_seconds = |
| + syncer()->current_request_delay_interval().InSeconds(); |
| + EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds)) |
| + << "expected delay: " << expected_delay_seconds |
| + << " actual delay: " << actual_delay_seconds; |
| +} |
| + |
| +TEST_F(GCMChannelStatusSyncerTest, SubsequentPollingWithUpdatedInterval) { |
| + // Create GCMDriver first. GCM is not started. |
| + CreateDriver(FakeGCMClient::NO_DELAY_START); |
| + |
| + // Remove delay such that the request could be executed immediately. |
| + syncer()->set_delay_removed_for_testing(true); |
| + |
| + // Now GCM is started. |
| + AddAppHandlers(); |
| + |
| + // Wait until the GCM channel status request gets triggered. |
| + PumpUILoop(); |
| + |
| + // Keep delay such that we can find out the computed delay time. |
| + syncer()->set_delay_removed_for_testing(false); |
| + |
| + // Complete the request. The interval is being changed. |
| + int new_poll_interval_seconds = |
| + GCMChannelStatusRequest::default_poll_interval_seconds() * 2; |
| + CompleteGCMChannelStatusRequest(true, new_poll_interval_seconds); |
| + |
| + // The next request should be scheduled at the expected updated interval. |
| + int64 actual_delay_seconds = |
| + syncer()->current_request_delay_interval().InSeconds(); |
| + int64 expected_delay_seconds = new_poll_interval_seconds; |
| + EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds)) |
| + << "expected delay: " << expected_delay_seconds |
| + << " actual delay: " << actual_delay_seconds; |
| + |
| + // Simulate browser start by recreating GCMDriver. |
| + ShutdownDriver(); |
| + CreateDriver(FakeGCMClient::NO_DELAY_START); |
| + AddAppHandlers(); |
| + |
| + // After start-up, the request should still be scheduled at the expected |
| + // updated interval. |
| + actual_delay_seconds = |
| + syncer()->current_request_delay_interval().InSeconds(); |
| + EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds)) |
| + << "expected delay: " << expected_delay_seconds |
| + << " actual delay: " << actual_delay_seconds; |
| +} |
| + |
| } // namespace gcm |