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 |