Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "remoting/host/host_status_sender.h" | |
| 6 | |
| 7 #include "base/strings/string_number_conversions.h" | |
| 8 #include "remoting/base/constants.h" | |
| 9 #include "remoting/base/rsa_key_pair.h" | |
| 10 #include "remoting/base/test_rsa_key_pair.h" | |
| 11 #include "remoting/jingle_glue/mock_objects.h" | |
| 12 #include "testing/gmock/include/gmock/gmock.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | |
| 15 | |
| 16 using buzz::QName; | |
| 17 using buzz::XmlElement; | |
| 18 | |
| 19 using testing::DoAll; | |
| 20 using testing::NotNull; | |
| 21 using testing::Return; | |
| 22 using testing::SaveArg; | |
| 23 | |
| 24 namespace remoting { | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 const char kTestBotJid[] = "remotingunittest@bot.talk.google.com"; | |
| 29 const char kHostId[] = "0"; | |
| 30 const char kTestJid[] = "user@gmail.com/chromoting123"; | |
| 31 const char kStanzaId[] = "123"; | |
| 32 const uint32 kTestExitCode = 100; | |
| 33 const char kTestExitCodeString[] = "100"; | |
| 34 | |
| 35 } // namespace | |
| 36 | |
| 37 class HostStatusSenderTest | |
| 38 : public testing::Test { | |
| 39 protected: | |
| 40 virtual void SetUp() OVERRIDE { | |
| 41 key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair); | |
| 42 ASSERT_TRUE(key_pair_.get()); | |
| 43 | |
| 44 host_status_sender_.reset(new HostStatusSender( | |
| 45 kHostId, &signal_strategy_, key_pair_, kTestBotJid)); | |
| 46 } | |
| 47 | |
| 48 virtual void TearDown() OVERRIDE { | |
| 49 host_status_sender_.reset(); | |
| 50 } | |
| 51 | |
| 52 void ValidateHostStatusStanza(XmlElement* stanza, | |
| 53 HostStatusSender::HostStatus status); | |
| 54 | |
| 55 void ValidateSignature( | |
| 56 XmlElement* signature, HostStatusSender::HostStatus status); | |
| 57 | |
| 58 MockSignalStrategy signal_strategy_; | |
| 59 scoped_refptr<RsaKeyPair> key_pair_; | |
| 60 scoped_ptr<HostStatusSender> host_status_sender_; | |
| 61 }; | |
| 62 | |
| 63 TEST_F(HostStatusSenderTest, SendOnlineStatus) { | |
| 64 XmlElement* sent_iq = NULL; | |
| 65 EXPECT_CALL(signal_strategy_, GetState()) | |
| 66 .WillOnce(Return(SignalStrategy::DISCONNECTED)) | |
| 67 .WillRepeatedly(Return(SignalStrategy::CONNECTED)); | |
| 68 EXPECT_CALL(signal_strategy_, GetLocalJid()) | |
| 69 .WillRepeatedly(Return(kTestJid)); | |
| 70 EXPECT_CALL(signal_strategy_, GetNextId()) | |
| 71 .WillOnce(Return(kStanzaId)); | |
| 72 EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) | |
| 73 .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); | |
| 74 | |
| 75 // Call SendOnlineStatus twice. The first call should be a | |
| 76 // no-op because |signal_strategy_| is diconnected. | |
| 77 // So we expect SendStanza to be called only once. | |
| 78 host_status_sender_->SendOnlineStatus(); | |
| 79 | |
| 80 host_status_sender_->OnSignalStrategyStateChange( | |
| 81 SignalStrategy::CONNECTED); | |
| 82 host_status_sender_->SendOnlineStatus(); | |
| 83 | |
| 84 scoped_ptr<XmlElement> stanza(sent_iq); | |
| 85 | |
| 86 ASSERT_TRUE(stanza != NULL); | |
| 87 LOG(INFO) << stanza->Str(); | |
| 88 | |
| 89 ValidateHostStatusStanza(stanza.get(), HostStatusSender::ONLINE); | |
| 90 } | |
| 91 | |
| 92 TEST_F(HostStatusSenderTest, SendOfflineStatus) { | |
| 93 XmlElement* sent_iq = NULL; | |
| 94 EXPECT_CALL(signal_strategy_, GetState()) | |
| 95 .WillOnce(Return(SignalStrategy::DISCONNECTED)) | |
| 96 .WillRepeatedly(Return(SignalStrategy::CONNECTED)); | |
| 97 EXPECT_CALL(signal_strategy_, GetLocalJid()) | |
| 98 .WillRepeatedly(Return(kTestJid)); | |
| 99 EXPECT_CALL(signal_strategy_, GetNextId()) | |
| 100 .WillOnce(Return(kStanzaId)); | |
| 101 EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) | |
| 102 .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); | |
| 103 | |
| 104 // Call SendOfflineStatus twice. The first call should be a | |
| 105 // no-op because |signal_strategy_| is diconnected. | |
| 106 // So we expect SendStanza to be called only once. | |
| 107 host_status_sender_->SendOfflineStatus(kTestExitCode); | |
| 108 | |
| 109 host_status_sender_->OnSignalStrategyStateChange( | |
| 110 SignalStrategy::CONNECTED); | |
| 111 host_status_sender_->SendOfflineStatus(kTestExitCode); | |
| 112 | |
| 113 scoped_ptr<XmlElement> stanza(sent_iq); | |
| 114 | |
| 115 ASSERT_TRUE(stanza != NULL); | |
| 116 LOG(INFO) << stanza->Str(); | |
| 117 | |
| 118 ValidateHostStatusStanza(stanza.get(), HostStatusSender::OFFLINE); | |
| 119 } | |
| 120 | |
| 121 // Validate a host status stanza. | |
| 122 void HostStatusSenderTest::ValidateHostStatusStanza( | |
| 123 XmlElement* stanza, HostStatusSender::HostStatus status) { | |
| 124 EXPECT_EQ(stanza->Attr(QName(std::string(), "to")), | |
| 125 std::string(kTestBotJid)); | |
| 126 EXPECT_EQ(stanza->Attr(QName(std::string(), "type")), "set"); | |
| 127 | |
| 128 XmlElement* host_status_stanza = | |
| 129 stanza->FirstNamed(QName(kChromotingXmlNamespace, "host-status")); | |
| 130 ASSERT_TRUE(host_status_stanza != NULL); | |
| 131 | |
| 132 if (status == HostStatusSender::ONLINE) | |
| 133 EXPECT_FALSE(host_status_stanza->HasAttr( | |
| 134 QName(kChromotingXmlNamespace, "exit-code"))); | |
| 135 else | |
| 136 EXPECT_EQ(kTestExitCodeString, | |
| 137 host_status_stanza->Attr( | |
| 138 QName(kChromotingXmlNamespace, "exit-code"))); | |
| 139 | |
| 140 EXPECT_EQ(std::string(kHostId), | |
| 141 host_status_stanza->Attr( | |
| 142 QName(kChromotingXmlNamespace, "hostid"))); | |
| 143 | |
| 144 QName signature_tag(kChromotingXmlNamespace, "signature"); | |
| 145 XmlElement* signature = host_status_stanza->FirstNamed(signature_tag); | |
| 146 ASSERT_TRUE(signature != NULL); | |
| 147 EXPECT_TRUE(host_status_stanza->NextNamed(signature_tag) == NULL); | |
| 148 | |
| 149 ValidateSignature(signature, status); | |
| 150 } | |
| 151 | |
| 152 // Validate the signature. | |
| 153 void HostStatusSenderTest::ValidateSignature( | |
| 154 XmlElement* signature, HostStatusSender::HostStatus status) { | |
| 155 | |
| 156 std::string time_str = | |
| 157 signature->Attr(QName(kChromotingXmlNamespace, "time")); | |
| 158 | |
| 159 std::string message; | |
| 160 message += kTestJid; | |
| 161 message += " "; | |
| 162 message += time_str; | |
| 163 message += " "; | |
| 164 message += base::IntToString(status); | |
| 165 | |
| 166 if (status == HostStatusSender::OFFLINE) { | |
| 167 message += " "; | |
| 168 message += kTestExitCodeString; | |
| 169 } | |
| 170 | |
| 171 scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::FromString(kTestRsaKeyPair); | |
| 172 ASSERT_TRUE(key_pair.get()); | |
| 173 | |
| 174 std::string expected_signature = | |
| 175 key_pair->SignMessage(message); | |
| 176 EXPECT_EQ(expected_signature, signature->BodyText()); | |
| 177 | |
| 178 // Number of seconds since epoch (Jan 1, 1970). | |
| 179 int64 time; | |
| 180 ASSERT_TRUE(base::StringToInt64(time_str, &time)); | |
| 181 int64 now = static_cast<int64>(base::Time::Now().ToDoubleT()); | |
| 182 | |
| 183 // For a unit test SendHostStatus and the validation should complete in | |
|
rmsousa
2013/07/04 01:20:14
You shouldn't depend on real wallclock timing in u
weitao
2013/07/09 00:37:40
Done.
| |
| 184 // less than 1 seconds (on my machine it took ~0.005 second). | |
| 185 LOG(INFO) << "SendHostStatus took " << now - time << " seconds."; | |
| 186 EXPECT_LE(now - time, 1); | |
| 187 | |
| 188 } | |
| 189 | |
| 190 } // namespace remoting | |
| OLD | NEW |