blob: 6b24ccf7d60fe6d9fde7392666091353fdaf4f2c [file] [log] [blame]
[email protected]71f76c52014-07-10 00:36:051// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]00c794a2011-11-22 22:48:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]71f76c52014-07-10 00:36:055#include "remoting/host/host_status_logger.h"
6
[email protected]f368eeb2013-07-17 23:53:327#include "base/message_loop/message_loop.h"
fdoray2ad58be2016-06-22 20:36:168#include "base/run_loop.h"
[email protected]a4b4fe52014-07-17 23:42:499#include "remoting/host/fake_host_status_monitor.h"
[email protected]fd0ca112014-07-17 06:10:2010#include "remoting/signaling/mock_signal_strategy.h"
[email protected]00c794a2011-11-22 22:48:5511#include "testing/gmock/include/gmock/gmock.h"
[email protected]9cfb0c32013-03-02 04:27:4912#include "testing/gmock_mutant.h"
[email protected]00c794a2011-11-22 22:48:5513#include "testing/gtest/include/gtest/gtest.h"
niklaseaf726f12014-09-08 18:43:0214#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
[email protected]00c794a2011-11-22 22:48:5515
[email protected]b67b3952012-05-25 00:43:5816using buzz::XmlElement;
17using buzz::QName;
[email protected]00c794a2011-11-22 22:48:5518using testing::_;
[email protected]02f2de62011-11-23 03:45:1119using testing::DeleteArg;
[email protected]00c794a2011-11-22 22:48:5520using testing::InSequence;
[email protected]02f2de62011-11-23 03:45:1121using testing::Return;
[email protected]00c794a2011-11-22 22:48:5522
23namespace remoting {
24
25namespace {
26
fdoray2df4a9e2016-07-18 23:47:1627ACTION_P(QuitRunLoop, run_loop) {
28 run_loop->QuitWhenIdle();
[email protected]00c794a2011-11-22 22:48:5529}
30
[email protected]b67b3952012-05-25 00:43:5831const char kJabberClientNamespace[] = "jabber:client";
32const char kChromotingNamespace[] = "google:remoting";
[email protected]6583ed62013-02-05 07:31:0533const char kTestBotJid[] = "[email protected]";
[email protected]b67b3952012-05-25 00:43:5834const char kClientJid1[] = "[email protected]/1234";
35const char kClientJid2[] = "[email protected]/5678";
36const char kHostJid[] = "[email protected]/1234";
37
38bool IsLogEntryForConnection(XmlElement* node, const char* connection_type) {
39 return (node->Name() == QName(kChromotingNamespace, "entry") &&
[email protected]007b3f82013-04-09 08:46:4540 node->Attr(QName(std::string(), "event-name")) == "session-state" &&
41 node->Attr(QName(std::string(), "session-state")) == "connected" &&
42 node->Attr(QName(std::string(), "role")) == "host" &&
43 node->Attr(QName(std::string(), "mode")) == "me2me" &&
44 node->Attr(QName(std::string(), "connection-type")) ==
45 connection_type);
[email protected]b67b3952012-05-25 00:43:5846}
47
48MATCHER_P(IsClientConnected, connection_type, "") {
49 if (arg->Name() != QName(kJabberClientNamespace, "iq")) {
50 return false;
51 }
52 buzz::XmlElement* log_stanza = arg->FirstChild()->AsElement();
[email protected]71f76c52014-07-10 00:36:0553 if (log_stanza->Name() != QName(kChromotingNamespace, "log")) {
[email protected]b67b3952012-05-25 00:43:5854 return false;
55 }
56 if (log_stanza->NextChild()) {
57 return false;
58 }
59 buzz::XmlElement* log_entry = log_stanza->FirstChild()->AsElement();
60 if (!IsLogEntryForConnection(log_entry, connection_type)) {
61 return false;
62 }
63 if (log_entry->NextChild()) {
64 return false;
65 }
66 return true;
67}
68
69MATCHER_P2(IsTwoClientsConnected, connection_type1, connection_type2, "") {
70 if (arg->Name() != QName(kJabberClientNamespace, "iq")) {
71 return false;
72 }
73 buzz::XmlElement* log_stanza = arg->FirstChild()->AsElement();
[email protected]71f76c52014-07-10 00:36:0574 if (log_stanza->Name() != QName(kChromotingNamespace, "log")) {
[email protected]b67b3952012-05-25 00:43:5875 return false;
76 }
77 if (log_stanza->NextChild()) {
78 return false;
79 }
80 buzz::XmlElement* log_entry = log_stanza->FirstChild()->AsElement();
81 if (!IsLogEntryForConnection(log_entry, connection_type1)) {
82 return false;
83 }
84 log_entry = log_entry->NextChild()->AsElement();
85 if (!IsLogEntryForConnection(log_entry, connection_type2)) {
86 return false;
87 }
88 if (log_entry->NextChild()) {
89 return false;
90 }
91 return true;
92}
93
94bool IsLogEntryForDisconnection(XmlElement* node) {
95 return (node->Name() == QName(kChromotingNamespace, "entry") &&
[email protected]007b3f82013-04-09 08:46:4596 node->Attr(QName(std::string(), "event-name")) == "session-state" &&
97 node->Attr(QName(std::string(), "session-state")) == "closed" &&
98 node->Attr(QName(std::string(), "role")) == "host" &&
99 node->Attr(QName(std::string(), "mode")) == "me2me");
[email protected]b67b3952012-05-25 00:43:58100}
101
102MATCHER(IsClientDisconnected, "") {
103 if (arg->Name() != QName(kJabberClientNamespace, "iq")) {
104 return false;
105 }
106 buzz::XmlElement* log_stanza = arg->FirstChild()->AsElement();
107 if (log_stanza->Name() !=QName(kChromotingNamespace, "log")) {
108 return false;
109 }
110 if (log_stanza->NextChild()) {
111 return false;
112 }
113 buzz::XmlElement* log_entry = log_stanza->FirstChild()->AsElement();
114 if (!IsLogEntryForDisconnection(log_entry)) {
115 return false;
116 }
117 if (log_entry->NextChild()) {
118 return false;
119 }
120 return true;
121}
122
[email protected]00c794a2011-11-22 22:48:55123} // namespace
124
[email protected]71f76c52014-07-10 00:36:05125class HostStatusLoggerTest : public testing::Test {
[email protected]00c794a2011-11-22 22:48:55126 public:
[email protected]71f76c52014-07-10 00:36:05127 HostStatusLoggerTest() {}
dcheng440d8e1c2014-10-28 01:23:15128 void SetUp() override {
[email protected]988dfc3c2012-01-04 01:10:11129 EXPECT_CALL(signal_strategy_, AddListener(_));
[email protected]71f76c52014-07-10 00:36:05130 host_status_logger_.reset(
131 new HostStatusLogger(host_status_monitor_.AsWeakPtr(),
132 ServerLogEntry::ME2ME,
133 &signal_strategy_,
134 kTestBotJid));
[email protected]988dfc3c2012-01-04 01:10:11135 EXPECT_CALL(signal_strategy_, RemoveListener(_));
[email protected]00c794a2011-11-22 22:48:55136 }
137
138 protected:
[email protected]faea9d2d2013-04-30 03:18:44139 base::MessageLoop message_loop_;
[email protected]00c794a2011-11-22 22:48:55140 MockSignalStrategy signal_strategy_;
dcheng0765c492016-04-06 22:41:53141 std::unique_ptr<HostStatusLogger> host_status_logger_;
[email protected]a4b4fe52014-07-17 23:42:49142 FakeHostStatusMonitor host_status_monitor_;
[email protected]00c794a2011-11-22 22:48:55143};
144
[email protected]71f76c52014-07-10 00:36:05145TEST_F(HostStatusLoggerTest, SendNow) {
fdoray2df4a9e2016-07-18 23:47:16146 base::RunLoop run_loop;
[email protected]00c794a2011-11-22 22:48:55147 {
148 InSequence s;
[email protected]08128a312012-01-03 21:02:39149 EXPECT_CALL(signal_strategy_, GetLocalJid())
[email protected]b67b3952012-05-25 00:43:58150 .WillRepeatedly(Return(kHostJid));
[email protected]00c794a2011-11-22 22:48:55151 EXPECT_CALL(signal_strategy_, AddListener(_));
152 EXPECT_CALL(signal_strategy_, GetNextId());
[email protected]b67b3952012-05-25 00:43:58153 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientConnected("direct")))
[email protected]02f2de62011-11-23 03:45:11154 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
[email protected]00c794a2011-11-22 22:48:55155 EXPECT_CALL(signal_strategy_, RemoveListener(_))
fdoray2df4a9e2016-07-18 23:47:16156 .WillOnce(QuitRunLoop(&run_loop))
[email protected]00c794a2011-11-22 22:48:55157 .RetiresOnSaturation();
158 }
[email protected]71f76c52014-07-10 00:36:05159 host_status_logger_->SetSignalingStateForTest(SignalStrategy::CONNECTED);
[email protected]be451c82012-03-20 22:24:47160 protocol::TransportRoute route;
161 route.type = protocol::TransportRoute::DIRECT;
[email protected]71f76c52014-07-10 00:36:05162 host_status_logger_->OnClientRouteChange(kClientJid1, "video", route);
163 host_status_logger_->OnClientAuthenticated(kClientJid1);
164 host_status_logger_->OnClientConnected(kClientJid1);
165 host_status_logger_->SetSignalingStateForTest(
166 SignalStrategy::DISCONNECTED);
fdoray2df4a9e2016-07-18 23:47:16167 run_loop.Run();
[email protected]00c794a2011-11-22 22:48:55168}
169
[email protected]71f76c52014-07-10 00:36:05170TEST_F(HostStatusLoggerTest, SendLater) {
fdoray2df4a9e2016-07-18 23:47:16171 base::RunLoop run_loop;
[email protected]be451c82012-03-20 22:24:47172 protocol::TransportRoute route;
173 route.type = protocol::TransportRoute::DIRECT;
[email protected]71f76c52014-07-10 00:36:05174 host_status_logger_->OnClientRouteChange(kClientJid1, "video", route);
175 host_status_logger_->OnClientAuthenticated(kClientJid1);
176 host_status_logger_->OnClientConnected(kClientJid1);
[email protected]00c794a2011-11-22 22:48:55177 {
178 InSequence s;
[email protected]08128a312012-01-03 21:02:39179 EXPECT_CALL(signal_strategy_, GetLocalJid())
[email protected]b67b3952012-05-25 00:43:58180 .WillRepeatedly(Return(kHostJid));
[email protected]00c794a2011-11-22 22:48:55181 EXPECT_CALL(signal_strategy_, AddListener(_));
182 EXPECT_CALL(signal_strategy_, GetNextId());
[email protected]b67b3952012-05-25 00:43:58183 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientConnected("direct")))
[email protected]02f2de62011-11-23 03:45:11184 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
[email protected]00c794a2011-11-22 22:48:55185 EXPECT_CALL(signal_strategy_, RemoveListener(_))
fdoray2df4a9e2016-07-18 23:47:16186 .WillOnce(QuitRunLoop(&run_loop))
[email protected]00c794a2011-11-22 22:48:55187 .RetiresOnSaturation();
188 }
[email protected]71f76c52014-07-10 00:36:05189 host_status_logger_->SetSignalingStateForTest(SignalStrategy::CONNECTED);
190 host_status_logger_->SetSignalingStateForTest(SignalStrategy::DISCONNECTED);
fdoray2df4a9e2016-07-18 23:47:16191 run_loop.Run();
[email protected]00c794a2011-11-22 22:48:55192}
193
[email protected]71f76c52014-07-10 00:36:05194TEST_F(HostStatusLoggerTest, SendTwoEntriesLater) {
fdoray2df4a9e2016-07-18 23:47:16195 base::RunLoop run_loop;
[email protected]b67b3952012-05-25 00:43:58196 protocol::TransportRoute route1;
197 route1.type = protocol::TransportRoute::DIRECT;
[email protected]71f76c52014-07-10 00:36:05198 host_status_logger_->OnClientRouteChange(kClientJid1, "video", route1);
199 host_status_logger_->OnClientAuthenticated(kClientJid1);
200 host_status_logger_->OnClientConnected(kClientJid1);
[email protected]b67b3952012-05-25 00:43:58201 protocol::TransportRoute route2;
202 route2.type = protocol::TransportRoute::STUN;
[email protected]71f76c52014-07-10 00:36:05203 host_status_logger_->OnClientRouteChange(kClientJid2, "video", route2);
204 host_status_logger_->OnClientAuthenticated(kClientJid2);
205 host_status_logger_->OnClientConnected(kClientJid2);
[email protected]00c794a2011-11-22 22:48:55206 {
207 InSequence s;
[email protected]08128a312012-01-03 21:02:39208 EXPECT_CALL(signal_strategy_, GetLocalJid())
[email protected]b67b3952012-05-25 00:43:58209 .WillRepeatedly(Return(kHostJid));
[email protected]00c794a2011-11-22 22:48:55210 EXPECT_CALL(signal_strategy_, AddListener(_));
211 EXPECT_CALL(signal_strategy_, GetNextId());
[email protected]71f76c52014-07-10 00:36:05212 EXPECT_CALL(signal_strategy_,
213 SendStanzaPtr(IsTwoClientsConnected("direct", "stun")))
214 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
[email protected]00c794a2011-11-22 22:48:55215 EXPECT_CALL(signal_strategy_, RemoveListener(_))
fdoray2df4a9e2016-07-18 23:47:16216 .WillOnce(QuitRunLoop(&run_loop))
[email protected]00c794a2011-11-22 22:48:55217 .RetiresOnSaturation();
218 }
[email protected]71f76c52014-07-10 00:36:05219 host_status_logger_->SetSignalingStateForTest(SignalStrategy::CONNECTED);
220 host_status_logger_->SetSignalingStateForTest(SignalStrategy::DISCONNECTED);
fdoray2df4a9e2016-07-18 23:47:16221 run_loop.Run();
[email protected]00c794a2011-11-22 22:48:55222}
223
[email protected]71f76c52014-07-10 00:36:05224TEST_F(HostStatusLoggerTest, HandleRouteChangeInUnusualOrder) {
fdoray2df4a9e2016-07-18 23:47:16225 base::RunLoop run_loop;
[email protected]b67b3952012-05-25 00:43:58226 {
227 InSequence s;
228 EXPECT_CALL(signal_strategy_, GetLocalJid())
229 .WillRepeatedly(Return(kHostJid));
230 EXPECT_CALL(signal_strategy_, AddListener(_));
231 EXPECT_CALL(signal_strategy_, GetNextId());
232 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientConnected("direct")))
233 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
234 EXPECT_CALL(signal_strategy_, GetNextId());
235 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientDisconnected()))
236 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
237 EXPECT_CALL(signal_strategy_, GetNextId());
238 EXPECT_CALL(signal_strategy_, SendStanzaPtr(IsClientConnected("stun")))
239 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
240 EXPECT_CALL(signal_strategy_, RemoveListener(_))
fdoray2df4a9e2016-07-18 23:47:16241 .WillOnce(QuitRunLoop(&run_loop))
[email protected]b67b3952012-05-25 00:43:58242 .RetiresOnSaturation();
243 }
[email protected]71f76c52014-07-10 00:36:05244 host_status_logger_->SetSignalingStateForTest(SignalStrategy::CONNECTED);
[email protected]b67b3952012-05-25 00:43:58245 protocol::TransportRoute route1;
246 route1.type = protocol::TransportRoute::DIRECT;
[email protected]71f76c52014-07-10 00:36:05247 host_status_logger_->OnClientRouteChange(kClientJid1, "video", route1);
248 host_status_logger_->OnClientAuthenticated(kClientJid1);
249 host_status_logger_->OnClientConnected(kClientJid1);
[email protected]b67b3952012-05-25 00:43:58250 protocol::TransportRoute route2;
251 route2.type = protocol::TransportRoute::STUN;
[email protected]71f76c52014-07-10 00:36:05252 host_status_logger_->OnClientRouteChange(kClientJid2, "video", route2);
253 host_status_logger_->OnClientDisconnected(kClientJid1);
254 host_status_logger_->OnClientAuthenticated(kClientJid2);
255 host_status_logger_->OnClientConnected(kClientJid2);
256 host_status_logger_->SetSignalingStateForTest(SignalStrategy::DISCONNECTED);
fdoray2df4a9e2016-07-18 23:47:16257 run_loop.Run();
[email protected]b67b3952012-05-25 00:43:58258}
259
[email protected]00c794a2011-11-22 22:48:55260} // namespace remoting