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

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: fix probe tool 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
« no previous file with comments | « google_apis/gcm/engine/mcs_client.cc ('k') | google_apis/gcm/tools/mcs_probe.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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, 1));
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()); 265 }
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, 1));
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());
251 } 281 }
252 282
253 // Send a message with RMQ support. 283 // Send a message with RMQ support.
254 TEST_F(MCSClientTest, SendMessageRMQ) { 284 TEST_F(MCSClientTest, SendMessageRMQ) {
255 BuildMCSClient(); 285 BuildMCSClient();
256 InitializeClient(); 286 InitializeClient();
257 LoginClient(std::vector<std::string>()); 287 LoginClient(std::vector<std::string>());
258 MCSMessage message(BuildDataMessage("from", "category", 1, "1")); 288 MCSMessage message(
289 BuildDataMessage("from", "category", 1, "1", kTTLValue, 1));
259 GetFakeHandler()->ExpectOutgoingMessage(message); 290 GetFakeHandler()->ExpectOutgoingMessage(message);
260 mcs_client()->SendMessage(message, true); 291 mcs_client()->SendMessage(message);
261 EXPECT_TRUE(GetFakeHandler()-> 292 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
262 AllOutgoingMessagesReceived());
263 } 293 }
264 294
265 // Send a message with RMQ support while disconnected. On reconnect, the message 295 // Send a message with RMQ support while disconnected. On reconnect, the message
266 // should be resent. 296 // should be resent.
267 TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) { 297 TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) {
268 BuildMCSClient(); 298 BuildMCSClient();
269 InitializeClient(); 299 InitializeClient();
270 LoginClient(std::vector<std::string>()); 300 LoginClient(std::vector<std::string>());
271 GetFakeHandler()->set_fail_send(true); 301 GetFakeHandler()->set_fail_send(true);
272 MCSMessage message(BuildDataMessage("from", "category", 1, "1")); 302 MCSMessage message(
303 BuildDataMessage("from", "category", 1, "1", kTTLValue, 1));
273 304
274 // The initial (failed) send. 305 // The initial (failed) send.
275 GetFakeHandler()->ExpectOutgoingMessage(message); 306 GetFakeHandler()->ExpectOutgoingMessage(message);
276 // The login request. 307 // The login request.
277 GetFakeHandler()->ExpectOutgoingMessage( 308 GetFakeHandler()->ExpectOutgoingMessage(
278 MCSMessage(kLoginRequestTag, 309 MCSMessage(kLoginRequestTag,
279 BuildLoginRequest(kAndroidId, kSecurityToken). 310 BuildLoginRequest(kAndroidId, kSecurityToken).
280 PassAs<const google::protobuf::MessageLite>())); 311 PassAs<const google::protobuf::MessageLite>()));
281 // The second (re)send. 312 // The second (re)send.
282 GetFakeHandler()->ExpectOutgoingMessage(message); 313 GetFakeHandler()->ExpectOutgoingMessage(message);
283 mcs_client()->SendMessage(message, true); 314 mcs_client()->SendMessage(message);
284 EXPECT_FALSE(GetFakeHandler()-> 315 EXPECT_FALSE(GetFakeHandler()->AllOutgoingMessagesReceived());
285 AllOutgoingMessagesReceived());
286 GetFakeHandler()->set_fail_send(false); 316 GetFakeHandler()->set_fail_send(false);
287 connection_factory()->Connect(); 317 connection_factory()->Connect();
288 WaitForMCSEvent(); // Wait for the login to finish. 318 WaitForMCSEvent(); // Wait for the login to finish.
289 PumpLoop(); // Wait for the send to happen. 319 PumpLoop(); // Wait for the send to happen.
290 EXPECT_TRUE(GetFakeHandler()-> 320 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
291 AllOutgoingMessagesReceived());
292 } 321 }
293 322
294 // Send a message with RMQ support without receiving an acknowledgement. On 323 // Send a message with RMQ support without receiving an acknowledgement. On
295 // restart the message should be resent. 324 // restart the message should be resent.
296 TEST_F(MCSClientTest, SendMessageRMQOnRestart) { 325 TEST_F(MCSClientTest, SendMessageRMQOnRestart) {
297 BuildMCSClient(); 326 BuildMCSClient();
298 InitializeClient(); 327 InitializeClient();
299 LoginClient(std::vector<std::string>()); 328 LoginClient(std::vector<std::string>());
300 GetFakeHandler()->set_fail_send(true); 329 GetFakeHandler()->set_fail_send(true);
301 MCSMessage message(BuildDataMessage("from", "category", 1, "1")); 330 MCSMessage message(
331 BuildDataMessage("from", "category", 1, "1", kTTLValue, 1));
302 332
303 // The initial (failed) send. 333 // The initial (failed) send.
304 GetFakeHandler()->ExpectOutgoingMessage(message); 334 GetFakeHandler()->ExpectOutgoingMessage(message);
305 GetFakeHandler()->set_fail_send(false); 335 GetFakeHandler()->set_fail_send(false);
306 mcs_client()->SendMessage(message, true); 336 mcs_client()->SendMessage(message);
307 EXPECT_TRUE(GetFakeHandler()-> 337 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
308 AllOutgoingMessagesReceived());
309 338
310 // Rebuild the client, which should resend the old message. 339 // Rebuild the client, which should resend the old message.
311 BuildMCSClient(); 340 BuildMCSClient();
312 InitializeClient(); 341 InitializeClient();
313 LoginClient(std::vector<std::string>()); 342 LoginClient(std::vector<std::string>());
314 GetFakeHandler()->ExpectOutgoingMessage(message); 343 GetFakeHandler()->ExpectOutgoingMessage(message);
315 PumpLoop(); 344 PumpLoop();
316 EXPECT_TRUE(GetFakeHandler()-> 345 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
317 AllOutgoingMessagesReceived());
318 } 346 }
319 347
320 // Send messages with RMQ support, followed by receiving a stream ack. On 348 // Send messages with RMQ support, followed by receiving a stream ack. On
321 // restart nothing should be recent. 349 // restart nothing should be recent.
322 TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) { 350 TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) {
323 BuildMCSClient(); 351 BuildMCSClient();
324 InitializeClient(); 352 InitializeClient();
325 LoginClient(std::vector<std::string>()); 353 LoginClient(std::vector<std::string>());
326 354
327 // Send some messages. 355 // Send some messages.
328 for (int i = 1; i <= kMessageBatchSize; ++i) { 356 for (int i = 1; i <= kMessageBatchSize; ++i) {
329 MCSMessage message( 357 MCSMessage message(
330 BuildDataMessage("from", "category", 1, base::IntToString(i))); 358 BuildDataMessage("from",
359 "category",
360 1,
361 base::IntToString(i),
362 kTTLValue,
363 1));
331 GetFakeHandler()->ExpectOutgoingMessage(message); 364 GetFakeHandler()->ExpectOutgoingMessage(message);
332 mcs_client()->SendMessage(message, true); 365 mcs_client()->SendMessage(message);
333 } 366 }
334 EXPECT_TRUE(GetFakeHandler()-> 367 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
335 AllOutgoingMessagesReceived());
336 368
337 // Receive the ack. 369 // Receive the ack.
338 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); 370 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck();
339 ack->set_last_stream_id_received(kMessageBatchSize + 1); 371 ack->set_last_stream_id_received(kMessageBatchSize + 1);
340 GetFakeHandler()->ReceiveMessage( 372 GetFakeHandler()->ReceiveMessage(
341 MCSMessage(kIqStanzaTag, 373 MCSMessage(kIqStanzaTag,
342 ack.PassAs<const google::protobuf::MessageLite>())); 374 ack.PassAs<const google::protobuf::MessageLite>()));
343 WaitForMCSEvent(); 375 WaitForMCSEvent();
344 376
345 // Reconnect and ensure no messages are resent. 377 // Reconnect and ensure no messages are resent.
346 BuildMCSClient(); 378 BuildMCSClient();
347 InitializeClient(); 379 InitializeClient();
348 LoginClient(std::vector<std::string>()); 380 LoginClient(std::vector<std::string>());
349 PumpLoop(); 381 PumpLoop();
350 } 382 }
351 383
352 // Send messages with RMQ support. On restart, receive a SelectiveAck with 384 // Send messages with RMQ support. On restart, receive a SelectiveAck with
353 // the login response. No messages should be resent. 385 // the login response. No messages should be resent.
354 TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) { 386 TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) {
355 BuildMCSClient(); 387 BuildMCSClient();
356 InitializeClient(); 388 InitializeClient();
357 LoginClient(std::vector<std::string>()); 389 LoginClient(std::vector<std::string>());
358 390
359 // Send some messages. 391 // Send some messages.
360 std::vector<std::string> id_list; 392 std::vector<std::string> id_list;
361 for (int i = 1; i <= kMessageBatchSize; ++i) { 393 for (int i = 1; i <= kMessageBatchSize; ++i) {
362 id_list.push_back(base::IntToString(i)); 394 id_list.push_back(base::IntToString(i));
363 MCSMessage message( 395 MCSMessage message(
364 BuildDataMessage("from", "category", 1, id_list.back())); 396 BuildDataMessage("from", "category", 1, id_list.back(), kTTLValue, 1));
365 GetFakeHandler()->ExpectOutgoingMessage(message); 397 GetFakeHandler()->ExpectOutgoingMessage(message);
366 mcs_client()->SendMessage(message, true); 398 mcs_client()->SendMessage(message);
367 } 399 }
368 EXPECT_TRUE(GetFakeHandler()-> 400 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
369 AllOutgoingMessagesReceived());
370 401
371 // Rebuild the client, and receive an acknowledgment for the messages as 402 // Rebuild the client, and receive an acknowledgment for the messages as
372 // part of the login response. 403 // part of the login response.
373 BuildMCSClient(); 404 BuildMCSClient();
374 InitializeClient(); 405 InitializeClient();
375 LoginClient(std::vector<std::string>()); 406 LoginClient(std::vector<std::string>());
376 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(id_list)); 407 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(id_list));
377 GetFakeHandler()->ReceiveMessage( 408 GetFakeHandler()->ReceiveMessage(
378 MCSMessage(kIqStanzaTag, 409 MCSMessage(kIqStanzaTag,
379 ack.PassAs<const google::protobuf::MessageLite>())); 410 ack.PassAs<const google::protobuf::MessageLite>()));
380 WaitForMCSEvent(); 411 WaitForMCSEvent();
381 EXPECT_TRUE(GetFakeHandler()-> 412 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
382 AllOutgoingMessagesReceived());
383 } 413 }
384 414
385 // Send messages with RMQ support. On restart, receive a SelectiveAck with 415 // Send messages with RMQ support. On restart, receive a SelectiveAck with
386 // the login response that only acks some messages. The unacked messages should 416 // the login response that only acks some messages. The unacked messages should
387 // be resent. 417 // be resent.
388 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { 418 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) {
389 BuildMCSClient(); 419 BuildMCSClient();
390 InitializeClient(); 420 InitializeClient();
391 LoginClient(std::vector<std::string>()); 421 LoginClient(std::vector<std::string>());
392 422
393 // Send some messages. 423 // Send some messages.
394 std::vector<std::string> id_list; 424 std::vector<std::string> id_list;
395 for (int i = 1; i <= kMessageBatchSize; ++i) { 425 for (int i = 1; i <= kMessageBatchSize; ++i) {
396 id_list.push_back(base::IntToString(i)); 426 id_list.push_back(base::IntToString(i));
397 MCSMessage message( 427 MCSMessage message(
398 BuildDataMessage("from", "category", 1, id_list.back())); 428 BuildDataMessage("from", "category", 1, id_list.back(), kTTLValue, 1));
399 GetFakeHandler()->ExpectOutgoingMessage(message); 429 GetFakeHandler()->ExpectOutgoingMessage(message);
400 mcs_client()->SendMessage(message, true); 430 mcs_client()->SendMessage(message);
401 } 431 }
402 EXPECT_TRUE(GetFakeHandler()-> 432 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
403 AllOutgoingMessagesReceived());
404 433
405 // Rebuild the client, and receive an acknowledgment for the messages as 434 // Rebuild the client, and receive an acknowledgment for the messages as
406 // part of the login response. 435 // part of the login response.
407 BuildMCSClient(); 436 BuildMCSClient();
408 InitializeClient(); 437 InitializeClient();
409 LoginClient(std::vector<std::string>()); 438 LoginClient(std::vector<std::string>());
410 439
411 std::vector<std::string> acked_ids, remaining_ids; 440 std::vector<std::string> acked_ids, remaining_ids;
412 acked_ids.insert(acked_ids.end(), 441 acked_ids.insert(acked_ids.end(),
413 id_list.begin(), 442 id_list.begin(),
414 id_list.begin() + kMessageBatchSize / 2); 443 id_list.begin() + kMessageBatchSize / 2);
415 remaining_ids.insert(remaining_ids.end(), 444 remaining_ids.insert(remaining_ids.end(),
416 id_list.begin() + kMessageBatchSize / 2, 445 id_list.begin() + kMessageBatchSize / 2,
417 id_list.end()); 446 id_list.end());
418 for (int i = 1; i <= kMessageBatchSize / 2; ++i) { 447 for (int i = 1; i <= kMessageBatchSize / 2; ++i) {
419 MCSMessage message( 448 MCSMessage message(
420 BuildDataMessage("from", 449 BuildDataMessage("from",
421 "category", 450 "category",
422 2, 451 2,
423 remaining_ids[i - 1])); 452 remaining_ids[i - 1],
453 kTTLValue,
454 1));
424 GetFakeHandler()->ExpectOutgoingMessage(message); 455 GetFakeHandler()->ExpectOutgoingMessage(message);
425 } 456 }
426 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); 457 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids));
427 GetFakeHandler()->ReceiveMessage( 458 GetFakeHandler()->ReceiveMessage(
428 MCSMessage(kIqStanzaTag, 459 MCSMessage(kIqStanzaTag,
429 ack.PassAs<const google::protobuf::MessageLite>())); 460 ack.PassAs<const google::protobuf::MessageLite>()));
430 WaitForMCSEvent(); 461 WaitForMCSEvent();
431 EXPECT_TRUE(GetFakeHandler()-> 462 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
432 AllOutgoingMessagesReceived());
433 } 463 }
434 464
435 // Receive some messages. On restart, the login request should contain the 465 // Receive some messages. On restart, the login request should contain the
436 // appropriate acknowledged ids. 466 // appropriate acknowledged ids.
437 TEST_F(MCSClientTest, AckOnLogin) { 467 TEST_F(MCSClientTest, AckOnLogin) {
438 BuildMCSClient(); 468 BuildMCSClient();
439 InitializeClient(); 469 InitializeClient();
440 LoginClient(std::vector<std::string>()); 470 LoginClient(std::vector<std::string>());
441 471
442 // Receive some messages. 472 // Receive some messages.
443 std::vector<std::string> id_list; 473 std::vector<std::string> id_list;
444 for (int i = 1; i <= kMessageBatchSize; ++i) { 474 for (int i = 1; i <= kMessageBatchSize; ++i) {
445 id_list.push_back(base::IntToString(i)); 475 id_list.push_back(base::IntToString(i));
446 MCSMessage message( 476 MCSMessage message(
447 BuildDataMessage("from", "category", i, id_list.back())); 477 BuildDataMessage("from", "category", i, id_list.back(), kTTLValue, 1));
448 GetFakeHandler()->ReceiveMessage(message); 478 GetFakeHandler()->ReceiveMessage(message);
449 WaitForMCSEvent(); 479 WaitForMCSEvent();
450 PumpLoop(); 480 PumpLoop();
451 } 481 }
452 482
453 // Restart the client. 483 // Restart the client.
454 BuildMCSClient(); 484 BuildMCSClient();
455 InitializeClient(); 485 InitializeClient();
456 LoginClient(id_list); 486 LoginClient(id_list);
457 } 487 }
458 488
459 // Receive some messages. On the next send, the outgoing message should contain 489 // 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. 490 // the appropriate last stream id received field to ack the received messages.
461 TEST_F(MCSClientTest, AckOnSend) { 491 TEST_F(MCSClientTest, AckOnSend) {
462 BuildMCSClient(); 492 BuildMCSClient();
463 InitializeClient(); 493 InitializeClient();
464 LoginClient(std::vector<std::string>()); 494 LoginClient(std::vector<std::string>());
465 495
466 // Receive some messages. 496 // Receive some messages.
467 std::vector<std::string> id_list; 497 std::vector<std::string> id_list;
468 for (int i = 1; i <= kMessageBatchSize; ++i) { 498 for (int i = 1; i <= kMessageBatchSize; ++i) {
469 id_list.push_back(base::IntToString(i)); 499 id_list.push_back(base::IntToString(i));
470 MCSMessage message( 500 MCSMessage message(
471 BuildDataMessage("from", "category", i, id_list.back())); 501 BuildDataMessage("from", "category", i, id_list.back(), kTTLValue, 1));
472 GetFakeHandler()->ReceiveMessage(message); 502 GetFakeHandler()->ReceiveMessage(message);
473 WaitForMCSEvent(); 503 WaitForMCSEvent();
474 PumpLoop(); 504 PumpLoop();
475 } 505 }
476 506
477 // Trigger a message send, which should acknowledge via stream ack. 507 // Trigger a message send, which should acknowledge via stream ack.
478 MCSMessage message( 508 MCSMessage message(
479 BuildDataMessage("from", "category", kMessageBatchSize + 1, "1")); 509 BuildDataMessage("from",
510 "category",
511 kMessageBatchSize + 1,
512 "1",
513 kTTLValue,
514 1));
480 GetFakeHandler()->ExpectOutgoingMessage(message); 515 GetFakeHandler()->ExpectOutgoingMessage(message);
481 mcs_client()->SendMessage(message, true); 516 mcs_client()->SendMessage(message);
482 EXPECT_TRUE(GetFakeHandler()-> 517 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
483 AllOutgoingMessagesReceived());
484 } 518 }
485 519
486 // Receive the ack limit in messages, which should trigger an automatic 520 // Receive the ack limit in messages, which should trigger an automatic
487 // stream ack. Receive a heartbeat to confirm the ack. 521 // stream ack. Receive a heartbeat to confirm the ack.
488 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { 522 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) {
489 BuildMCSClient(); 523 BuildMCSClient();
490 InitializeClient(); 524 InitializeClient();
491 LoginClient(std::vector<std::string>()); 525 LoginClient(std::vector<std::string>());
492 526
493 // The stream ack. 527 // The stream ack.
494 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); 528 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck();
495 ack->set_last_stream_id_received(kAckLimitSize + 1); 529 ack->set_last_stream_id_received(kAckLimitSize + 1);
496 GetFakeHandler()->ExpectOutgoingMessage( 530 GetFakeHandler()->ExpectOutgoingMessage(
497 MCSMessage(kIqStanzaTag, 531 MCSMessage(kIqStanzaTag,
498 ack.PassAs<const google::protobuf::MessageLite>())); 532 ack.PassAs<const google::protobuf::MessageLite>()));
499 533
500 // Receive some messages. 534 // Receive some messages.
501 std::vector<std::string> id_list; 535 std::vector<std::string> id_list;
502 for (int i = 1; i <= kAckLimitSize; ++i) { 536 for (int i = 1; i <= kAckLimitSize; ++i) {
503 id_list.push_back(base::IntToString(i)); 537 id_list.push_back(base::IntToString(i));
504 MCSMessage message( 538 MCSMessage message(
505 BuildDataMessage("from", "category", i, id_list.back())); 539 BuildDataMessage("from", "category", i, id_list.back(), kTTLValue, 1));
506 GetFakeHandler()->ReceiveMessage(message); 540 GetFakeHandler()->ReceiveMessage(message);
507 WaitForMCSEvent(); 541 WaitForMCSEvent();
508 PumpLoop(); 542 PumpLoop();
509 } 543 }
510 EXPECT_TRUE(GetFakeHandler()-> 544 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
511 AllOutgoingMessagesReceived());
512 545
513 // Receive a heartbeat confirming the ack (and receive the heartbeat ack). 546 // Receive a heartbeat confirming the ack (and receive the heartbeat ack).
514 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat( 547 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat(
515 new mcs_proto::HeartbeatPing()); 548 new mcs_proto::HeartbeatPing());
516 heartbeat->set_last_stream_id_received(2); 549 heartbeat->set_last_stream_id_received(2);
517 550
518 scoped_ptr<mcs_proto::HeartbeatAck> heartbeat_ack( 551 scoped_ptr<mcs_proto::HeartbeatAck> heartbeat_ack(
519 new mcs_proto::HeartbeatAck()); 552 new mcs_proto::HeartbeatAck());
520 heartbeat_ack->set_last_stream_id_received(kAckLimitSize + 2); 553 heartbeat_ack->set_last_stream_id_received(kAckLimitSize + 2);
521 GetFakeHandler()->ExpectOutgoingMessage( 554 GetFakeHandler()->ExpectOutgoingMessage(
522 MCSMessage(kHeartbeatAckTag, 555 MCSMessage(kHeartbeatAckTag,
523 heartbeat_ack.PassAs<const google::protobuf::MessageLite>())); 556 heartbeat_ack.PassAs<const google::protobuf::MessageLite>()));
524 557
525 GetFakeHandler()->ReceiveMessage( 558 GetFakeHandler()->ReceiveMessage(
526 MCSMessage(kHeartbeatPingTag, 559 MCSMessage(kHeartbeatPingTag,
527 heartbeat.PassAs<const google::protobuf::MessageLite>())); 560 heartbeat.PassAs<const google::protobuf::MessageLite>()));
528 WaitForMCSEvent(); 561 WaitForMCSEvent();
529 EXPECT_TRUE(GetFakeHandler()-> 562 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
530 AllOutgoingMessagesReceived());
531 563
532 // Rebuild the client. Nothing should be sent on login. 564 // Rebuild the client. Nothing should be sent on login.
533 BuildMCSClient(); 565 BuildMCSClient();
534 InitializeClient(); 566 InitializeClient();
535 LoginClient(std::vector<std::string>()); 567 LoginClient(std::vector<std::string>());
536 EXPECT_TRUE(GetFakeHandler()-> 568 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
537 AllOutgoingMessagesReceived()); 569 }
570
571 // If a message's TTL has expired by the time it reaches the front of the send
572 // queue, it should be dropped.
573 TEST_F(MCSClientTest, ExpiredTTLOnSend) {
574 BuildMCSClient();
575 InitializeClient();
576 LoginClient(std::vector<std::string>());
577 MCSMessage message(
578 BuildDataMessage("from", "category", 1, "1", kTTLValue, 1));
579
580 // Advance time to after the TTL.
581 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2));
582 EXPECT_TRUE(sent_message_id().empty());
583 mcs_client()->SendMessage(message);
584
585 // No messages should be sent, but the callback should still be invoked.
586 EXPECT_FALSE(sent_message_id().empty());
587 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
588 }
589
590 TEST_F(MCSClientTest, ExpiredTTLOnRestart) {
591 BuildMCSClient();
592 InitializeClient();
593 LoginClient(std::vector<std::string>());
594 GetFakeHandler()->set_fail_send(true);
595 MCSMessage message(
596 BuildDataMessage("from", "category", 1, "1", kTTLValue, 1));
597
598 // The initial (failed) send.
599 GetFakeHandler()->ExpectOutgoingMessage(message);
600 GetFakeHandler()->set_fail_send(false);
601 mcs_client()->SendMessage(message);
602 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
603
604 // Move the clock forward and rebuild the client, which should fail the
605 // message send on restart.
606 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2));
607 BuildMCSClient();
608 InitializeClient();
609 LoginClient(std::vector<std::string>());
610 PumpLoop();
611 EXPECT_FALSE(sent_message_id().empty());
612 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived());
538 } 613 }
539 614
540 } // namespace 615 } // namespace
541 616
542 } // namespace gcm 617 } // namespace gcm
OLDNEW
« no previous file with comments | « google_apis/gcm/engine/mcs_client.cc ('k') | google_apis/gcm/tools/mcs_probe.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698