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