Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / google_apis / gcm / engine / gcm_store_impl_unittest.cc
blobbbe408f40d62d562e9e69ab17a44497ee578d53c
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
3 // found in the LICENSE file.
5 #include "google_apis/gcm/engine/gcm_store_impl.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "google_apis/gcm/base/fake_encryptor.h"
19 #include "google_apis/gcm/base/mcs_message.h"
20 #include "google_apis/gcm/base/mcs_util.h"
21 #include "google_apis/gcm/protocol/mcs.pb.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 namespace gcm {
26 namespace {
28 // Number of persistent ids to use in tests.
29 const int kNumPersistentIds = 10;
31 // Number of per-app messages in tests.
32 const int kNumMessagesPerApp = 20;
34 // App name for testing.
35 const char kAppName[] = "my_app";
37 // Category name for testing.
38 const char kCategoryName[] = "my_category";
40 const uint64 kDeviceId = 22;
41 const uint64 kDeviceToken = 55;
43 class GCMStoreImplTest : public testing::Test {
44 public:
45 GCMStoreImplTest();
46 virtual ~GCMStoreImplTest();
48 scoped_ptr<GCMStore> BuildGCMStore();
50 std::string GetNextPersistentId();
52 void PumpLoop();
54 void LoadCallback(scoped_ptr<GCMStore::LoadResult>* result_dst,
55 scoped_ptr<GCMStore::LoadResult> result);
56 void UpdateCallback(bool success);
58 protected:
59 base::MessageLoop message_loop_;
60 base::ScopedTempDir temp_directory_;
61 bool expected_success_;
62 uint64 next_persistent_id_;
63 scoped_ptr<base::RunLoop> run_loop_;
66 GCMStoreImplTest::GCMStoreImplTest()
67 : expected_success_(true),
68 next_persistent_id_(base::Time::Now().ToInternalValue()) {
69 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir());
70 run_loop_.reset(new base::RunLoop());
73 GCMStoreImplTest::~GCMStoreImplTest() {}
75 scoped_ptr<GCMStore> GCMStoreImplTest::BuildGCMStore() {
76 return scoped_ptr<GCMStore>(new GCMStoreImpl(
77 temp_directory_.path(),
78 message_loop_.message_loop_proxy(),
79 make_scoped_ptr<Encryptor>(new FakeEncryptor)));
82 std::string GCMStoreImplTest::GetNextPersistentId() {
83 return base::Uint64ToString(next_persistent_id_++);
86 void GCMStoreImplTest::PumpLoop() { message_loop_.RunUntilIdle(); }
88 void GCMStoreImplTest::LoadCallback(
89 scoped_ptr<GCMStore::LoadResult>* result_dst,
90 scoped_ptr<GCMStore::LoadResult> result) {
91 ASSERT_TRUE(result->success);
92 *result_dst = result.Pass();
93 run_loop_->Quit();
94 run_loop_.reset(new base::RunLoop());
97 void GCMStoreImplTest::UpdateCallback(bool success) {
98 ASSERT_EQ(expected_success_, success);
101 // Verify creating a new database and loading it.
102 TEST_F(GCMStoreImplTest, LoadNew) {
103 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
104 scoped_ptr<GCMStore::LoadResult> load_result;
105 gcm_store->Load(base::Bind(
106 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
107 PumpLoop();
109 EXPECT_EQ(0U, load_result->device_android_id);
110 EXPECT_EQ(0U, load_result->device_security_token);
111 EXPECT_TRUE(load_result->incoming_messages.empty());
112 EXPECT_TRUE(load_result->outgoing_messages.empty());
113 EXPECT_TRUE(load_result->gservices_settings.empty());
114 EXPECT_EQ(base::Time::FromInternalValue(0LL), load_result->last_checkin_time);
117 TEST_F(GCMStoreImplTest, DeviceCredentials) {
118 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
119 scoped_ptr<GCMStore::LoadResult> load_result;
120 gcm_store->Load(base::Bind(
121 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
122 PumpLoop();
124 gcm_store->SetDeviceCredentials(
125 kDeviceId,
126 kDeviceToken,
127 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
128 PumpLoop();
130 gcm_store = BuildGCMStore().Pass();
131 gcm_store->Load(base::Bind(
132 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
133 PumpLoop();
135 ASSERT_EQ(kDeviceId, load_result->device_android_id);
136 ASSERT_EQ(kDeviceToken, load_result->device_security_token);
139 TEST_F(GCMStoreImplTest, LastCheckinInfo) {
140 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
141 scoped_ptr<GCMStore::LoadResult> load_result;
142 gcm_store->Load(base::Bind(
143 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
144 PumpLoop();
146 base::Time last_checkin_time = base::Time::Now();
147 std::set<std::string> accounts;
148 accounts.insert("test_user1@gmail.com");
149 accounts.insert("test_user2@gmail.com");
151 gcm_store->SetLastCheckinInfo(
152 last_checkin_time,
153 accounts,
154 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
155 PumpLoop();
157 gcm_store = BuildGCMStore().Pass();
158 gcm_store->Load(base::Bind(
159 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
160 PumpLoop();
161 ASSERT_EQ(last_checkin_time, load_result->last_checkin_time);
162 ASSERT_EQ(accounts, load_result->last_checkin_accounts);
165 TEST_F(GCMStoreImplTest, GServicesSettings_ProtocolV2) {
166 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
167 scoped_ptr<GCMStore::LoadResult> load_result;
168 gcm_store->Load(base::Bind(
169 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
170 PumpLoop();
172 std::map<std::string, std::string> settings;
173 settings["checkin_interval"] = "12345";
174 settings["mcs_port"] = "438";
175 settings["checkin_url"] = "http://checkin.google.com";
176 std::string digest = "digest1";
178 gcm_store->SetGServicesSettings(
179 settings,
180 digest,
181 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
182 PumpLoop();
184 gcm_store = BuildGCMStore().Pass();
185 gcm_store->Load(base::Bind(
186 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
187 PumpLoop();
189 ASSERT_EQ(settings, load_result->gservices_settings);
190 ASSERT_EQ(digest, load_result->gservices_digest);
192 // Remove some, and add some.
193 settings.clear();
194 settings["checkin_interval"] = "54321";
195 settings["registration_url"] = "http://registration.google.com";
196 digest = "digest2";
198 gcm_store->SetGServicesSettings(
199 settings,
200 digest,
201 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
202 PumpLoop();
204 gcm_store = BuildGCMStore().Pass();
205 gcm_store->Load(base::Bind(
206 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
207 PumpLoop();
209 ASSERT_EQ(settings, load_result->gservices_settings);
210 ASSERT_EQ(digest, load_result->gservices_digest);
213 TEST_F(GCMStoreImplTest, Registrations) {
214 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
215 scoped_ptr<GCMStore::LoadResult> load_result;
216 gcm_store->Load(base::Bind(
217 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
218 PumpLoop();
220 // Add one registration with one sender.
221 linked_ptr<RegistrationInfo> registration1(new RegistrationInfo);
222 registration1->sender_ids.push_back("sender1");
223 registration1->registration_id = "registration1";
224 gcm_store->AddRegistration(
225 "app1",
226 registration1,
227 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
228 PumpLoop();
230 // Add one registration with multiple senders.
231 linked_ptr<RegistrationInfo> registration2(new RegistrationInfo);
232 registration2->sender_ids.push_back("sender2_1");
233 registration2->sender_ids.push_back("sender2_2");
234 registration2->registration_id = "registration2";
235 gcm_store->AddRegistration(
236 "app2",
237 registration2,
238 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
239 PumpLoop();
241 gcm_store = BuildGCMStore().Pass();
242 gcm_store->Load(base::Bind(
243 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
244 PumpLoop();
246 ASSERT_EQ(2u, load_result->registrations.size());
247 ASSERT_TRUE(load_result->registrations.find("app1") !=
248 load_result->registrations.end());
249 EXPECT_EQ(registration1->registration_id,
250 load_result->registrations["app1"]->registration_id);
251 ASSERT_EQ(1u, load_result->registrations["app1"]->sender_ids.size());
252 EXPECT_EQ(registration1->sender_ids[0],
253 load_result->registrations["app1"]->sender_ids[0]);
254 ASSERT_TRUE(load_result->registrations.find("app2") !=
255 load_result->registrations.end());
256 EXPECT_EQ(registration2->registration_id,
257 load_result->registrations["app2"]->registration_id);
258 ASSERT_EQ(2u, load_result->registrations["app2"]->sender_ids.size());
259 EXPECT_EQ(registration2->sender_ids[0],
260 load_result->registrations["app2"]->sender_ids[0]);
261 EXPECT_EQ(registration2->sender_ids[1],
262 load_result->registrations["app2"]->sender_ids[1]);
264 gcm_store->RemoveRegistration(
265 "app2",
266 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
267 PumpLoop();
269 gcm_store = BuildGCMStore().Pass();
270 gcm_store->Load(base::Bind(
271 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
272 PumpLoop();
274 ASSERT_EQ(1u, load_result->registrations.size());
275 ASSERT_TRUE(load_result->registrations.find("app1") !=
276 load_result->registrations.end());
277 EXPECT_EQ(registration1->registration_id,
278 load_result->registrations["app1"]->registration_id);
279 ASSERT_EQ(1u, load_result->registrations["app1"]->sender_ids.size());
280 EXPECT_EQ(registration1->sender_ids[0],
281 load_result->registrations["app1"]->sender_ids[0]);
284 // Verify saving some incoming messages, reopening the directory, and then
285 // removing those incoming messages.
286 TEST_F(GCMStoreImplTest, IncomingMessages) {
287 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
288 scoped_ptr<GCMStore::LoadResult> load_result;
289 gcm_store->Load(base::Bind(
290 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
291 PumpLoop();
293 std::vector<std::string> persistent_ids;
294 for (int i = 0; i < kNumPersistentIds; ++i) {
295 persistent_ids.push_back(GetNextPersistentId());
296 gcm_store->AddIncomingMessage(
297 persistent_ids.back(),
298 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
299 PumpLoop();
302 gcm_store = BuildGCMStore().Pass();
303 gcm_store->Load(base::Bind(
304 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
305 PumpLoop();
307 ASSERT_EQ(persistent_ids, load_result->incoming_messages);
308 ASSERT_TRUE(load_result->outgoing_messages.empty());
310 gcm_store->RemoveIncomingMessages(
311 persistent_ids,
312 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
313 PumpLoop();
315 gcm_store = BuildGCMStore().Pass();
316 load_result->incoming_messages.clear();
317 gcm_store->Load(base::Bind(
318 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
319 PumpLoop();
321 ASSERT_TRUE(load_result->incoming_messages.empty());
322 ASSERT_TRUE(load_result->outgoing_messages.empty());
325 // Verify saving some outgoing messages, reopening the directory, and then
326 // removing those outgoing messages.
327 TEST_F(GCMStoreImplTest, OutgoingMessages) {
328 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
329 scoped_ptr<GCMStore::LoadResult> load_result;
330 gcm_store->Load(base::Bind(
331 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
332 PumpLoop();
334 std::vector<std::string> persistent_ids;
335 const int kNumPersistentIds = 10;
336 for (int i = 0; i < kNumPersistentIds; ++i) {
337 persistent_ids.push_back(GetNextPersistentId());
338 mcs_proto::DataMessageStanza message;
339 message.set_from(kAppName + persistent_ids.back());
340 message.set_category(kCategoryName + persistent_ids.back());
341 gcm_store->AddOutgoingMessage(
342 persistent_ids.back(),
343 MCSMessage(message),
344 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
345 PumpLoop();
348 gcm_store = BuildGCMStore().Pass();
349 gcm_store->Load(base::Bind(
350 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
351 PumpLoop();
353 ASSERT_TRUE(load_result->incoming_messages.empty());
354 ASSERT_EQ(load_result->outgoing_messages.size(), persistent_ids.size());
355 for (int i = 0; i < kNumPersistentIds; ++i) {
356 std::string id = persistent_ids[i];
357 ASSERT_TRUE(load_result->outgoing_messages[id].get());
358 const mcs_proto::DataMessageStanza* message =
359 reinterpret_cast<mcs_proto::DataMessageStanza*>(
360 load_result->outgoing_messages[id].get());
361 ASSERT_EQ(message->from(), kAppName + id);
362 ASSERT_EQ(message->category(), kCategoryName + id);
365 gcm_store->RemoveOutgoingMessages(
366 persistent_ids,
367 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
368 PumpLoop();
370 gcm_store = BuildGCMStore().Pass();
371 load_result->outgoing_messages.clear();
372 gcm_store->Load(base::Bind(
373 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
374 PumpLoop();
376 ASSERT_TRUE(load_result->incoming_messages.empty());
377 ASSERT_TRUE(load_result->outgoing_messages.empty());
380 // Verify incoming and outgoing messages don't conflict.
381 TEST_F(GCMStoreImplTest, IncomingAndOutgoingMessages) {
382 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
383 scoped_ptr<GCMStore::LoadResult> load_result;
384 gcm_store->Load(base::Bind(
385 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
386 PumpLoop();
388 std::vector<std::string> persistent_ids;
389 const int kNumPersistentIds = 10;
390 for (int i = 0; i < kNumPersistentIds; ++i) {
391 persistent_ids.push_back(GetNextPersistentId());
392 gcm_store->AddIncomingMessage(
393 persistent_ids.back(),
394 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
395 PumpLoop();
397 mcs_proto::DataMessageStanza message;
398 message.set_from(kAppName + persistent_ids.back());
399 message.set_category(kCategoryName + persistent_ids.back());
400 gcm_store->AddOutgoingMessage(
401 persistent_ids.back(),
402 MCSMessage(message),
403 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
404 PumpLoop();
407 gcm_store = BuildGCMStore().Pass();
408 gcm_store->Load(base::Bind(
409 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
410 PumpLoop();
412 ASSERT_EQ(persistent_ids, load_result->incoming_messages);
413 ASSERT_EQ(load_result->outgoing_messages.size(), persistent_ids.size());
414 for (int i = 0; i < kNumPersistentIds; ++i) {
415 std::string id = persistent_ids[i];
416 ASSERT_TRUE(load_result->outgoing_messages[id].get());
417 const mcs_proto::DataMessageStanza* message =
418 reinterpret_cast<mcs_proto::DataMessageStanza*>(
419 load_result->outgoing_messages[id].get());
420 ASSERT_EQ(message->from(), kAppName + id);
421 ASSERT_EQ(message->category(), kCategoryName + id);
424 gcm_store->RemoveIncomingMessages(
425 persistent_ids,
426 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
427 PumpLoop();
428 gcm_store->RemoveOutgoingMessages(
429 persistent_ids,
430 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
431 PumpLoop();
433 gcm_store = BuildGCMStore().Pass();
434 load_result->incoming_messages.clear();
435 load_result->outgoing_messages.clear();
436 gcm_store->Load(base::Bind(
437 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
438 PumpLoop();
440 ASSERT_TRUE(load_result->incoming_messages.empty());
441 ASSERT_TRUE(load_result->outgoing_messages.empty());
444 // Test that per-app message limits are enforced, persisted across restarts,
445 // and updated as messages are removed.
446 TEST_F(GCMStoreImplTest, PerAppMessageLimits) {
447 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
448 scoped_ptr<GCMStore::LoadResult> load_result;
449 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
450 base::Unretained(this),
451 &load_result));
453 // Add the initial (below app limit) messages.
454 for (int i = 0; i < kNumMessagesPerApp; ++i) {
455 mcs_proto::DataMessageStanza message;
456 message.set_from(kAppName);
457 message.set_category(kCategoryName);
458 EXPECT_TRUE(gcm_store->AddOutgoingMessage(
459 base::IntToString(i),
460 MCSMessage(message),
461 base::Bind(&GCMStoreImplTest::UpdateCallback,
462 base::Unretained(this))));
463 PumpLoop();
466 // Attempting to add some more should fail.
467 for (int i = 0; i < kNumMessagesPerApp; ++i) {
468 mcs_proto::DataMessageStanza message;
469 message.set_from(kAppName);
470 message.set_category(kCategoryName);
471 EXPECT_FALSE(gcm_store->AddOutgoingMessage(
472 base::IntToString(i + kNumMessagesPerApp),
473 MCSMessage(message),
474 base::Bind(&GCMStoreImplTest::UpdateCallback,
475 base::Unretained(this))));
476 PumpLoop();
479 // Tear down and restore the database.
480 gcm_store = BuildGCMStore().Pass();
481 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
482 base::Unretained(this),
483 &load_result));
484 PumpLoop();
486 // Adding more messages should still fail.
487 for (int i = 0; i < kNumMessagesPerApp; ++i) {
488 mcs_proto::DataMessageStanza message;
489 message.set_from(kAppName);
490 message.set_category(kCategoryName);
491 EXPECT_FALSE(gcm_store->AddOutgoingMessage(
492 base::IntToString(i + kNumMessagesPerApp),
493 MCSMessage(message),
494 base::Bind(&GCMStoreImplTest::UpdateCallback,
495 base::Unretained(this))));
496 PumpLoop();
499 // Remove the existing messages.
500 for (int i = 0; i < kNumMessagesPerApp; ++i) {
501 gcm_store->RemoveOutgoingMessage(
502 base::IntToString(i),
503 base::Bind(&GCMStoreImplTest::UpdateCallback,
504 base::Unretained(this)));
505 PumpLoop();
508 // Successfully add new messages.
509 for (int i = 0; i < kNumMessagesPerApp; ++i) {
510 mcs_proto::DataMessageStanza message;
511 message.set_from(kAppName);
512 message.set_category(kCategoryName);
513 EXPECT_TRUE(gcm_store->AddOutgoingMessage(
514 base::IntToString(i + kNumMessagesPerApp),
515 MCSMessage(message),
516 base::Bind(&GCMStoreImplTest::UpdateCallback,
517 base::Unretained(this))));
518 PumpLoop();
522 TEST_F(GCMStoreImplTest, AccountMapping) {
523 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
524 scoped_ptr<GCMStore::LoadResult> load_result;
525 gcm_store->Load(base::Bind(
526 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
528 // Add account mappings.
529 AccountMapping account_mapping1;
530 account_mapping1.account_id = "account_id_1";
531 account_mapping1.email = "account_id_1@gmail.com";
532 account_mapping1.access_token = "account_token1";
533 account_mapping1.status = AccountMapping::ADDING;
534 account_mapping1.status_change_timestamp = base::Time();
535 account_mapping1.last_message_type = AccountMapping::MSG_ADD;
536 account_mapping1.last_message_id = "message_1";
538 AccountMapping account_mapping2;
539 account_mapping2.account_id = "account_id_2";
540 account_mapping2.email = "account_id_2@gmail.com";
541 account_mapping2.access_token = "account_token1";
542 account_mapping2.status = AccountMapping::REMOVING;
543 account_mapping2.status_change_timestamp =
544 base::Time::FromInternalValue(1305734521259935LL);
545 account_mapping2.last_message_type = AccountMapping::MSG_REMOVE;
546 account_mapping2.last_message_id = "message_2";
548 gcm_store->AddAccountMapping(
549 account_mapping1,
550 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
551 PumpLoop();
552 gcm_store->AddAccountMapping(
553 account_mapping2,
554 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
555 PumpLoop();
557 gcm_store = BuildGCMStore().Pass();
558 gcm_store->Load(base::Bind(
559 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
560 PumpLoop();
562 EXPECT_EQ(2UL, load_result->account_mappings.size());
563 GCMStore::AccountMappingMap::iterator iter =
564 load_result->account_mappings.begin();
565 EXPECT_EQ("account_id_1", iter->first);
566 EXPECT_EQ(account_mapping1.account_id, iter->second.account_id);
567 EXPECT_EQ(account_mapping1.email, iter->second.email);
568 EXPECT_TRUE(iter->second.access_token.empty());
569 EXPECT_EQ(AccountMapping::ADDING, iter->second.status);
570 EXPECT_EQ(account_mapping1.status_change_timestamp,
571 iter->second.status_change_timestamp);
572 EXPECT_EQ(account_mapping1.last_message_type, iter->second.last_message_type);
573 EXPECT_EQ(account_mapping1.last_message_id, iter->second.last_message_id);
574 ++iter;
575 EXPECT_EQ("account_id_2", iter->first);
576 EXPECT_EQ(account_mapping2.account_id, iter->second.account_id);
577 EXPECT_EQ(account_mapping2.email, iter->second.email);
578 EXPECT_TRUE(iter->second.access_token.empty());
579 EXPECT_EQ(AccountMapping::REMOVING, iter->second.status);
580 EXPECT_EQ(account_mapping2.status_change_timestamp,
581 iter->second.status_change_timestamp);
582 EXPECT_EQ(account_mapping2.last_message_type, iter->second.last_message_type);
583 EXPECT_EQ(account_mapping2.last_message_id, iter->second.last_message_id);
585 gcm_store->RemoveAccountMapping(
586 account_mapping1.account_id,
587 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
588 PumpLoop();
590 gcm_store = BuildGCMStore().Pass();
591 gcm_store->Load(base::Bind(
592 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
593 PumpLoop();
595 EXPECT_EQ(1UL, load_result->account_mappings.size());
596 iter = load_result->account_mappings.begin();
597 EXPECT_EQ("account_id_2", iter->first);
598 EXPECT_EQ(account_mapping2.account_id, iter->second.account_id);
599 EXPECT_EQ(account_mapping2.email, iter->second.email);
600 EXPECT_TRUE(iter->second.access_token.empty());
601 EXPECT_EQ(AccountMapping::REMOVING, iter->second.status);
602 EXPECT_EQ(account_mapping2.status_change_timestamp,
603 iter->second.status_change_timestamp);
604 EXPECT_EQ(account_mapping2.last_message_type, iter->second.last_message_type);
605 EXPECT_EQ(account_mapping2.last_message_id, iter->second.last_message_id);
608 // When the database is destroyed, all database updates should fail. At the
609 // same time, they per-app message counts should not go up, as failures should
610 // result in decrementing the counts.
611 TEST_F(GCMStoreImplTest, AddMessageAfterDestroy) {
612 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
613 scoped_ptr<GCMStore::LoadResult> load_result;
614 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
615 base::Unretained(this),
616 &load_result));
617 PumpLoop();
618 gcm_store->Destroy(base::Bind(&GCMStoreImplTest::UpdateCallback,
619 base::Unretained(this)));
620 PumpLoop();
622 expected_success_ = false;
623 for (int i = 0; i < kNumMessagesPerApp * 2; ++i) {
624 mcs_proto::DataMessageStanza message;
625 message.set_from(kAppName);
626 message.set_category(kCategoryName);
627 // Because all adds are failing, none should hit the per-app message limits.
628 EXPECT_TRUE(gcm_store->AddOutgoingMessage(
629 base::IntToString(i),
630 MCSMessage(message),
631 base::Bind(&GCMStoreImplTest::UpdateCallback,
632 base::Unretained(this))));
633 PumpLoop();
637 TEST_F(GCMStoreImplTest, ReloadAfterClose) {
638 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
639 scoped_ptr<GCMStore::LoadResult> load_result;
640 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
641 base::Unretained(this),
642 &load_result));
643 PumpLoop();
645 gcm_store->Close();
646 PumpLoop();
648 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
649 base::Unretained(this),
650 &load_result));
651 PumpLoop();
654 } // namespace
656 } // namespace gcm