| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "remoting/host/heartbeat_sender.h" | 5 #include "remoting/host/heartbeat_sender.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 | 34 |
| 35 namespace remoting { | 35 namespace remoting { |
| 36 | 36 |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 const char kTestBotJid[] = "remotingunittest@bot.talk.google.com"; | 39 const char kTestBotJid[] = "remotingunittest@bot.talk.google.com"; |
| 40 const char kHostId[] = "0"; | 40 const char kHostId[] = "0"; |
| 41 const char kTestJid[] = "User@gmail.com/chromotingABC123"; | 41 const char kTestJid[] = "User@gmail.com/chromotingABC123"; |
| 42 const char kTestJidNormalized[] = "user@gmail.com/chromotingABC123"; | 42 const char kTestJidNormalized[] = "user@gmail.com/chromotingABC123"; |
| 43 const char kStanzaId[] = "123"; | 43 const char kStanzaId[] = "123"; |
| 44 const int kTestInterval = 123; | 44 constexpr base::TimeDelta kTestInterval = base::TimeDelta::FromSeconds(123); |
| 45 const base::TimeDelta kTestTimeout = base::TimeDelta::FromSeconds(123); | 45 constexpr base::TimeDelta kOfflineReasonTimeout = |
| 46 base::TimeDelta::FromSeconds(123); |
| 46 | 47 |
| 47 } // namespace | 48 } // namespace |
| 48 | 49 |
| 49 ACTION_P(AddListener, list) { | 50 ACTION_P(AddListener, list) { |
| 50 list->insert(arg0); | 51 list->insert(arg0); |
| 51 } | 52 } |
| 52 ACTION_P(RemoveListener, list) { | 53 ACTION_P(RemoveListener, list) { |
| 53 EXPECT_TRUE(list->find(arg0) != list->end()); | 54 EXPECT_TRUE(list->find(arg0) != list->end()); |
| 54 list->erase(arg0); | 55 list->erase(arg0); |
| 55 } | 56 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 79 | 80 |
| 80 void TearDown() override { | 81 void TearDown() override { |
| 81 heartbeat_sender_.reset(); | 82 heartbeat_sender_.reset(); |
| 82 EXPECT_TRUE(signal_strategy_listeners_.empty()); | 83 EXPECT_TRUE(signal_strategy_listeners_.empty()); |
| 83 } | 84 } |
| 84 | 85 |
| 85 void ValidateHeartbeatStanza(XmlElement* stanza, | 86 void ValidateHeartbeatStanza(XmlElement* stanza, |
| 86 const char* expected_sequence_id, | 87 const char* expected_sequence_id, |
| 87 const char* expected_host_offline_reason); | 88 const char* expected_host_offline_reason); |
| 88 | 89 |
| 89 void ProcessResponseWithInterval( | 90 void ProcessResponseWithInterval(bool is_offline_heartbeat_response, |
| 90 bool is_offline_heartbeat_response, | 91 base::TimeDelta interval); |
| 91 int interval); | |
| 92 | 92 |
| 93 base::MessageLoop message_loop_; | 93 base::MessageLoop message_loop_; |
| 94 MockSignalStrategy signal_strategy_; | 94 MockSignalStrategy signal_strategy_; |
| 95 base::MockCallback<base::Closure> mock_heartbeat_successful_callback_; | 95 base::MockCallback<base::Closure> mock_heartbeat_successful_callback_; |
| 96 base::MockCallback<base::Closure> mock_unknown_host_id_error_callback_; | 96 base::MockCallback<base::Closure> mock_unknown_host_id_error_callback_; |
| 97 std::set<SignalStrategy::Listener*> signal_strategy_listeners_; | 97 std::set<SignalStrategy::Listener*> signal_strategy_listeners_; |
| 98 scoped_refptr<RsaKeyPair> key_pair_; | 98 scoped_refptr<RsaKeyPair> key_pair_; |
| 99 std::unique_ptr<HeartbeatSender> heartbeat_sender_; | 99 std::unique_ptr<HeartbeatSender> heartbeat_sender_; |
| 100 }; | 100 }; |
| 101 | 101 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 ValidateHeartbeatStanza(stanza2.get(), | 199 ValidateHeartbeatStanza(stanza2.get(), |
| 200 base::IntToString(kExpectedSequenceId).c_str(), | 200 base::IntToString(kExpectedSequenceId).c_str(), |
| 201 nullptr); | 201 nullptr); |
| 202 | 202 |
| 203 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED); | 203 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED); |
| 204 base::RunLoop().RunUntilIdle(); | 204 base::RunLoop().RunUntilIdle(); |
| 205 } | 205 } |
| 206 | 206 |
| 207 void HeartbeatSenderTest::ProcessResponseWithInterval( | 207 void HeartbeatSenderTest::ProcessResponseWithInterval( |
| 208 bool is_offline_heartbeat_response, | 208 bool is_offline_heartbeat_response, |
| 209 int interval) { | 209 base::TimeDelta interval) { |
| 210 std::unique_ptr<XmlElement> response(new XmlElement(buzz::QN_IQ)); | 210 std::unique_ptr<XmlElement> response(new XmlElement(buzz::QN_IQ)); |
| 211 response->AddAttr(QName(std::string(), "type"), "result"); | 211 response->AddAttr(QName(std::string(), "type"), "result"); |
| 212 | 212 |
| 213 XmlElement* result = new XmlElement( | 213 XmlElement* result = new XmlElement( |
| 214 QName(kChromotingXmlNamespace, "heartbeat-result")); | 214 QName(kChromotingXmlNamespace, "heartbeat-result")); |
| 215 response->AddElement(result); | 215 response->AddElement(result); |
| 216 | 216 |
| 217 XmlElement* set_interval = new XmlElement( | 217 XmlElement* set_interval = new XmlElement( |
| 218 QName(kChromotingXmlNamespace, "set-interval")); | 218 QName(kChromotingXmlNamespace, "set-interval")); |
| 219 result->AddElement(set_interval); | 219 result->AddElement(set_interval); |
| 220 | 220 |
| 221 set_interval->AddText(base::IntToString(interval)); | 221 set_interval->AddText(base::IntToString(interval.InSeconds())); |
| 222 | 222 |
| 223 heartbeat_sender_->ProcessResponse( | 223 heartbeat_sender_->ProcessResponse( |
| 224 is_offline_heartbeat_response, nullptr, response.get()); | 224 is_offline_heartbeat_response, nullptr, response.get()); |
| 225 } | 225 } |
| 226 | 226 |
| 227 // Verify that ProcessResponse parses set-interval result. | 227 // Verify that ProcessResponse parses set-interval result. |
| 228 TEST_F(HeartbeatSenderTest, ProcessResponseSetInterval) { | 228 TEST_F(HeartbeatSenderTest, ProcessResponseSetInterval) { |
| 229 EXPECT_CALL(mock_heartbeat_successful_callback_, Run()); | 229 EXPECT_CALL(mock_heartbeat_successful_callback_, Run()); |
| 230 | 230 |
| 231 ProcessResponseWithInterval(false, kTestInterval); | 231 ProcessResponseWithInterval(false, kTestInterval); |
| 232 | 232 |
| 233 EXPECT_EQ(kTestInterval * 1000, heartbeat_sender_->interval_ms_); | 233 EXPECT_EQ(kTestInterval, heartbeat_sender_->interval_); |
| 234 } | 234 } |
| 235 | 235 |
| 236 // Make sure SetHostOfflineReason sends a correct stanza. | 236 // Make sure SetHostOfflineReason sends a correct stanza. |
| 237 TEST_F(HeartbeatSenderTest, DoSetHostOfflineReason) { | 237 TEST_F(HeartbeatSenderTest, DoSetHostOfflineReason) { |
| 238 XmlElement* sent_iq = nullptr; | 238 XmlElement* sent_iq = nullptr; |
| 239 base::MockCallback<base::Callback<void(bool success)>> mock_ack_callback; | 239 base::MockCallback<base::Callback<void(bool success)>> mock_ack_callback; |
| 240 | 240 |
| 241 EXPECT_CALL(signal_strategy_, GetNextId()) | 241 EXPECT_CALL(signal_strategy_, GetNextId()) |
| 242 .WillOnce(Return(kStanzaId)); | 242 .WillOnce(Return(kStanzaId)); |
| 243 EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) | 243 EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) |
| 244 .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); | 244 .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); |
| 245 EXPECT_CALL(signal_strategy_, GetState()) | 245 EXPECT_CALL(signal_strategy_, GetState()) |
| 246 .WillOnce(Return(SignalStrategy::DISCONNECTED)) | 246 .WillOnce(Return(SignalStrategy::DISCONNECTED)) |
| 247 .WillRepeatedly(Return(SignalStrategy::CONNECTED)); | 247 .WillRepeatedly(Return(SignalStrategy::CONNECTED)); |
| 248 EXPECT_CALL(mock_ack_callback, Run(_)).Times(0); | 248 EXPECT_CALL(mock_ack_callback, Run(_)).Times(0); |
| 249 | 249 |
| 250 heartbeat_sender_->SetHostOfflineReason("test_error", kTestTimeout, | 250 heartbeat_sender_->SetHostOfflineReason("test_error", kOfflineReasonTimeout, |
| 251 mock_ack_callback.Get()); | 251 mock_ack_callback.Get()); |
| 252 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); | 252 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); |
| 253 base::RunLoop().RunUntilIdle(); | 253 base::RunLoop().RunUntilIdle(); |
| 254 | 254 |
| 255 std::unique_ptr<XmlElement> stanza(sent_iq); | 255 std::unique_ptr<XmlElement> stanza(sent_iq); |
| 256 ASSERT_TRUE(stanza != nullptr); | 256 ASSERT_TRUE(stanza != nullptr); |
| 257 ValidateHeartbeatStanza(stanza.get(), "0", "test_error"); | 257 ValidateHeartbeatStanza(stanza.get(), "0", "test_error"); |
| 258 | 258 |
| 259 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED); | 259 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED); |
| 260 base::RunLoop().RunUntilIdle(); | 260 base::RunLoop().RunUntilIdle(); |
| 261 } | 261 } |
| 262 | 262 |
| 263 // Make sure SetHostOfflineReason triggers a callback when bot responds. | 263 // Make sure SetHostOfflineReason triggers a callback when bot responds. |
| 264 TEST_F(HeartbeatSenderTest, ProcessHostOfflineResponses) { | 264 TEST_F(HeartbeatSenderTest, ProcessHostOfflineResponses) { |
| 265 base::MockCallback<base::Callback<void(bool success)>> mock_ack_callback; | 265 base::MockCallback<base::Callback<void(bool success)>> mock_ack_callback; |
| 266 | 266 |
| 267 EXPECT_CALL(signal_strategy_, GetNextId()) | 267 EXPECT_CALL(signal_strategy_, GetNextId()) |
| 268 .WillOnce(Return(kStanzaId)); | 268 .WillOnce(Return(kStanzaId)); |
| 269 EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) | 269 EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) |
| 270 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); | 270 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); |
| 271 EXPECT_CALL(signal_strategy_, GetState()) | 271 EXPECT_CALL(signal_strategy_, GetState()) |
| 272 .WillOnce(Return(SignalStrategy::DISCONNECTED)) | 272 .WillOnce(Return(SignalStrategy::DISCONNECTED)) |
| 273 .WillRepeatedly(Return(SignalStrategy::CONNECTED)); | 273 .WillRepeatedly(Return(SignalStrategy::CONNECTED)); |
| 274 EXPECT_CALL(mock_heartbeat_successful_callback_, Run()) | 274 EXPECT_CALL(mock_heartbeat_successful_callback_, Run()) |
| 275 .WillRepeatedly(Return()); | 275 .WillRepeatedly(Return()); |
| 276 | 276 |
| 277 // Callback should not run, until response to offline-reason. | 277 // Callback should not run, until response to offline-reason. |
| 278 EXPECT_CALL(mock_ack_callback, Run(_)).Times(0); | 278 EXPECT_CALL(mock_ack_callback, Run(_)).Times(0); |
| 279 | 279 |
| 280 heartbeat_sender_->SetHostOfflineReason("test_error", kTestTimeout, | 280 heartbeat_sender_->SetHostOfflineReason("test_error", kOfflineReasonTimeout, |
| 281 mock_ack_callback.Get()); | 281 mock_ack_callback.Get()); |
| 282 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); | 282 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); |
| 283 base::RunLoop().RunUntilIdle(); | 283 base::RunLoop().RunUntilIdle(); |
| 284 | 284 |
| 285 ProcessResponseWithInterval( | 285 ProcessResponseWithInterval( |
| 286 false, // <- This is not a response to offline-reason. | 286 false, // <- This is not a response to offline-reason. |
| 287 kTestInterval); | 287 kTestInterval); |
| 288 base::RunLoop().RunUntilIdle(); | 288 base::RunLoop().RunUntilIdle(); |
| 289 | 289 |
| 290 // Callback should run once, when we get response to offline-reason. | 290 // Callback should run once, when we get response to offline-reason. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 ASSERT_TRUE(signature != nullptr); | 365 ASSERT_TRUE(signature != nullptr); |
| 366 EXPECT_TRUE(heartbeat_stanza->NextNamed(signature_tag) == nullptr); | 366 EXPECT_TRUE(heartbeat_stanza->NextNamed(signature_tag) == nullptr); |
| 367 | 367 |
| 368 scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::FromString(kTestRsaKeyPair); | 368 scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::FromString(kTestRsaKeyPair); |
| 369 ASSERT_TRUE(key_pair.get()); | 369 ASSERT_TRUE(key_pair.get()); |
| 370 std::string expected_signature = key_pair->SignMessage( | 370 std::string expected_signature = key_pair->SignMessage( |
| 371 std::string(kTestJidNormalized) + ' ' + expected_sequence_id); | 371 std::string(kTestJidNormalized) + ' ' + expected_sequence_id); |
| 372 EXPECT_EQ(expected_signature, signature->BodyText()); | 372 EXPECT_EQ(expected_signature, signature->BodyText()); |
| 373 } | 373 } |
| 374 | 374 |
| 375 TEST_F(HeartbeatSenderTest, ResponseTimeout) { |
| 376 XmlElement* sent_iq = nullptr; |
| 377 EXPECT_CALL(signal_strategy_, GetNextId()).WillOnce(Return(kStanzaId)); |
| 378 EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) |
| 379 .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); |
| 380 EXPECT_CALL(signal_strategy_, GetState()) |
| 381 .WillRepeatedly(Return(SignalStrategy::CONNECTED)); |
| 382 |
| 383 heartbeat_sender_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); |
| 384 base::RunLoop().RunUntilIdle(); |
| 385 |
| 386 std::unique_ptr<XmlElement> stanza(sent_iq); |
| 387 ASSERT_TRUE(stanza); |
| 388 |
| 389 XmlElement* sent_iq2 = nullptr; |
| 390 EXPECT_CALL(signal_strategy_, GetNextId()).WillOnce(Return(kStanzaId + 1)); |
| 391 EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) |
| 392 .WillOnce(DoAll(SaveArg<0>(&sent_iq2), Return(true))); |
| 393 |
| 394 heartbeat_sender_->ProcessResponse(false, nullptr, nullptr /* timeout */); |
| 395 heartbeat_sender_->DoSendStanza(); |
| 396 base::RunLoop().RunUntilIdle(); |
| 397 |
| 398 std::unique_ptr<XmlElement> stanza2(sent_iq2); |
| 399 ASSERT_TRUE(stanza2); |
| 400 |
| 401 EXPECT_CALL(signal_strategy_, Disconnect()); |
| 402 heartbeat_sender_->ProcessResponse(false, nullptr, nullptr /* timeout */); |
| 403 } |
| 404 |
| 375 } // namespace remoting | 405 } // namespace remoting |
| OLD | NEW |