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

Side by Side Diff: google_apis/gcm/engine/mcs_client_unittest.cc

Issue 117513004: [GCM] Add TTL support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 6 years, 11 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/engine/mcs_client.h" 5 #include "google_apis/gcm/engine/mcs_client.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/strings/string_number_conversions.h"
11 #include "base/test/simple_test_clock.h"
11 #include "components/webdata/encryptor/encryptor.h" 12 #include "components/webdata/encryptor/encryptor.h"
12 #include "google_apis/gcm/base/mcs_util.h" 13 #include "google_apis/gcm/base/mcs_util.h"
13 #include "google_apis/gcm/engine/fake_connection_factory.h" 14 #include "google_apis/gcm/engine/fake_connection_factory.h"
14 #include "google_apis/gcm/engine/fake_connection_handler.h" 15 #include "google_apis/gcm/engine/fake_connection_handler.h"
15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
16 17
17 namespace gcm { 18 namespace gcm {
18 19
19 namespace { 20 namespace {
20 21
21 const uint64 kAndroidId = 54321; 22 const uint64 kAndroidId = 54321;
22 const uint64 kSecurityToken = 12345; 23 const uint64 kSecurityToken = 12345;
23 24
24 // Number of messages to send when testing batching. 25 // Number of messages to send when testing batching.
25 // Note: must be even for tests that split batches in half. 26 // Note: must be even for tests that split batches in half.
26 const int kMessageBatchSize = 6; 27 const int kMessageBatchSize = 6;
27 28
28 // The number of unacked messages the client will receive before sending a 29 // The number of unacked messages the client will receive before sending a
29 // stream ack. 30 // stream ack.
30 // TODO(zea): get this (and other constants) directly from the mcs client. 31 // TODO(zea): get this (and other constants) directly from the mcs client.
31 const int kAckLimitSize = 10; 32 const int kAckLimitSize = 10;
32 33
34 // TTL value for reliable messages.
35 const int kTTLValue = 5 * 60; // 5 minutes.
36
33 // Helper for building arbitrary data messages. 37 // Helper for building arbitrary data messages.
34 MCSMessage BuildDataMessage(const std::string& from, 38 MCSMessage BuildDataMessage(const std::string& from,
35 const std::string& category, 39 const std::string& category,
36 int last_stream_id_received, 40 int last_stream_id_received,
37 const std::string persistent_id) { 41 const std::string persistent_id,
42 int ttl,
43 uint64 sent) {
38 mcs_proto::DataMessageStanza data_message; 44 mcs_proto::DataMessageStanza data_message;
39 data_message.set_from(from); 45 data_message.set_from(from);
40 data_message.set_category(category); 46 data_message.set_category(category);
41 data_message.set_last_stream_id_received(last_stream_id_received); 47 data_message.set_last_stream_id_received(last_stream_id_received);
42 if (!persistent_id.empty()) 48 if (!persistent_id.empty())
43 data_message.set_persistent_id(persistent_id); 49 data_message.set_persistent_id(persistent_id);
50 data_message.set_ttl(ttl);
51 data_message.set_sent(sent);
44 return MCSMessage(kDataMessageStanzaTag, data_message); 52 return MCSMessage(kDataMessageStanzaTag, data_message);
45 } 53 }
46 54
47 // MCSClient with overriden exposed persistent id logic. 55 // MCSClient with overriden exposed persistent id logic.
48 class TestMCSClient : public MCSClient { 56 class TestMCSClient : public MCSClient {
49 public: 57 public:
50 TestMCSClient(ConnectionFactory* connection_factory, 58 TestMCSClient(base::Clock* clock,
59 ConnectionFactory* connection_factory,
51 RMQStore* rmq_store) 60 RMQStore* rmq_store)
52 : MCSClient(connection_factory, rmq_store), 61 : MCSClient(clock, connection_factory, rmq_store),
53 next_id_(0) { 62 next_id_(0) {
54 } 63 }
55 64
56 virtual std::string GetNextPersistentId() OVERRIDE { 65 virtual std::string GetNextPersistentId() OVERRIDE {
57 return base::UintToString(++next_id_); 66 return base::UintToString(++next_id_);
58 } 67 }
59 68
60 private: 69 private:
61 uint32 next_id_; 70 uint32 next_id_;
62 }; 71 };
63 72
64 class MCSClientTest : public testing::Test { 73 class MCSClientTest : public testing::Test {
65 public: 74 public:
66 MCSClientTest(); 75 MCSClientTest();
67 virtual ~MCSClientTest(); 76 virtual ~MCSClientTest();
68 77
69 void BuildMCSClient(); 78 void BuildMCSClient();
70 void InitializeClient(); 79 void InitializeClient();
71 void LoginClient(const std::vector<std::string>& acknowledged_ids); 80 void LoginClient(const std::vector<std::string>& acknowledged_ids);
72 81
82 base::SimpleTestClock* clock() { return &clock_; }
73 TestMCSClient* mcs_client() const { return mcs_client_.get(); } 83 TestMCSClient* mcs_client() const { return mcs_client_.get(); }
74 FakeConnectionFactory* connection_factory() { 84 FakeConnectionFactory* connection_factory() {
75 return &connection_factory_; 85 return &connection_factory_;
76 } 86 }
77 bool init_success() const { return init_success_; } 87 bool init_success() const { return init_success_; }
78 uint64 restored_android_id() const { return restored_android_id_; } 88 uint64 restored_android_id() const { return restored_android_id_; }
79 uint64 restored_security_token() const { return restored_security_token_; } 89 uint64 restored_security_token() const { return restored_security_token_; }
80 MCSMessage* received_message() const { return received_message_.get(); } 90 MCSMessage* received_message() const { return received_message_.get(); }
81 std::string sent_message_id() const { return sent_message_id_;} 91 std::string sent_message_id() const { return sent_message_id_;}
82 92
83 FakeConnectionHandler* GetFakeHandler() const; 93 FakeConnectionHandler* GetFakeHandler() const;
84 94
85 void WaitForMCSEvent(); 95 void WaitForMCSEvent();
86 void PumpLoop(); 96 void PumpLoop();
87 97
88 private: 98 private:
89 void InitializationCallback(bool success, 99 void InitializationCallback(bool success,
90 uint64 restored_android_id, 100 uint64 restored_android_id,
91 uint64 restored_security_token); 101 uint64 restored_security_token);
92 void MessageReceivedCallback(const MCSMessage& message); 102 void MessageReceivedCallback(const MCSMessage& message);
93 void MessageSentCallback(const std::string& message_id); 103 void MessageSentCallback(const std::string& message_id);
94 104
105 base::SimpleTestClock clock_;
106
95 base::ScopedTempDir temp_directory_; 107 base::ScopedTempDir temp_directory_;
96 base::MessageLoop message_loop_; 108 base::MessageLoop message_loop_;
97 scoped_ptr<base::RunLoop> run_loop_; 109 scoped_ptr<base::RunLoop> run_loop_;
98 scoped_ptr<RMQStore> rmq_store_; 110 scoped_ptr<RMQStore> rmq_store_;
99 111
100 FakeConnectionFactory connection_factory_; 112 FakeConnectionFactory connection_factory_;
101 scoped_ptr<TestMCSClient> mcs_client_; 113 scoped_ptr<TestMCSClient> mcs_client_;
102 bool init_success_; 114 bool init_success_;
103 uint64 restored_android_id_; 115 uint64 restored_android_id_;
104 uint64 restored_security_token_; 116 uint64 restored_security_token_;
(...skipping 13 matching lines...) Expand all
118 #if defined(OS_MACOSX) 130 #if defined(OS_MACOSX)
119 Encryptor::UseMockKeychain(true); 131 Encryptor::UseMockKeychain(true);
120 #endif 132 #endif
121 } 133 }
122 134
123 MCSClientTest::~MCSClientTest() {} 135 MCSClientTest::~MCSClientTest() {}
124 136
125 void MCSClientTest::BuildMCSClient() { 137 void MCSClientTest::BuildMCSClient() {
126 rmq_store_.reset(new RMQStore(temp_directory_.path(), 138 rmq_store_.reset(new RMQStore(temp_directory_.path(),
127 message_loop_.message_loop_proxy())); 139 message_loop_.message_loop_proxy()));
128 mcs_client_.reset(new TestMCSClient(&connection_factory_, rmq_store_.get())); 140 mcs_client_.reset(new TestMCSClient(&clock_,
141 &connection_factory_,
142 rmq_store_.get()));
129 } 143 }
130 144
131 void MCSClientTest::InitializeClient() { 145 void MCSClientTest::InitializeClient() {
132 rmq_store_->Load( 146 rmq_store_->Load(
133 base::Bind(&MCSClient::Initialize, 147 base::Bind(&MCSClient::Initialize,
134 base::Unretained(mcs_client_.get()), 148 base::Unretained(mcs_client_.get()),
135 base::Bind(&MCSClientTest::InitializationCallback, 149 base::Bind(&MCSClientTest::InitializationCallback,
136 base::Unretained(this)), 150 base::Unretained(this)),
137 base::Bind(&MCSClientTest::MessageReceivedCallback, 151 base::Bind(&MCSClientTest::MessageReceivedCallback,
138 base::Unretained(this)), 152 base::Unretained(this)),
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 196 }
183 197
184 void MCSClientTest::MessageReceivedCallback(const MCSMessage& message) { 198 void MCSClientTest::MessageReceivedCallback(const MCSMessage& message) {
185 received_message_.reset(new MCSMessage(message)); 199 received_message_.reset(new MCSMessage(message));
186 DVLOG(1) << "Message received callback invoked, killing loop."; 200 DVLOG(1) << "Message received callback invoked, killing loop.";
187 run_loop_->Quit(); 201 run_loop_->Quit();
188 } 202 }
189 203
190 void MCSClientTest::MessageSentCallback(const std::string& message_id) { 204 void MCSClientTest::MessageSentCallback(const std::string& message_id) {
191 DVLOG(1) << "Message sent callback invoked, killing loop."; 205 DVLOG(1) << "Message sent callback invoked, killing loop.";
206 sent_message_id_ = message_id;
192 run_loop_->Quit(); 207 run_loop_->Quit();
193 } 208 }
194 209
195 // Initialize a new client. 210 // Initialize a new client.
196 TEST_F(MCSClientTest, InitializeNew) { 211 TEST_F(MCSClientTest, InitializeNew) {
197 BuildMCSClient(); 212 BuildMCSClient();
198 InitializeClient(); 213 InitializeClient();
199 EXPECT_EQ(0U, restored_android_id()); 214 EXPECT_EQ(0U, restored_android_id());
200 EXPECT_EQ(0U, restored_security_token()); 215 EXPECT_EQ(0U, restored_security_token());
201 EXPECT_TRUE(init_success()); 216 EXPECT_TRUE(init_success());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 EXPECT_FALSE(connection_factory()->IsEndpointReachable()); 251 EXPECT_FALSE(connection_factory()->IsEndpointReachable());
237 EXPECT_FALSE(init_success()); 252 EXPECT_FALSE(init_success());
238 EXPECT_FALSE(received_message()); 253 EXPECT_FALSE(received_message());
239 } 254 }
240 255
241 // Send a message without RMQ support. 256 // Send a message without RMQ support.
242 TEST_F(MCSClientTest, SendMessageNoRMQ) { 257 TEST_F(MCSClientTest, SendMessageNoRMQ) {
243 BuildMCSClient(); 258 BuildMCSClient();
244 InitializeClient(); 259 InitializeClient();
245 LoginClient(std::vector<std::string>()); 260 LoginClient(std::vector<std::string>());
246 MCSMessage message(BuildDataMessage("from", "category", 1, "")); 261 MCSMessage message(BuildDataMessage("from", "category", 1, "", 0, 0));
247 GetFakeHandler()->ExpectOutgoingMessage(message); 262 GetFakeHandler()->ExpectOutgoingMessage(message);
248 mcs_client()->SendMessage(message, false); 263 mcs_client()->SendMessage(message);
249 EXPECT_TRUE(GetFakeHandler()-> 264 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
250 AllOutgoingMessagesReceived());
251 } 265 }
252 266
267 // Send a message without RMQ support while disconnected. Message send should
268 // fail immediately, invoking callback.
269 TEST_F(MCSClientTest, SendMessageNoRMQWhileDisconnected) {
270 BuildMCSClient();
271 InitializeClient();
272
273 EXPECT_TRUE(sent_message_id().empty());
274 MCSMessage message(BuildDataMessage("from", "category", 1, "", 0, 0));
275 mcs_client()->SendMessage(message);
276
277 // Message sent callback should be invoked, but no message should actually
278 // be sent.
279 EXPECT_FALSE(sent_message_id().empty());
280 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
281 }
282
jianli 2014/01/02 18:52:58 nit: empty line not needed
Nicolas Zea 2014/01/02 21:39:08 Done.
283
253 // Send a message with RMQ support. 284 // Send a message with RMQ support.
254 TEST_F(MCSClientTest, SendMessageRMQ) { 285 TEST_F(MCSClientTest, SendMessageRMQ) {
255 BuildMCSClient(); 286 BuildMCSClient();
256 InitializeClient(); 287 InitializeClient();
257 LoginClient(std::vector<std::string>()); 288 LoginClient(std::vector<std::string>());
258 MCSMessage message(BuildDataMessage("from", "category", 1, "1")); 289 MCSMessage message(
290 BuildDataMessage("from", "category", 1, "1", kTTLValue, 0));
259 GetFakeHandler()->ExpectOutgoingMessage(message); 291 GetFakeHandler()->ExpectOutgoingMessage(message);
260 mcs_client()->SendMessage(message, true); 292 mcs_client()->SendMessage(message);
261 EXPECT_TRUE(GetFakeHandler()-> 293 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
262 AllOutgoingMessagesReceived());
263 } 294 }
264 295
265 // Send a message with RMQ support while disconnected. On reconnect, the message 296 // Send a message with RMQ support while disconnected. On reconnect, the message
266 // should be resent. 297 // should be resent.
267 TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) { 298 TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) {
268 BuildMCSClient(); 299 BuildMCSClient();
269 InitializeClient(); 300 InitializeClient();
270 LoginClient(std::vector<std::string>()); 301 LoginClient(std::vector<std::string>());
271 GetFakeHandler()->set_fail_send(true); 302 GetFakeHandler()->set_fail_send(true);
272 MCSMessage message(BuildDataMessage("from", "category", 1, "1")); 303 MCSMessage message(
304 BuildDataMessage("from", "category", 1, "1", kTTLValue, 0));
273 305
274 // The initial (failed) send. 306 // The initial (failed) send.
275 GetFakeHandler()->ExpectOutgoingMessage(message); 307 GetFakeHandler()->ExpectOutgoingMessage(message);
276 // The login request. 308 // The login request.
277 GetFakeHandler()->ExpectOutgoingMessage( 309 GetFakeHandler()->ExpectOutgoingMessage(
278 MCSMessage(kLoginRequestTag, 310 MCSMessage(kLoginRequestTag,
279 BuildLoginRequest(kAndroidId, kSecurityToken). 311 BuildLoginRequest(kAndroidId, kSecurityToken).
280 PassAs<const google::protobuf::MessageLite>())); 312 PassAs<const google::protobuf::MessageLite>()));
281 // The second (re)send. 313 // The second (re)send.
282 GetFakeHandler()->ExpectOutgoingMessage(message); 314 GetFakeHandler()->ExpectOutgoingMessage(message);
283 mcs_client()->SendMessage(message, true); 315 mcs_client()->SendMessage(message);
284 EXPECT_FALSE(GetFakeHandler()-> 316 EXPECT_FALSE(GetFakeHandler()->AllOutgoingMessagesReceived());
285 AllOutgoingMessagesReceived());
286 GetFakeHandler()->set_fail_send(false); 317 GetFakeHandler()->set_fail_send(false);
287 connection_factory()->Connect(); 318 connection_factory()->Connect();
288 WaitForMCSEvent(); // Wait for the login to finish. 319 WaitForMCSEvent(); // Wait for the login to finish.
289 PumpLoop(); // Wait for the send to happen. 320 PumpLoop(); // Wait for the send to happen.
290 EXPECT_TRUE(GetFakeHandler()-> 321 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
291 AllOutgoingMessagesReceived());
292 } 322 }
293 323
294 // Send a message with RMQ support without receiving an acknowledgement. On 324 // Send a message with RMQ support without receiving an acknowledgement. On
295 // restart the message should be resent. 325 // restart the message should be resent.
296 TEST_F(MCSClientTest, SendMessageRMQOnRestart) { 326 TEST_F(MCSClientTest, SendMessageRMQOnRestart) {
297 BuildMCSClient(); 327 BuildMCSClient();
298 InitializeClient(); 328 InitializeClient();
299 LoginClient(std::vector<std::string>()); 329 LoginClient(std::vector<std::string>());
300 GetFakeHandler()->set_fail_send(true); 330 GetFakeHandler()->set_fail_send(true);
301 MCSMessage message(BuildDataMessage("from", "category", 1, "1")); 331 MCSMessage message(
332 BuildDataMessage("from", "category", 1, "1", kTTLValue, 0));
302 333
303 // The initial (failed) send. 334 // The initial (failed) send.
304 GetFakeHandler()->ExpectOutgoingMessage(message); 335 GetFakeHandler()->ExpectOutgoingMessage(message);
305 GetFakeHandler()->set_fail_send(false); 336 GetFakeHandler()->set_fail_send(false);
306 mcs_client()->SendMessage(message, true); 337 mcs_client()->SendMessage(message);
307 EXPECT_TRUE(GetFakeHandler()-> 338 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
308 AllOutgoingMessagesReceived());
309 339
310 // Rebuild the client, which should resend the old message. 340 // Rebuild the client, which should resend the old message.
311 BuildMCSClient(); 341 BuildMCSClient();
312 InitializeClient(); 342 InitializeClient();
313 LoginClient(std::vector<std::string>()); 343 LoginClient(std::vector<std::string>());
314 GetFakeHandler()->ExpectOutgoingMessage(message); 344 GetFakeHandler()->ExpectOutgoingMessage(message);
315 PumpLoop(); 345 PumpLoop();
316 EXPECT_TRUE(GetFakeHandler()-> 346 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
317 AllOutgoingMessagesReceived());
318 } 347 }
319 348
320 // Send messages with RMQ support, followed by receiving a stream ack. On 349 // Send messages with RMQ support, followed by receiving a stream ack. On
321 // restart nothing should be recent. 350 // restart nothing should be recent.
322 TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) { 351 TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) {
323 BuildMCSClient(); 352 BuildMCSClient();
324 InitializeClient(); 353 InitializeClient();
325 LoginClient(std::vector<std::string>()); 354 LoginClient(std::vector<std::string>());
326 355
327 // Send some messages. 356 // Send some messages.
328 for (int i = 1; i <= kMessageBatchSize; ++i) { 357 for (int i = 1; i <= kMessageBatchSize; ++i) {
329 MCSMessage message( 358 MCSMessage message(
330 BuildDataMessage("from", "category", 1, base::IntToString(i))); 359 BuildDataMessage("from",
360 "category",
361 1,
362 base::IntToString(i),
363 kTTLValue,
364 0));
331 GetFakeHandler()->ExpectOutgoingMessage(message); 365 GetFakeHandler()->ExpectOutgoingMessage(message);
332 mcs_client()->SendMessage(message, true); 366 mcs_client()->SendMessage(message);
333 } 367 }
334 EXPECT_TRUE(GetFakeHandler()-> 368 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
335 AllOutgoingMessagesReceived());
336 369
337 // Receive the ack. 370 // Receive the ack.
338 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); 371 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck();
339 ack->set_last_stream_id_received(kMessageBatchSize + 1); 372 ack->set_last_stream_id_received(kMessageBatchSize + 1);
340 GetFakeHandler()->ReceiveMessage( 373 GetFakeHandler()->ReceiveMessage(
341 MCSMessage(kIqStanzaTag, 374 MCSMessage(kIqStanzaTag,
342 ack.PassAs<const google::protobuf::MessageLite>())); 375 ack.PassAs<const google::protobuf::MessageLite>()));
343 WaitForMCSEvent(); 376 WaitForMCSEvent();
344 377
345 // Reconnect and ensure no messages are resent. 378 // Reconnect and ensure no messages are resent.
346 BuildMCSClient(); 379 BuildMCSClient();
347 InitializeClient(); 380 InitializeClient();
348 LoginClient(std::vector<std::string>()); 381 LoginClient(std::vector<std::string>());
349 PumpLoop(); 382 PumpLoop();
350 } 383 }
351 384
352 // Send messages with RMQ support. On restart, receive a SelectiveAck with 385 // Send messages with RMQ support. On restart, receive a SelectiveAck with
353 // the login response. No messages should be resent. 386 // the login response. No messages should be resent.
354 TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) { 387 TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) {
355 BuildMCSClient(); 388 BuildMCSClient();
356 InitializeClient(); 389 InitializeClient();
357 LoginClient(std::vector<std::string>()); 390 LoginClient(std::vector<std::string>());
358 391
359 // Send some messages. 392 // Send some messages.
360 std::vector<std::string> id_list; 393 std::vector<std::string> id_list;
361 for (int i = 1; i <= kMessageBatchSize; ++i) { 394 for (int i = 1; i <= kMessageBatchSize; ++i) {
362 id_list.push_back(base::IntToString(i)); 395 id_list.push_back(base::IntToString(i));
363 MCSMessage message( 396 MCSMessage message(
364 BuildDataMessage("from", "category", 1, id_list.back())); 397 BuildDataMessage("from", "category", 1, id_list.back(), kTTLValue, 0));
365 GetFakeHandler()->ExpectOutgoingMessage(message); 398 GetFakeHandler()->ExpectOutgoingMessage(message);
366 mcs_client()->SendMessage(message, true); 399 mcs_client()->SendMessage(message);
367 } 400 }
368 EXPECT_TRUE(GetFakeHandler()-> 401 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
369 AllOutgoingMessagesReceived());
370 402
371 // Rebuild the client, and receive an acknowledgment for the messages as 403 // Rebuild the client, and receive an acknowledgment for the messages as
372 // part of the login response. 404 // part of the login response.
373 BuildMCSClient(); 405 BuildMCSClient();
374 InitializeClient(); 406 InitializeClient();
375 LoginClient(std::vector<std::string>()); 407 LoginClient(std::vector<std::string>());
376 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(id_list)); 408 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(id_list));
377 GetFakeHandler()->ReceiveMessage( 409 GetFakeHandler()->ReceiveMessage(
378 MCSMessage(kIqStanzaTag, 410 MCSMessage(kIqStanzaTag,
379 ack.PassAs<const google::protobuf::MessageLite>())); 411 ack.PassAs<const google::protobuf::MessageLite>()));
380 WaitForMCSEvent(); 412 WaitForMCSEvent();
381 EXPECT_TRUE(GetFakeHandler()-> 413 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
382 AllOutgoingMessagesReceived());
383 } 414 }
384 415
385 // Send messages with RMQ support. On restart, receive a SelectiveAck with 416 // Send messages with RMQ support. On restart, receive a SelectiveAck with
386 // the login response that only acks some messages. The unacked messages should 417 // the login response that only acks some messages. The unacked messages should
387 // be resent. 418 // be resent.
388 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { 419 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) {
389 BuildMCSClient(); 420 BuildMCSClient();
390 InitializeClient(); 421 InitializeClient();
391 LoginClient(std::vector<std::string>()); 422 LoginClient(std::vector<std::string>());
392 423
393 // Send some messages. 424 // Send some messages.
394 std::vector<std::string> id_list; 425 std::vector<std::string> id_list;
395 for (int i = 1; i <= kMessageBatchSize; ++i) { 426 for (int i = 1; i <= kMessageBatchSize; ++i) {
396 id_list.push_back(base::IntToString(i)); 427 id_list.push_back(base::IntToString(i));
397 MCSMessage message( 428 MCSMessage message(
398 BuildDataMessage("from", "category", 1, id_list.back())); 429 BuildDataMessage("from", "category", 1, id_list.back(), kTTLValue, 0));
399 GetFakeHandler()->ExpectOutgoingMessage(message); 430 GetFakeHandler()->ExpectOutgoingMessage(message);
400 mcs_client()->SendMessage(message, true); 431 mcs_client()->SendMessage(message);
401 } 432 }
402 EXPECT_TRUE(GetFakeHandler()-> 433 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
403 AllOutgoingMessagesReceived());
404 434
405 // Rebuild the client, and receive an acknowledgment for the messages as 435 // Rebuild the client, and receive an acknowledgment for the messages as
406 // part of the login response. 436 // part of the login response.
407 BuildMCSClient(); 437 BuildMCSClient();
408 InitializeClient(); 438 InitializeClient();
409 LoginClient(std::vector<std::string>()); 439 LoginClient(std::vector<std::string>());
410 440
411 std::vector<std::string> acked_ids, remaining_ids; 441 std::vector<std::string> acked_ids, remaining_ids;
412 acked_ids.insert(acked_ids.end(), 442 acked_ids.insert(acked_ids.end(),
413 id_list.begin(), 443 id_list.begin(),
414 id_list.begin() + kMessageBatchSize / 2); 444 id_list.begin() + kMessageBatchSize / 2);
415 remaining_ids.insert(remaining_ids.end(), 445 remaining_ids.insert(remaining_ids.end(),
416 id_list.begin() + kMessageBatchSize / 2, 446 id_list.begin() + kMessageBatchSize / 2,
417 id_list.end()); 447 id_list.end());
418 for (int i = 1; i <= kMessageBatchSize / 2; ++i) { 448 for (int i = 1; i <= kMessageBatchSize / 2; ++i) {
419 MCSMessage message( 449 MCSMessage message(
420 BuildDataMessage("from", 450 BuildDataMessage("from",
421 "category", 451 "category",
422 2, 452 2,
423 remaining_ids[i - 1])); 453 remaining_ids[i - 1],
454 kTTLValue,
455 0));
424 GetFakeHandler()->ExpectOutgoingMessage(message); 456 GetFakeHandler()->ExpectOutgoingMessage(message);
425 } 457 }
426 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); 458 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids));
427 GetFakeHandler()->ReceiveMessage( 459 GetFakeHandler()->ReceiveMessage(
428 MCSMessage(kIqStanzaTag, 460 MCSMessage(kIqStanzaTag,
429 ack.PassAs<const google::protobuf::MessageLite>())); 461 ack.PassAs<const google::protobuf::MessageLite>()));
430 WaitForMCSEvent(); 462 WaitForMCSEvent();
431 EXPECT_TRUE(GetFakeHandler()-> 463 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
432 AllOutgoingMessagesReceived());
433 } 464 }
434 465
435 // Receive some messages. On restart, the login request should contain the 466 // Receive some messages. On restart, the login request should contain the
436 // appropriate acknowledged ids. 467 // appropriate acknowledged ids.
437 TEST_F(MCSClientTest, AckOnLogin) { 468 TEST_F(MCSClientTest, AckOnLogin) {
438 BuildMCSClient(); 469 BuildMCSClient();
439 InitializeClient(); 470 InitializeClient();
440 LoginClient(std::vector<std::string>()); 471 LoginClient(std::vector<std::string>());
441 472
442 // Receive some messages. 473 // Receive some messages.
443 std::vector<std::string> id_list; 474 std::vector<std::string> id_list;
444 for (int i = 1; i <= kMessageBatchSize; ++i) { 475 for (int i = 1; i <= kMessageBatchSize; ++i) {
445 id_list.push_back(base::IntToString(i)); 476 id_list.push_back(base::IntToString(i));
446 MCSMessage message( 477 MCSMessage message(
447 BuildDataMessage("from", "category", i, id_list.back())); 478 BuildDataMessage("from", "category", i, id_list.back(), kTTLValue, 0));
448 GetFakeHandler()->ReceiveMessage(message); 479 GetFakeHandler()->ReceiveMessage(message);
449 WaitForMCSEvent(); 480 WaitForMCSEvent();
450 PumpLoop(); 481 PumpLoop();
451 } 482 }
452 483
453 // Restart the client. 484 // Restart the client.
454 BuildMCSClient(); 485 BuildMCSClient();
455 InitializeClient(); 486 InitializeClient();
456 LoginClient(id_list); 487 LoginClient(id_list);
457 } 488 }
458 489
459 // Receive some messages. On the next send, the outgoing message should contain 490 // Receive some messages. On the next send, the outgoing message should contain
460 // the appropriate last stream id received field to ack the received messages. 491 // the appropriate last stream id received field to ack the received messages.
461 TEST_F(MCSClientTest, AckOnSend) { 492 TEST_F(MCSClientTest, AckOnSend) {
462 BuildMCSClient(); 493 BuildMCSClient();
463 InitializeClient(); 494 InitializeClient();
464 LoginClient(std::vector<std::string>()); 495 LoginClient(std::vector<std::string>());
465 496
466 // Receive some messages. 497 // Receive some messages.
467 std::vector<std::string> id_list; 498 std::vector<std::string> id_list;
468 for (int i = 1; i <= kMessageBatchSize; ++i) { 499 for (int i = 1; i <= kMessageBatchSize; ++i) {
469 id_list.push_back(base::IntToString(i)); 500 id_list.push_back(base::IntToString(i));
470 MCSMessage message( 501 MCSMessage message(
471 BuildDataMessage("from", "category", i, id_list.back())); 502 BuildDataMessage("from", "category", i, id_list.back(), kTTLValue, 0));
472 GetFakeHandler()->ReceiveMessage(message); 503 GetFakeHandler()->ReceiveMessage(message);
473 WaitForMCSEvent(); 504 WaitForMCSEvent();
474 PumpLoop(); 505 PumpLoop();
475 } 506 }
476 507
477 // Trigger a message send, which should acknowledge via stream ack. 508 // Trigger a message send, which should acknowledge via stream ack.
478 MCSMessage message( 509 MCSMessage message(
479 BuildDataMessage("from", "category", kMessageBatchSize + 1, "1")); 510 BuildDataMessage("from",
511 "category",
512 kMessageBatchSize + 1,
513 "1",
514 kTTLValue,
515 0));
480 GetFakeHandler()->ExpectOutgoingMessage(message); 516 GetFakeHandler()->ExpectOutgoingMessage(message);
481 mcs_client()->SendMessage(message, true); 517 mcs_client()->SendMessage(message);
482 EXPECT_TRUE(GetFakeHandler()-> 518 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
483 AllOutgoingMessagesReceived());
484 } 519 }
485 520
486 // Receive the ack limit in messages, which should trigger an automatic 521 // Receive the ack limit in messages, which should trigger an automatic
487 // stream ack. Receive a heartbeat to confirm the ack. 522 // stream ack. Receive a heartbeat to confirm the ack.
488 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { 523 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) {
489 BuildMCSClient(); 524 BuildMCSClient();
490 InitializeClient(); 525 InitializeClient();
491 LoginClient(std::vector<std::string>()); 526 LoginClient(std::vector<std::string>());
492 527
493 // The stream ack. 528 // The stream ack.
494 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); 529 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck();
495 ack->set_last_stream_id_received(kAckLimitSize + 1); 530 ack->set_last_stream_id_received(kAckLimitSize + 1);
496 GetFakeHandler()->ExpectOutgoingMessage( 531 GetFakeHandler()->ExpectOutgoingMessage(
497 MCSMessage(kIqStanzaTag, 532 MCSMessage(kIqStanzaTag,
498 ack.PassAs<const google::protobuf::MessageLite>())); 533 ack.PassAs<const google::protobuf::MessageLite>()));
499 534
500 // Receive some messages. 535 // Receive some messages.
501 std::vector<std::string> id_list; 536 std::vector<std::string> id_list;
502 for (int i = 1; i <= kAckLimitSize; ++i) { 537 for (int i = 1; i <= kAckLimitSize; ++i) {
503 id_list.push_back(base::IntToString(i)); 538 id_list.push_back(base::IntToString(i));
504 MCSMessage message( 539 MCSMessage message(
505 BuildDataMessage("from", "category", i, id_list.back())); 540 BuildDataMessage("from", "category", i, id_list.back(), kTTLValue, 0));
506 GetFakeHandler()->ReceiveMessage(message); 541 GetFakeHandler()->ReceiveMessage(message);
507 WaitForMCSEvent(); 542 WaitForMCSEvent();
508 PumpLoop(); 543 PumpLoop();
509 } 544 }
510 EXPECT_TRUE(GetFakeHandler()-> 545 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
511 AllOutgoingMessagesReceived());
512 546
513 // Receive a heartbeat confirming the ack (and receive the heartbeat ack). 547 // Receive a heartbeat confirming the ack (and receive the heartbeat ack).
514 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat( 548 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat(
515 new mcs_proto::HeartbeatPing()); 549 new mcs_proto::HeartbeatPing());
516 heartbeat->set_last_stream_id_received(2); 550 heartbeat->set_last_stream_id_received(2);
517 551
518 scoped_ptr<mcs_proto::HeartbeatAck> heartbeat_ack( 552 scoped_ptr<mcs_proto::HeartbeatAck> heartbeat_ack(
519 new mcs_proto::HeartbeatAck()); 553 new mcs_proto::HeartbeatAck());
520 heartbeat_ack->set_last_stream_id_received(kAckLimitSize + 2); 554 heartbeat_ack->set_last_stream_id_received(kAckLimitSize + 2);
521 GetFakeHandler()->ExpectOutgoingMessage( 555 GetFakeHandler()->ExpectOutgoingMessage(
522 MCSMessage(kHeartbeatAckTag, 556 MCSMessage(kHeartbeatAckTag,
523 heartbeat_ack.PassAs<const google::protobuf::MessageLite>())); 557 heartbeat_ack.PassAs<const google::protobuf::MessageLite>()));
524 558
525 GetFakeHandler()->ReceiveMessage( 559 GetFakeHandler()->ReceiveMessage(
526 MCSMessage(kHeartbeatPingTag, 560 MCSMessage(kHeartbeatPingTag,
527 heartbeat.PassAs<const google::protobuf::MessageLite>())); 561 heartbeat.PassAs<const google::protobuf::MessageLite>()));
528 WaitForMCSEvent(); 562 WaitForMCSEvent();
529 EXPECT_TRUE(GetFakeHandler()-> 563 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
530 AllOutgoingMessagesReceived());
531 564
532 // Rebuild the client. Nothing should be sent on login. 565 // Rebuild the client. Nothing should be sent on login.
533 BuildMCSClient(); 566 BuildMCSClient();
534 InitializeClient(); 567 InitializeClient();
535 LoginClient(std::vector<std::string>()); 568 LoginClient(std::vector<std::string>());
536 EXPECT_TRUE(GetFakeHandler()-> 569 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
537 AllOutgoingMessagesReceived()); 570 }
571
572 // If a message's TTL has expired by the time it reaches the front of the send
573 // queue, it should be dropped.
574 TEST_F(MCSClientTest, ExpiredTTLOnSend) {
575 BuildMCSClient();
576 InitializeClient();
577 LoginClient(std::vector<std::string>());
578 MCSMessage message(
579 BuildDataMessage("from", "category", 1, "1", kTTLValue, 0));
580
581 // Advance time to after the TTL.
582 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 1));
583 EXPECT_TRUE(sent_message_id().empty());
584 mcs_client()->SendMessage(message);
585
586 // No messages should be sent, but the callback should still be invoked.
587 EXPECT_FALSE(sent_message_id().empty());
588 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
589 }
590
591 TEST_F(MCSClientTest, ExpiredTTLOnRestart) {
592 BuildMCSClient();
593 InitializeClient();
594 LoginClient(std::vector<std::string>());
595 GetFakeHandler()->set_fail_send(true);
596 MCSMessage message(
597 BuildDataMessage("from", "category", 1, "1", kTTLValue, 0));
598
599 // The initial (failed) send.
600 GetFakeHandler()->ExpectOutgoingMessage(message);
601 GetFakeHandler()->set_fail_send(false);
602 mcs_client()->SendMessage(message);
603 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
604
605 // Move the clock forward and rebuild the client, which should fail the
606 // message send on restart.
607 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 1));
608 BuildMCSClient();
609 InitializeClient();
610 LoginClient(std::vector<std::string>());
611 PumpLoop();
612 EXPECT_FALSE(sent_message_id().empty());
613 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
538 } 614 }
539 615
540 } // namespace 616 } // namespace
541 617
542 } // namespace gcm 618 } // namespace gcm
OLDNEW
« google_apis/gcm/engine/mcs_client.cc ('K') | « google_apis/gcm/engine/mcs_client.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698