Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / remoting / host / log_to_server_unittest.cc
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