Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: google_apis/gcm/gcm_client_impl_unittest.cc

Issue 215363007: [GCM] Adding basic G-services handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing Jian Li's CR comments. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "google_apis/gcm/gcm_client_impl.h" 5 #include "google_apis/gcm/gcm_client_impl.h"
6 6
7 #include "base/files/scoped_temp_dir.h" 7 #include "base/files/scoped_temp_dir.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/strings/string_number_conversions.h"
10 #include "base/test/simple_test_clock.h" 11 #include "base/test/simple_test_clock.h"
11 #include "components/os_crypt/os_crypt.h" 12 #include "components/os_crypt/os_crypt.h"
12 #include "google_apis/gcm/base/mcs_message.h" 13 #include "google_apis/gcm/base/mcs_message.h"
13 #include "google_apis/gcm/base/mcs_util.h" 14 #include "google_apis/gcm/base/mcs_util.h"
14 #include "google_apis/gcm/engine/fake_connection_factory.h" 15 #include "google_apis/gcm/engine/fake_connection_factory.h"
15 #include "google_apis/gcm/engine/fake_connection_handler.h" 16 #include "google_apis/gcm/engine/fake_connection_handler.h"
16 #include "google_apis/gcm/protocol/android_checkin.pb.h" 17 #include "google_apis/gcm/protocol/android_checkin.pb.h"
17 #include "google_apis/gcm/protocol/checkin.pb.h" 18 #include "google_apis/gcm/protocol/checkin.pb.h"
18 #include "google_apis/gcm/protocol/mcs.pb.h" 19 #include "google_apis/gcm/protocol/mcs.pb.h"
19 #include "net/url_request/test_url_fetcher_factory.h" 20 #include "net/url_request/test_url_fetcher_factory.h"
(...skipping 10 matching lines...) Expand all
30 LOADING_COMPLETED, 31 LOADING_COMPLETED,
31 REGISTRATION_COMPLETED, 32 REGISTRATION_COMPLETED,
32 UNREGISTRATION_COMPLETED, 33 UNREGISTRATION_COMPLETED,
33 MESSAGE_SEND_ERROR, 34 MESSAGE_SEND_ERROR,
34 MESSAGE_RECEIVED, 35 MESSAGE_RECEIVED,
35 MESSAGES_DELETED, 36 MESSAGES_DELETED,
36 }; 37 };
37 38
38 const uint64 kDeviceAndroidId = 54321; 39 const uint64 kDeviceAndroidId = 54321;
39 const uint64 kDeviceSecurityToken = 12345; 40 const uint64 kDeviceSecurityToken = 12345;
41 const int64 kSettingsCheckinInterval = 3600;
42 const char kSettingsDefaultDigest[] = "default_digest";
40 const char kAppId[] = "app_id"; 43 const char kAppId[] = "app_id";
41 const char kSender[] = "project_id"; 44 const char kSender[] = "project_id";
42 const char kSender2[] = "project_id2"; 45 const char kSender2[] = "project_id2";
43 const char kSender3[] = "project_id3"; 46 const char kSender3[] = "project_id3";
44 const char kRegistrationResponsePrefix[] = "token="; 47 const char kRegistrationResponsePrefix[] = "token=";
45 const char kUnregistrationResponsePrefix[] = "deleted="; 48 const char kUnregistrationResponsePrefix[] = "deleted=";
46 49
47 // Helper for building arbitrary data messages. 50 // Helper for building arbitrary data messages.
48 MCSMessage BuildDownstreamMessage( 51 MCSMessage BuildDownstreamMessage(
49 const std::string& project_id, 52 const std::string& project_id,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 } 151 }
149 152
150 scoped_ptr<ConnectionFactory> FakeGCMInternalsBuilder::BuildConnectionFactory( 153 scoped_ptr<ConnectionFactory> FakeGCMInternalsBuilder::BuildConnectionFactory(
151 const std::vector<GURL>& endpoints, 154 const std::vector<GURL>& endpoints,
152 const net::BackoffEntry::Policy& backoff_policy, 155 const net::BackoffEntry::Policy& backoff_policy,
153 scoped_refptr<net::HttpNetworkSession> network_session, 156 scoped_refptr<net::HttpNetworkSession> network_session,
154 net::NetLog* net_log) { 157 net::NetLog* net_log) {
155 return make_scoped_ptr<ConnectionFactory>(new FakeConnectionFactory()); 158 return make_scoped_ptr<ConnectionFactory>(new FakeConnectionFactory());
156 } 159 }
157 160
161 class CheckinGCMClientImpl : public GCMClientImpl {
162 public:
163 CheckinGCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder);
Nicolas Zea 2014/04/01 21:42:14 explicit
fgorski 2014/04/02 18:23:00 Done.
164 virtual ~CheckinGCMClientImpl();
165
166 virtual base::TimeDelta GetCheckinInterval() const OVERRIDE;
Nicolas Zea 2014/04/01 21:42:14 How important is it to override this? I think I'd
fgorski 2014/04/02 18:23:00 Done.
167 };
168
169 CheckinGCMClientImpl::CheckinGCMClientImpl(
170 scoped_ptr<GCMInternalsBuilder> internals_builder)
171 : GCMClientImpl(internals_builder.Pass()) {
172 }
173
174 CheckinGCMClientImpl::~CheckinGCMClientImpl() { }
175
176 base::TimeDelta CheckinGCMClientImpl::GetCheckinInterval() const {
177 return base::TimeDelta::FromMilliseconds(10);
178 }
179
158 } // namespace 180 } // namespace
159 181
160 class GCMClientImplTest : public testing::Test, 182 class GCMClientImplTest : public testing::Test,
161 public GCMClient::Delegate { 183 public GCMClient::Delegate {
162 public: 184 public:
163 GCMClientImplTest(); 185 GCMClientImplTest();
164 virtual ~GCMClientImplTest(); 186 virtual ~GCMClientImplTest();
165 187
166 virtual void SetUp() OVERRIDE; 188 virtual void SetUp() OVERRIDE;
167 189
168 void BuildGCMClient(); 190 void BuildGCMClient();
169 void InitializeGCMClient(); 191 void InitializeGCMClient();
170 void ReceiveMessageFromMCS(const MCSMessage& message); 192 void ReceiveMessageFromMCS(const MCSMessage& message);
171 void CompleteCheckin(uint64 android_id, uint64 security_token); 193 void CompleteCheckin(
194 uint64 android_id,
195 uint64 security_token,
196 const std::string& digest,
197 const std::map<std::string, std::string>& settings);
172 void CompleteRegistration(const std::string& registration_id); 198 void CompleteRegistration(const std::string& registration_id);
173 void CompleteUnregistration(const std::string& app_id); 199 void CompleteUnregistration(const std::string& app_id);
174 200
175 bool ExistsRegistration(const std::string& app_id) const; 201 bool ExistsRegistration(const std::string& app_id) const;
176 void AddRegistration(const std::string& app_id, 202 void AddRegistration(const std::string& app_id,
177 const std::vector<std::string>& sender_ids, 203 const std::vector<std::string>& sender_ids,
178 const std::string& registration_id); 204 const std::string& registration_id);
179 205
180 // GCMClient::Delegate overrides (for verification). 206 // GCMClient::Delegate overrides (for verification).
181 virtual void OnRegisterFinished(const std::string& app_id, 207 virtual void OnRegisterFinished(const std::string& app_id,
(...skipping 13 matching lines...) Expand all
195 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE; 221 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE;
196 virtual void OnGCMReady() OVERRIDE; 222 virtual void OnGCMReady() OVERRIDE;
197 223
198 GCMClientImpl* gcm_client() const { return gcm_client_.get(); } 224 GCMClientImpl* gcm_client() const { return gcm_client_.get(); }
199 FakeMCSClient* mcs_client() const { 225 FakeMCSClient* mcs_client() const {
200 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get()); 226 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get());
201 } 227 }
202 ConnectionFactory* connection_factory() const { 228 ConnectionFactory* connection_factory() const {
203 return gcm_client_->connection_factory_.get(); 229 return gcm_client_->connection_factory_.get();
204 } 230 }
231 GServicesSettingsMap& services_settings() {
232 return gcm_client_->gservices_settings_;
233 }
234 const std::string& services_digest() {
235 return gcm_client_->gservices_digest_;
236 }
205 237
206 void reset_last_event() { 238 void reset_last_event() {
207 last_event_ = NONE; 239 last_event_ = NONE;
208 last_app_id_.clear(); 240 last_app_id_.clear();
209 last_registration_id_.clear(); 241 last_registration_id_.clear();
210 last_message_id_.clear(); 242 last_message_id_.clear();
211 last_result_ = GCMClient::UNKNOWN_ERROR; 243 last_result_ = GCMClient::UNKNOWN_ERROR;
212 } 244 }
213 245
214 LastEvent last_event() const { return last_event_; } 246 LastEvent last_event() const { return last_event_; }
215 const std::string& last_app_id() const { return last_app_id_; } 247 const std::string& last_app_id() const { return last_app_id_; }
216 const std::string& last_registration_id() const { 248 const std::string& last_registration_id() const {
217 return last_registration_id_; 249 return last_registration_id_;
218 } 250 }
219 const std::string& last_message_id() const { return last_message_id_; } 251 const std::string& last_message_id() const { return last_message_id_; }
220 GCMClient::Result last_result() const { return last_result_; } 252 GCMClient::Result last_result() const { return last_result_; }
221 const GCMClient::IncomingMessage& last_message() const { 253 const GCMClient::IncomingMessage& last_message() const {
222 return last_message_; 254 return last_message_;
223 } 255 }
224 const GCMClient::SendErrorDetails& last_error_details() const { 256 const GCMClient::SendErrorDetails& last_error_details() const {
225 return last_error_details_; 257 return last_error_details_;
226 } 258 }
227 259
228 int64 CurrentTime(); 260 int64 CurrentTime();
229 261
230 private: 262 protected:
231 // Tooling. 263 // Tooling.
232 void PumpLoop(); 264 void PumpLoop();
233 void PumpLoopUntilIdle(); 265 void PumpLoopUntilIdle();
234 void QuitLoop(); 266 void QuitLoop();
267 void ResetLoop();
268
269 bool CreateUniqueTempDir();
235 270
236 base::SimpleTestClock* clock() const { 271 base::SimpleTestClock* clock() const {
237 return reinterpret_cast<base::SimpleTestClock*>(gcm_client_->clock_.get()); 272 return reinterpret_cast<base::SimpleTestClock*>(gcm_client_->clock_.get());
238 } 273 }
239 274
275 scoped_ptr<GCMClientImpl> gcm_client_;
Nicolas Zea 2014/04/01 21:42:14 this is already exposed via gcm_client(). Is is ne
fgorski 2014/04/02 18:23:00 Done.
276 private:
240 // Variables used for verification. 277 // Variables used for verification.
241 LastEvent last_event_; 278 LastEvent last_event_;
242 std::string last_app_id_; 279 std::string last_app_id_;
243 std::string last_registration_id_; 280 std::string last_registration_id_;
244 std::string last_message_id_; 281 std::string last_message_id_;
245 GCMClient::Result last_result_; 282 GCMClient::Result last_result_;
246 GCMClient::IncomingMessage last_message_; 283 GCMClient::IncomingMessage last_message_;
247 GCMClient::SendErrorDetails last_error_details_; 284 GCMClient::SendErrorDetails last_error_details_;
248 285
249 scoped_ptr<GCMClientImpl> gcm_client_;
250 286
251 base::MessageLoop message_loop_; 287 base::MessageLoop message_loop_;
252 scoped_ptr<base::RunLoop> run_loop_; 288 scoped_ptr<base::RunLoop> run_loop_;
253 net::TestURLFetcherFactory url_fetcher_factory_; 289 net::TestURLFetcherFactory url_fetcher_factory_;
254 290
255 // Injected to GCM client: 291 // Injected to GCM client:
256 base::ScopedTempDir temp_directory_; 292 base::ScopedTempDir temp_directory_;
257 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_; 293 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
258 }; 294 };
259 295
260 GCMClientImplTest::GCMClientImplTest() 296 GCMClientImplTest::GCMClientImplTest()
261 : last_event_(NONE), 297 : last_event_(NONE),
262 last_result_(GCMClient::UNKNOWN_ERROR), 298 last_result_(GCMClient::UNKNOWN_ERROR),
263 url_request_context_getter_(new net::TestURLRequestContextGetter( 299 url_request_context_getter_(new net::TestURLRequestContextGetter(
264 message_loop_.message_loop_proxy())) { 300 message_loop_.message_loop_proxy())) {
265 } 301 }
266 302
267 GCMClientImplTest::~GCMClientImplTest() {} 303 GCMClientImplTest::~GCMClientImplTest() {}
268 304
269 void GCMClientImplTest::SetUp() { 305 void GCMClientImplTest::SetUp() {
270 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); 306 ASSERT_TRUE(CreateUniqueTempDir());
271 run_loop_.reset(new base::RunLoop); 307 ResetLoop();
272 BuildGCMClient(); 308 BuildGCMClient();
273 InitializeGCMClient(); 309 InitializeGCMClient();
274 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken); 310 CompleteCheckin(kDeviceAndroidId,
311 kDeviceSecurityToken,
312 kSettingsDefaultDigest,
313 std::map<std::string, std::string>());
275 } 314 }
276 315
277 void GCMClientImplTest::PumpLoop() { 316 void GCMClientImplTest::PumpLoop() {
278 run_loop_->Run(); 317 run_loop_->Run();
279 run_loop_.reset(new base::RunLoop()); 318 run_loop_.reset(new base::RunLoop());
280 } 319 }
281 320
282 void GCMClientImplTest::PumpLoopUntilIdle() { 321 void GCMClientImplTest::PumpLoopUntilIdle() {
283 run_loop_->RunUntilIdle(); 322 run_loop_->RunUntilIdle();
284 run_loop_.reset(new base::RunLoop()); 323 run_loop_.reset(new base::RunLoop());
285 } 324 }
286 325
287 void GCMClientImplTest::QuitLoop() { 326 void GCMClientImplTest::QuitLoop() {
288 if (run_loop_ && run_loop_->running()) 327 if (run_loop_ && run_loop_->running())
289 run_loop_->Quit(); 328 run_loop_->Quit();
290 } 329 }
291 330
331 void GCMClientImplTest::ResetLoop() {
332 run_loop_.reset(new base::RunLoop);
333 }
334
335 bool GCMClientImplTest::CreateUniqueTempDir() {
336 return temp_directory_.CreateUniqueTempDir();
337 }
338
292 void GCMClientImplTest::BuildGCMClient() { 339 void GCMClientImplTest::BuildGCMClient() {
293 gcm_client_.reset(new GCMClientImpl( 340 gcm_client_.reset(new GCMClientImpl(
294 make_scoped_ptr<GCMInternalsBuilder>(new FakeGCMInternalsBuilder()))); 341 make_scoped_ptr<GCMInternalsBuilder>(new FakeGCMInternalsBuilder())));
295 } 342 }
296 343
297 void GCMClientImplTest::CompleteCheckin(uint64 android_id, 344 void GCMClientImplTest::CompleteCheckin(
298 uint64 security_token) { 345 uint64 android_id,
346 uint64 security_token,
347 const std::string& digest,
348 const std::map<std::string, std::string>& settings) {
299 checkin_proto::AndroidCheckinResponse response; 349 checkin_proto::AndroidCheckinResponse response;
300 response.set_stats_ok(true); 350 response.set_stats_ok(true);
301 response.set_android_id(android_id); 351 response.set_android_id(android_id);
302 response.set_security_token(security_token); 352 response.set_security_token(security_token);
303 353
354 // For testing GServices settings.
355 response.set_digest(digest);
356 for (std::map<std::string, std::string>::const_iterator it = settings.begin();
357 it != settings.end(); ++it) {
358 checkin_proto::GservicesSetting* setting = response.add_setting();
359 setting->set_name(it->first);
360 setting->set_value(it->second);
361 }
362
304 std::string response_string; 363 std::string response_string;
305 response.SerializeToString(&response_string); 364 response.SerializeToString(&response_string);
306 365
307 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 366 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
308 ASSERT_TRUE(fetcher); 367 ASSERT_TRUE(fetcher);
309 fetcher->set_response_code(net::HTTP_OK); 368 fetcher->set_response_code(net::HTTP_OK);
310 fetcher->SetResponseString(response_string); 369 fetcher->SetResponseString(response_string);
311 fetcher->delegate()->OnURLFetchComplete(fetcher); 370 fetcher->delegate()->OnURLFetchComplete(fetcher);
312 url_fetcher_factory_.RemoveFetcherFromMap(0); 371 url_fetcher_factory_.RemoveFetcherFromMap(0);
313 } 372 }
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl()); 647 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl());
589 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent()); 648 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent());
590 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id()); 649 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id());
591 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from()); 650 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from());
592 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to()); 651 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
593 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key()); 652 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key());
594 EXPECT_EQ("value", 653 EXPECT_EQ("value",
595 mcs_client()->last_data_message_stanza().app_data(0).value()); 654 mcs_client()->last_data_message_stanza().app_data(0).value());
596 } 655 }
597 656
657 class GCMClientImplCheckinTest : public GCMClientImplTest {
658 public:
659 GCMClientImplCheckinTest();
660 virtual ~GCMClientImplCheckinTest();
661
662 virtual void SetUp() OVERRIDE;
663
664 std::map<std::string, std::string> GenerateSettings(int64 checkin_interval);
Nicolas Zea 2014/04/01 21:42:14 you're always passing in kSettingsCheckinInterval
fgorski 2014/04/02 18:23:00 Done.
665 void BuildGCMClient();
666 };
667
668 GCMClientImplCheckinTest::GCMClientImplCheckinTest() {}
669
670 GCMClientImplCheckinTest::~GCMClientImplCheckinTest() {}
671
672 void GCMClientImplCheckinTest::SetUp() {
673 ASSERT_TRUE(CreateUniqueTempDir());
674 ResetLoop();
675 BuildGCMClient();
676 InitializeGCMClient();
677 }
678
679 std::map<std::string, std::string> GCMClientImplCheckinTest::GenerateSettings(
680 int64 checkin_interval) {
681 std::map<std::string, std::string> settings;
682 settings["checkin_interval"] = base::Int64ToString(checkin_interval);
Nicolas Zea 2014/04/01 21:42:14 nit: pull "checkin_interval" into a const and reus
fgorski 2014/04/02 18:23:00 Done.
683 return settings;
684 }
685
686 void GCMClientImplCheckinTest::BuildGCMClient() {
687 gcm_client_.reset(new CheckinGCMClientImpl(
688 make_scoped_ptr<GCMInternalsBuilder>(new FakeGCMInternalsBuilder())));
689 }
690
691 TEST_F(GCMClientImplCheckinTest, GServicesSettingsAfterInitialCheckin) {
692 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
693 kSettingsDefaultDigest, GenerateSettings(kSettingsCheckinInterval));
694 EXPECT_EQ(base::Int64ToString(kSettingsCheckinInterval),
695 services_settings()["checkin_interval"]);
696 }
697
698 // This test only checks that periodic checkin happens.
699 TEST_F(GCMClientImplCheckinTest, PeriodicCheckin) {
700 std::map<std::string, std::string> settings =
701 GenerateSettings(kSettingsCheckinInterval);
702 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
703 kSettingsDefaultDigest, settings);
704 PumpLoopUntilIdle();
705
706 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
707 kSettingsDefaultDigest, settings);
708 }
709
710 // This test checks that checkin can update GServices settings by diffing them.
711 TEST_F(GCMClientImplCheckinTest, GServicesSettingsSameDigest) {
712 std::map<std::string, std::string> settings =
713 GenerateSettings(kSettingsCheckinInterval);
714 settings["checkin_url"] = "http://checkin.google.com";
715 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
716 kSettingsDefaultDigest, settings);
717 EXPECT_EQ(settings, services_settings());
718 PumpLoopUntilIdle();
719
720 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
721 kSettingsDefaultDigest, settings);
722 EXPECT_EQ(settings, services_settings());
723 }
724
725 // Test that checkin can make full replacement of GServices settings.
726 TEST_F(GCMClientImplCheckinTest, GServicesSettingsFullUpdate) {
727 std::map<std::string, std::string> settings =
728 GenerateSettings(kSettingsCheckinInterval);
729 settings["checkin_url"] = "http://checkin.google.com";
730 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
731 kSettingsDefaultDigest, settings);
732 EXPECT_EQ(settings, services_settings());
733 EXPECT_EQ(kSettingsDefaultDigest, services_digest());
734 PumpLoopUntilIdle();
735
736 settings.clear();
737 settings["some_settings"] = "on second checkin";
738 settings["checkin_interval"] = "2100";
739 settings["checkin_url"] = "http://checkin.google.com";
740 std::string new_digest = "some_other_digest";
741
742 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, new_digest, settings);
743 EXPECT_EQ(settings, services_settings());
744 EXPECT_EQ(new_digest, services_digest());
745 }
746
598 } // namespace gcm 747 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698