OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/message_loop/message_loop.h" | |
6 #include "base/message_loop/message_loop_proxy.h" | |
7 #include "remoting/host/host_status_monitor_fake.h" | |
8 #include "remoting/host/log_to_server.h" | |
9 #include "remoting/jingle_glue/mock_objects.h" | |
10 #include "testing/gmock/include/gmock/gmock.h" | |
11 #include "testing/gmock_mutant.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | |
14 | |
15 using buzz::XmlElement; | |
16 using buzz::QName; | |
17 using testing::_; | |
18 using testing::DeleteArg; | |
19 using testing::InSequence; | |
20 using testing::Return; | |
21 | |
22 namespace remoting { | |
23 | |
24 namespace { | |
25 | |
26 ACTION_P(QuitMainMessageLoop, message_loop) { | |
27 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | |
28 } | |
29 | |
30 const char kJabberClientNamespace[] = "jabber:client"; | |
31 const char kChromotingNamespace[] = "google:remoting"; | |
32 const char kTestBotJid[] = "remotingunittest@bot.talk.google.com"; | |
33 const char kClientJid1[] = "client@domain.com/1234"; | |
34 const char kClientJid2[] = "client@domain.com/5678"; | |
35 const char kHostJid[] = "host@domain.com/1234"; | |
36 | |
37 bool IsLogEntryForConnection(XmlElement* node, const char* connection_type) { | |
38 return (node->Name() == QName(kChromotingNamespace, "entry") && | |
39 node->Attr(QName(std::string(), "event-name")) == "session-state" && | |
40 node->Attr(QName(std::string(), "session-state")) == "connected" && | |
41 node->Attr(QName(std::string(), "role")) == "host" && | |
42 node->Attr(QName(std::string(), "mode")) == "me2me" && | |
43 node->Attr(QName(std::string(), "connection-type")) == | |
44 connection_type); | |
45 } | |
46 | |
47 MATCHER_P(IsClientConnected, connection_type, "") { | |
48 if (arg->Name() != QName(kJabberClientNamespace, "iq")) { | |
49 return false; | |
50 } | |
51 buzz::XmlElement* log_stanza = arg->FirstChild()->AsElement(); | |
52 if (log_stanza->Name() !=QName(kChromotingNamespace, "log")) { | |
53 return false; | |
54 } | |
55 if (log_stanza->NextChild()) { | |
56 return false; | |
57 } | |
58 buzz::XmlElement* log_entry = log_stanza->FirstChild()->AsElement(); | |
59 if (!IsLogEntryForConnection(log_entry, connection_type)) { | |
60 return false; | |
61 } | |
62 if (log_entry->NextChild()) { | |
63 return false; | |
64 } | |
65 return true; | |
66 } | |
67 | |
68 MATCHER_P2(IsTwoClientsConnected, connection_type1, connection_type2, "") { | |
69 if (arg->Name() != QName(kJabberClientNamespace, "iq")) { | |
70 return false; | |
71 } | |
72 buzz::XmlElement* log_stanza = arg->FirstChild()->AsElement(); | |
73 if (log_stanza->Name() !=QName(kChromotingNamespace, "log")) { | |
74 return false; | |
75 } | |
76 if (log_stanza->NextChild()) { | |
77 return false; | |
78 } | |
79 buzz::XmlElement* log_entry = log_stanza->FirstChild()->AsElement(); | |
80 if (!IsLogEntryForConnection(log_entry, connection_type1)) { | |
81 return false; | |
82 } | |
83 log_entry = log_entry->NextChild()->AsElement(); | |
84 if (!IsLogEntryForConnection(log_entry, connection_type2)) { | |
85 return false; | |
86 } | |
87 if (log_entry->NextChild()) { | |
88 return false; | |
89 } | |
90 return true; | |
91 } | |
92 | |
93 bool IsLogEntryForDisconnection(XmlElement* node) { | |
94 return (node->Name() == QName(kChromotingNamespace, "entry") && | |
95 node->Attr(QName(std::string(), "event-name")) == "session-state" && | |
96 node->Attr(QName(std::string(), "session-state")) == "closed" && | |
97 node->Attr(QName(std::string(), "role")) == "host" && | |
98 node->Attr(QName(std::string(), "mode")) == "me2me"); | |
99 } | |
100 | |
101 MATCHER(IsClientDisconnected, "") { | |
102 if (arg->Name() != QName(kJabberClientNamespace, "iq")) { | |
103 return false; | |
104 } | |
105 buzz::XmlElement* log_stanza = arg->FirstChild()->AsElement(); | |
106 if (log_stanza->Name() !=QName(kChromotingNamespace, "log")) { | |
107 return false; | |
108 } | |
109 if (log_stanza->NextChild()) { | |
110 return false; | |
111 } | |
112 buzz::XmlElement* log_entry = log_stanza->FirstChild()->AsElement(); | |
113 if (!IsLogEntryForDisconnection(log_entry)) { | |
114 return false; | |
115 } | |
116 if (log_entry->NextChild()) { | |
117 return false; | |
118 } | |
119 return true; | |
120 } | |
121 | |
122 } // namespace | |
123 | |
124 class LogToServerTest : public testing::Test { | |
125 public: | |
126 LogToServerTest() {} | |
127 virtual void SetUp() OVERRIDE { | |
128 message_loop_proxy_ = base::MessageLoopProxy::current(); | |
129 EXPECT_CALL(signal_strategy_, AddListener(_)); | |
130 log_to_server_.reset( | |
131 new LogToServer(host_status_monitor_.AsWeakPtr(), | |
132 ServerLogEntry::ME2ME, | |
133 &signal_strategy_, | |
134 kTestBotJid)); | |
135 EXPECT_CALL(signal_strategy_, RemoveListener(_)); | |
136 } | |
137 | |
138 protected: | |
139 base::MessageLoop message_loop_; | |
140 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
141 MockSignalStrategy signal_strategy_; | |
142 scoped_ptr<LogToServer> log_to_server_; | |
143 HostStatusMonitorFake host_status_monitor_; | |
144 }; | |
145 | |
146 TEST_F(LogToServerTest, SendNow) { | |
147 { | |
148 InSequence s; | |
149 EXPECT_CALL(signal_strategy_, GetLocalJid()) | |
150 .WillRepeatedly(Return(kHostJid)); | |
151 EXPECT_CALL(signal_strategy_, AddListener(_)); | |
152 EXPECT_CALL(signal_strategy_, GetNextId()); | |
153 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientConnected("direct"))) | |
154 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); | |
155 EXPECT_CALL(signal_strategy_, RemoveListener(_)) | |
156 .WillOnce(QuitMainMessageLoop(&message_loop_)) | |
157 .RetiresOnSaturation(); | |
158 } | |
159 log_to_server_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); | |
160 protocol::TransportRoute route; | |
161 route.type = protocol::TransportRoute::DIRECT; | |
162 log_to_server_->OnClientRouteChange(kClientJid1, "video", route); | |
163 log_to_server_->OnClientAuthenticated(kClientJid1); | |
164 log_to_server_->OnClientConnected(kClientJid1); | |
165 log_to_server_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED); | |
166 message_loop_.Run(); | |
167 } | |
168 | |
169 TEST_F(LogToServerTest, SendLater) { | |
170 protocol::TransportRoute route; | |
171 route.type = protocol::TransportRoute::DIRECT; | |
172 log_to_server_->OnClientRouteChange(kClientJid1, "video", route); | |
173 log_to_server_->OnClientAuthenticated(kClientJid1); | |
174 log_to_server_->OnClientConnected(kClientJid1); | |
175 { | |
176 InSequence s; | |
177 EXPECT_CALL(signal_strategy_, GetLocalJid()) | |
178 .WillRepeatedly(Return(kHostJid)); | |
179 EXPECT_CALL(signal_strategy_, AddListener(_)); | |
180 EXPECT_CALL(signal_strategy_, GetNextId()); | |
181 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientConnected("direct"))) | |
182 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); | |
183 EXPECT_CALL(signal_strategy_, RemoveListener(_)) | |
184 .WillOnce(QuitMainMessageLoop(&message_loop_)) | |
185 .RetiresOnSaturation(); | |
186 } | |
187 log_to_server_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); | |
188 log_to_server_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED); | |
189 message_loop_.Run(); | |
190 } | |
191 | |
192 TEST_F(LogToServerTest, SendTwoEntriesLater) { | |
193 protocol::TransportRoute route1; | |
194 route1.type = protocol::TransportRoute::DIRECT; | |
195 log_to_server_->OnClientRouteChange(kClientJid1, "video", route1); | |
196 log_to_server_->OnClientAuthenticated(kClientJid1); | |
197 log_to_server_->OnClientConnected(kClientJid1); | |
198 protocol::TransportRoute route2; | |
199 route2.type = protocol::TransportRoute::STUN; | |
200 log_to_server_->OnClientRouteChange(kClientJid2, "video", route2); | |
201 log_to_server_->OnClientAuthenticated(kClientJid2); | |
202 log_to_server_->OnClientConnected(kClientJid2); | |
203 { | |
204 InSequence s; | |
205 EXPECT_CALL(signal_strategy_, GetLocalJid()) | |
206 .WillRepeatedly(Return(kHostJid)); | |
207 EXPECT_CALL(signal_strategy_, AddListener(_)); | |
208 EXPECT_CALL(signal_strategy_, GetNextId()); | |
209 EXPECT_CALL(signal_strategy_, SendStanzaPtr( | |
210 IsTwoClientsConnected("direct", "stun"))) | |
211 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); | |
212 EXPECT_CALL(signal_strategy_, RemoveListener(_)) | |
213 .WillOnce(QuitMainMessageLoop(&message_loop_)) | |
214 .RetiresOnSaturation(); | |
215 } | |
216 log_to_server_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); | |
217 log_to_server_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED); | |
218 message_loop_.Run(); | |
219 } | |
220 | |
221 TEST_F(LogToServerTest, HandleRouteChangeInUnusualOrder) { | |
222 { | |
223 InSequence s; | |
224 EXPECT_CALL(signal_strategy_, GetLocalJid()) | |
225 .WillRepeatedly(Return(kHostJid)); | |
226 EXPECT_CALL(signal_strategy_, AddListener(_)); | |
227 EXPECT_CALL(signal_strategy_, GetNextId()); | |
228 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientConnected("direct"))) | |
229 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); | |
230 EXPECT_CALL(signal_strategy_, GetNextId()); | |
231 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientDisconnected())) | |
232 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); | |
233 EXPECT_CALL(signal_strategy_, GetNextId()); | |
234 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientConnected("stun"))) | |
235 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); | |
236 EXPECT_CALL(signal_strategy_, RemoveListener(_)) | |
237 .WillOnce(QuitMainMessageLoop(&message_loop_)) | |
238 .RetiresOnSaturation(); | |
239 } | |
240 log_to_server_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED); | |
241 protocol::TransportRoute route1; | |
242 route1.type = protocol::TransportRoute::DIRECT; | |
243 log_to_server_->OnClientRouteChange(kClientJid1, "video", route1); | |
244 log_to_server_->OnClientAuthenticated(kClientJid1); | |
245 log_to_server_->OnClientConnected(kClientJid1); | |
246 protocol::TransportRoute route2; | |
247 route2.type = protocol::TransportRoute::STUN; | |
248 log_to_server_->OnClientRouteChange(kClientJid2, "video", route2); | |
249 log_to_server_->OnClientDisconnected(kClientJid1); | |
250 log_to_server_->OnClientAuthenticated(kClientJid2); | |
251 log_to_server_->OnClientConnected(kClientJid2); | |
252 log_to_server_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED); | |
253 message_loop_.Run(); | |
254 } | |
255 | |
256 } // namespace remoting | |
OLD | NEW |