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

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: Adding unit tests and addressing CR feedback 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;
40 const char kAppId[] = "app_id"; 42 const char kAppId[] = "app_id";
41 const char kSender[] = "project_id"; 43 const char kSender[] = "project_id";
42 const char kSender2[] = "project_id2"; 44 const char kSender2[] = "project_id2";
43 const char kSender3[] = "project_id3"; 45 const char kSender3[] = "project_id3";
44 const char kRegistrationResponsePrefix[] = "token="; 46 const char kRegistrationResponsePrefix[] = "token=";
45 const char kUnregistrationResponsePrefix[] = "deleted="; 47 const char kUnregistrationResponsePrefix[] = "deleted=";
46 48
47 // Helper for building arbitrary data messages. 49 // Helper for building arbitrary data messages.
48 MCSMessage BuildDownstreamMessage( 50 MCSMessage BuildDownstreamMessage(
49 const std::string& project_id, 51 const std::string& project_id,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 } 150 }
149 151
150 scoped_ptr<ConnectionFactory> FakeGCMInternalsBuilder::BuildConnectionFactory( 152 scoped_ptr<ConnectionFactory> FakeGCMInternalsBuilder::BuildConnectionFactory(
151 const std::vector<GURL>& endpoints, 153 const std::vector<GURL>& endpoints,
152 const net::BackoffEntry::Policy& backoff_policy, 154 const net::BackoffEntry::Policy& backoff_policy,
153 scoped_refptr<net::HttpNetworkSession> network_session, 155 scoped_refptr<net::HttpNetworkSession> network_session,
154 net::NetLog* net_log) { 156 net::NetLog* net_log) {
155 return make_scoped_ptr<ConnectionFactory>(new FakeConnectionFactory()); 157 return make_scoped_ptr<ConnectionFactory>(new FakeConnectionFactory());
156 } 158 }
157 159
160 class CheckinGCMClientImpl : public GCMClientImpl {
161 public:
162 CheckinGCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder);
163 virtual ~CheckinGCMClientImpl();
164
165 virtual base::TimeDelta GetCheckinInterval() OVERRIDE;
166 };
167
168 CheckinGCMClientImpl::CheckinGCMClientImpl(
169 scoped_ptr<GCMInternalsBuilder> internals_builder)
170 : GCMClientImpl(internals_builder.Pass()) {
171 }
172
173 CheckinGCMClientImpl::~CheckinGCMClientImpl() { }
174
175 base::TimeDelta CheckinGCMClientImpl::GetCheckinInterval() {
176 return base::TimeDelta::FromMilliseconds(10);
177 }
178
158 } // namespace 179 } // namespace
159 180
160 class GCMClientImplTest : public testing::Test, 181 class GCMClientImplTest : public testing::Test,
161 public GCMClient::Delegate { 182 public GCMClient::Delegate {
162 public: 183 public:
163 GCMClientImplTest(); 184 GCMClientImplTest();
164 virtual ~GCMClientImplTest(); 185 virtual ~GCMClientImplTest();
165 186
166 virtual void SetUp() OVERRIDE; 187 virtual void SetUp() OVERRIDE;
167 188
168 void BuildGCMClient(); 189 void BuildGCMClient();
169 void InitializeGCMClient(); 190 void InitializeGCMClient();
170 void ReceiveMessageFromMCS(const MCSMessage& message); 191 void ReceiveMessageFromMCS(const MCSMessage& message);
171 void CompleteCheckin(uint64 android_id, uint64 security_token); 192 void CompleteCheckin(
193 uint64 android_id,
194 uint64 security_token,
195 const std::map<std::string, std::string>& settings);
172 void CompleteRegistration(const std::string& registration_id); 196 void CompleteRegistration(const std::string& registration_id);
173 void CompleteUnregistration(const std::string& app_id); 197 void CompleteUnregistration(const std::string& app_id);
174 198
175 bool ExistsRegistration(const std::string& app_id) const; 199 bool ExistsRegistration(const std::string& app_id) const;
176 void AddRegistration(const std::string& app_id, 200 void AddRegistration(const std::string& app_id,
177 const std::vector<std::string>& sender_ids, 201 const std::vector<std::string>& sender_ids,
178 const std::string& registration_id); 202 const std::string& registration_id);
179 203
180 // GCMClient::Delegate overrides (for verification). 204 // GCMClient::Delegate overrides (for verification).
181 virtual void OnRegisterFinished(const std::string& app_id, 205 virtual void OnRegisterFinished(const std::string& app_id,
(...skipping 13 matching lines...) Expand all
195 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE; 219 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE;
196 virtual void OnGCMReady() OVERRIDE; 220 virtual void OnGCMReady() OVERRIDE;
197 221
198 GCMClientImpl* gcm_client() const { return gcm_client_.get(); } 222 GCMClientImpl* gcm_client() const { return gcm_client_.get(); }
199 FakeMCSClient* mcs_client() const { 223 FakeMCSClient* mcs_client() const {
200 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get()); 224 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get());
201 } 225 }
202 ConnectionFactory* connection_factory() const { 226 ConnectionFactory* connection_factory() const {
203 return gcm_client_->connection_factory_.get(); 227 return gcm_client_->connection_factory_.get();
204 } 228 }
229 GServicesSettingsMap& services_settings() {
230 return gcm_client_->gservices_settings_;
231 }
205 232
206 void reset_last_event() { 233 void reset_last_event() {
207 last_event_ = NONE; 234 last_event_ = NONE;
208 last_app_id_.clear(); 235 last_app_id_.clear();
209 last_registration_id_.clear(); 236 last_registration_id_.clear();
210 last_message_id_.clear(); 237 last_message_id_.clear();
211 last_result_ = GCMClient::UNKNOWN_ERROR; 238 last_result_ = GCMClient::UNKNOWN_ERROR;
212 } 239 }
213 240
214 LastEvent last_event() const { return last_event_; } 241 LastEvent last_event() const { return last_event_; }
215 const std::string& last_app_id() const { return last_app_id_; } 242 const std::string& last_app_id() const { return last_app_id_; }
216 const std::string& last_registration_id() const { 243 const std::string& last_registration_id() const {
217 return last_registration_id_; 244 return last_registration_id_;
218 } 245 }
219 const std::string& last_message_id() const { return last_message_id_; } 246 const std::string& last_message_id() const { return last_message_id_; }
220 GCMClient::Result last_result() const { return last_result_; } 247 GCMClient::Result last_result() const { return last_result_; }
221 const GCMClient::IncomingMessage& last_message() const { 248 const GCMClient::IncomingMessage& last_message() const {
222 return last_message_; 249 return last_message_;
223 } 250 }
224 const GCMClient::SendErrorDetails& last_error_details() const { 251 const GCMClient::SendErrorDetails& last_error_details() const {
225 return last_error_details_; 252 return last_error_details_;
226 } 253 }
227 254
228 int64 CurrentTime(); 255 int64 CurrentTime();
229 256
230 private: 257 protected:
231 // Tooling. 258 // Tooling.
232 void PumpLoop(); 259 void PumpLoop();
233 void PumpLoopUntilIdle(); 260 void PumpLoopUntilIdle();
234 void QuitLoop(); 261 void QuitLoop();
262 void ResetLoop();
263
264 bool CreateUniqueTempDir();
235 265
236 base::SimpleTestClock* clock() const { 266 base::SimpleTestClock* clock() const {
237 return reinterpret_cast<base::SimpleTestClock*>(gcm_client_->clock_.get()); 267 return reinterpret_cast<base::SimpleTestClock*>(gcm_client_->clock_.get());
238 } 268 }
239 269
270 scoped_ptr<GCMClientImpl> gcm_client_;
271 private:
240 // Variables used for verification. 272 // Variables used for verification.
241 LastEvent last_event_; 273 LastEvent last_event_;
242 std::string last_app_id_; 274 std::string last_app_id_;
243 std::string last_registration_id_; 275 std::string last_registration_id_;
244 std::string last_message_id_; 276 std::string last_message_id_;
245 GCMClient::Result last_result_; 277 GCMClient::Result last_result_;
246 GCMClient::IncomingMessage last_message_; 278 GCMClient::IncomingMessage last_message_;
247 GCMClient::SendErrorDetails last_error_details_; 279 GCMClient::SendErrorDetails last_error_details_;
248 280
249 scoped_ptr<GCMClientImpl> gcm_client_;
250 281
251 base::MessageLoop message_loop_; 282 base::MessageLoop message_loop_;
252 scoped_ptr<base::RunLoop> run_loop_; 283 scoped_ptr<base::RunLoop> run_loop_;
253 net::TestURLFetcherFactory url_fetcher_factory_; 284 net::TestURLFetcherFactory url_fetcher_factory_;
254 285
255 // Injected to GCM client: 286 // Injected to GCM client:
256 base::ScopedTempDir temp_directory_; 287 base::ScopedTempDir temp_directory_;
257 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_; 288 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
258 }; 289 };
259 290
260 GCMClientImplTest::GCMClientImplTest() 291 GCMClientImplTest::GCMClientImplTest()
261 : last_event_(NONE), 292 : last_event_(NONE),
262 last_result_(GCMClient::UNKNOWN_ERROR), 293 last_result_(GCMClient::UNKNOWN_ERROR),
263 url_request_context_getter_(new net::TestURLRequestContextGetter( 294 url_request_context_getter_(new net::TestURLRequestContextGetter(
264 message_loop_.message_loop_proxy())) { 295 message_loop_.message_loop_proxy())) {
265 } 296 }
266 297
267 GCMClientImplTest::~GCMClientImplTest() {} 298 GCMClientImplTest::~GCMClientImplTest() {}
268 299
269 void GCMClientImplTest::SetUp() { 300 void GCMClientImplTest::SetUp() {
270 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); 301 ASSERT_TRUE(CreateUniqueTempDir());
271 run_loop_.reset(new base::RunLoop); 302 ResetLoop();
272 BuildGCMClient(); 303 BuildGCMClient();
273 InitializeGCMClient(); 304 InitializeGCMClient();
274 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken); 305 CompleteCheckin(kDeviceAndroidId,
306 kDeviceSecurityToken,
307 std::map<std::string, std::string>());
275 } 308 }
276 309
277 void GCMClientImplTest::PumpLoop() { 310 void GCMClientImplTest::PumpLoop() {
278 run_loop_->Run(); 311 run_loop_->Run();
279 run_loop_.reset(new base::RunLoop()); 312 run_loop_.reset(new base::RunLoop());
280 } 313 }
281 314
282 void GCMClientImplTest::PumpLoopUntilIdle() { 315 void GCMClientImplTest::PumpLoopUntilIdle() {
283 run_loop_->RunUntilIdle(); 316 run_loop_->RunUntilIdle();
284 run_loop_.reset(new base::RunLoop()); 317 run_loop_.reset(new base::RunLoop());
285 } 318 }
286 319
287 void GCMClientImplTest::QuitLoop() { 320 void GCMClientImplTest::QuitLoop() {
288 if (run_loop_ && run_loop_->running()) 321 if (run_loop_ && run_loop_->running())
289 run_loop_->Quit(); 322 run_loop_->Quit();
290 } 323 }
291 324
325 void GCMClientImplTest::ResetLoop() {
326 run_loop_.reset(new base::RunLoop);
327 }
328
329 bool GCMClientImplTest::CreateUniqueTempDir() {
330 return temp_directory_.CreateUniqueTempDir();
331 }
332
292 void GCMClientImplTest::BuildGCMClient() { 333 void GCMClientImplTest::BuildGCMClient() {
293 gcm_client_.reset(new GCMClientImpl( 334 gcm_client_.reset(new GCMClientImpl(
294 make_scoped_ptr<GCMInternalsBuilder>(new FakeGCMInternalsBuilder()))); 335 make_scoped_ptr<GCMInternalsBuilder>(new FakeGCMInternalsBuilder())));
295 } 336 }
296 337
297 void GCMClientImplTest::CompleteCheckin(uint64 android_id, 338 void GCMClientImplTest::CompleteCheckin(
298 uint64 security_token) { 339 uint64 android_id,
340 uint64 security_token,
341 const std::map<std::string, std::string>& settings) {
299 checkin_proto::AndroidCheckinResponse response; 342 checkin_proto::AndroidCheckinResponse response;
300 response.set_stats_ok(true); 343 response.set_stats_ok(true);
301 response.set_android_id(android_id); 344 response.set_android_id(android_id);
302 response.set_security_token(security_token); 345 response.set_security_token(security_token);
303 346
347 std::map<std::string, std::string>::const_iterator it = settings.find("diff");
348 response.set_settings_diff(it != settings.end());
349
350 for (it = settings.begin(); it != settings.end(); ++it) {
351 if (it->first == "diff")
352 continue;
353 checkin_proto::GservicesSetting* setting = response.add_setting();
354 setting->set_name(it->first);
355 setting->set_value(it->second);
356 }
357
304 std::string response_string; 358 std::string response_string;
305 response.SerializeToString(&response_string); 359 response.SerializeToString(&response_string);
306 360
307 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 361 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
308 ASSERT_TRUE(fetcher); 362 ASSERT_TRUE(fetcher);
309 fetcher->set_response_code(net::HTTP_OK); 363 fetcher->set_response_code(net::HTTP_OK);
310 fetcher->SetResponseString(response_string); 364 fetcher->SetResponseString(response_string);
311 fetcher->delegate()->OnURLFetchComplete(fetcher); 365 fetcher->delegate()->OnURLFetchComplete(fetcher);
312 url_fetcher_factory_.RemoveFetcherFromMap(0); 366 url_fetcher_factory_.RemoveFetcherFromMap(0);
313 } 367 }
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl()); 642 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl());
589 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent()); 643 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent());
590 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id()); 644 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id());
591 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from()); 645 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from());
592 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to()); 646 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
593 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key()); 647 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key());
594 EXPECT_EQ("value", 648 EXPECT_EQ("value",
595 mcs_client()->last_data_message_stanza().app_data(0).value()); 649 mcs_client()->last_data_message_stanza().app_data(0).value());
596 } 650 }
597 651
652 class GCMClientImplCheckinTest : public GCMClientImplTest {
653 public:
654 GCMClientImplCheckinTest();
655 virtual ~GCMClientImplCheckinTest();
656
657 virtual void SetUp() OVERRIDE;
658
659 std::map<std::string, std::string> GenerateSettings(int64 checkin_interval);
660 void BuildGCMClient();
661 };
662
663 GCMClientImplCheckinTest::GCMClientImplCheckinTest() {}
664
665 GCMClientImplCheckinTest::~GCMClientImplCheckinTest() {}
666
667 void GCMClientImplCheckinTest::SetUp() {
668 ASSERT_TRUE(CreateUniqueTempDir());
669 ResetLoop();
670 BuildGCMClient();
671 InitializeGCMClient();
672 }
673
674 std::map<std::string, std::string> GCMClientImplCheckinTest::GenerateSettings(
675 int64 checkin_interval) {
676 std::map<std::string, std::string> settings;
677 settings["checkin_interval"] = base::Int64ToString(checkin_interval);
678 return settings;
679 }
680
681 void GCMClientImplCheckinTest::BuildGCMClient() {
682 gcm_client_.reset(new CheckinGCMClientImpl(
683 make_scoped_ptr<GCMInternalsBuilder>(new FakeGCMInternalsBuilder())));
684 }
685
686 TEST_F(GCMClientImplCheckinTest, GServicesSettingsAfterInitialCheckin) {
687 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
688 GenerateSettings(kSettingsCheckinInterval));
689 EXPECT_EQ(base::Int64ToString(kSettingsCheckinInterval),
690 services_settings()["checkin_interval"]);
691 }
692
693 // This test only checks that periodic checkin happens.
694 TEST_F(GCMClientImplCheckinTest, PeriodicCheckin) {
695 std::map<std::string, std::string> settings =
696 GenerateSettings(kSettingsCheckinInterval);
697 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, settings);
698 PumpLoopUntilIdle();
699
700 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, settings);
701 }
702
703 // This test checks that checkin can update GServices settings by diffing them.
704 TEST_F(GCMClientImplCheckinTest, GServicesSettingsDiff) {
705 std::map<std::string, std::string> settings =
706 GenerateSettings(kSettingsCheckinInterval);
707 settings["to_be"] = "removed";
708 settings["checkin_url"] = "http://checkin.google.com";
709 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, settings);
710 EXPECT_EQ(base::Int64ToString(kSettingsCheckinInterval),
711 services_settings()["checkin_interval"]);
712 EXPECT_EQ("http://checkin.google.com", services_settings()["checkin_url"]);
713 EXPECT_EQ("removed", services_settings()["to_be"]);
714 EXPECT_EQ(3U, services_settings().size());
715 PumpLoopUntilIdle();
716
717 settings.clear();
718 settings["diff"] = "";
719 settings["checkin_interval"] = "2100";
720 settings["delete_to_be"] = "";
721 settings["added"] = "on second checkin";
722 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, settings);
723 EXPECT_EQ("2100", services_settings()["checkin_interval"]);
724 // this one left untouched
725 EXPECT_EQ("http://checkin.google.com", services_settings()["checkin_url"]);
726 // this one added just now
727 EXPECT_EQ("on second checkin", services_settings()["added"]);
728 EXPECT_EQ(3U, services_settings().size());
729 }
730
731 // Test that checkin can make full replacement of GServices settings.
732 TEST_F(GCMClientImplCheckinTest, GServicesSettingsFullUpdate) {
733 std::map<std::string, std::string> settings =
734 GenerateSettings(kSettingsCheckinInterval);
735 settings["to_be"] = "removed";
736 settings["checkin_url"] = "http://checkin.google.com";
737 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, settings);
738 EXPECT_EQ(base::Int64ToString(kSettingsCheckinInterval),
739 services_settings()["checkin_interval"]);
740 EXPECT_EQ("http://checkin.google.com", services_settings()["checkin_url"]);
741 EXPECT_EQ("removed", services_settings()["to_be"]);
742 EXPECT_EQ(3U, services_settings().size());
743 PumpLoopUntilIdle();
744
745 settings.clear();
746 settings["added"] = "on second checkin";
747 settings["checkin_interval"] = "2100";
748 settings["checkin_url"] = "http://checkin.google.com";
749 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, settings);
750 EXPECT_EQ("2100", services_settings()["checkin_interval"]);
751 EXPECT_EQ("http://checkin.google.com", services_settings()["checkin_url"]);
752 EXPECT_EQ("on second checkin", services_settings()["added"]);
753 EXPECT_EQ(3U, services_settings().size());
754 }
755
598 } // namespace gcm 756 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698