| Index: remoting/client/log_to_server_client_unittest.cc
|
| diff --git a/remoting/client/log_to_server_client_unittest.cc b/remoting/client/log_to_server_client_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..709b7cabb94e80912e5cadecc9c22025276ef97e
|
| --- /dev/null
|
| +++ b/remoting/client/log_to_server_client_unittest.cc
|
| @@ -0,0 +1,194 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| +#include "remoting/client/chromoting_stats.h"
|
| +#include "remoting/client/log_to_server_client.h"
|
| +#include "remoting/jingle_glue/mock_objects.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
|
| +
|
| +using buzz::XmlElement;
|
| +using buzz::QName;
|
| +using remoting::protocol::ConnectionToHost;
|
| +using testing::_;
|
| +using testing::DeleteArg;
|
| +using testing::InSequence;
|
| +using testing::Return;
|
| +
|
| +namespace remoting {
|
| +
|
| +namespace {
|
| +
|
| +ACTION_P(QuitMainMessageLoop, message_loop) {
|
| + message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
|
| +}
|
| +
|
| +const char kJabberClientNamespace[] = "jabber:client";
|
| +const char kChromotingNamespace[] = "google:remoting";
|
| +const char kTestBotJid[] = "remotingunittest@bot.talk.google.com";
|
| +const char kClientJid[] = "host@domain.com/1234";
|
| +
|
| +// Verifies that |stanza| contains a log entry and returns it. Otherwise
|
| +// returns NULL and records a test failure.
|
| +XmlElement* GetLogElement(XmlElement* stanza) {
|
| + if (stanza->Name() != QName(kJabberClientNamespace, "iq")) {
|
| + ADD_FAILURE() << "Expected element 'iq'";
|
| + return NULL;
|
| + }
|
| + XmlElement* log_element = stanza->FirstChild()->AsElement();
|
| + if (log_element->Name() != QName(kChromotingNamespace, "log")) {
|
| + ADD_FAILURE() << "Expected element 'log'";
|
| + return NULL;
|
| + }
|
| + if (log_element->NextChild()) {
|
| + ADD_FAILURE() << "Expected only 1 child of 'iq'";
|
| + return NULL;
|
| + }
|
| + return log_element;
|
| +}
|
| +
|
| +// Verifies that |stanza| contains only 1 log entry, and returns it.
|
| +// Otherwise returns NULL and records a test failure.
|
| +XmlElement* GetSingleLogEntry(XmlElement* stanza) {
|
| + XmlElement* log_element = GetLogElement(stanza);
|
| + if (!log_element) {
|
| + // Test failure already recorded, so just return NULL here.
|
| + return NULL;
|
| + }
|
| + XmlElement* entry = log_element->FirstChild()->AsElement();
|
| + if (entry->Name() != QName(kChromotingNamespace, "entry")) {
|
| + ADD_FAILURE() << "Expected element 'entry'";
|
| + return NULL;
|
| + }
|
| + if (entry->NextChild()) {
|
| + ADD_FAILURE() << "Expected only 1 child of 'log'";
|
| + return NULL;
|
| + }
|
| + return entry;
|
| +}
|
| +
|
| +MATCHER_P2(IsStateChange, new_state, error, "") {
|
| + XmlElement* entry = GetSingleLogEntry(arg);
|
| + if (!entry) {
|
| + return false;
|
| + }
|
| +
|
| + bool is_state_change = (
|
| + entry->Attr(QName(std::string(), "event-name")) == "session-state" &&
|
| + entry->Attr(QName(std::string(), "session-state")) == new_state &&
|
| + entry->Attr(QName(std::string(), "role")) == "client" &&
|
| + entry->Attr(QName(std::string(), "mode")) == "me2me");
|
| + if (!std::string(error).empty()) {
|
| + is_state_change = is_state_change &&
|
| + entry->Attr(QName(std::string(), "connection-error")) == error;
|
| + }
|
| + return is_state_change;
|
| +}
|
| +
|
| +MATCHER(IsStatisticsLog, "") {
|
| + XmlElement* entry = GetSingleLogEntry(arg);
|
| + if (!entry) {
|
| + return false;
|
| + }
|
| +
|
| + return entry->Attr(QName(std::string(), "event-name")) ==
|
| + "connection-statistics";
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +class LogToServerClientTest : public testing::Test {
|
| + public:
|
| + LogToServerClientTest() {}
|
| + virtual void SetUp() OVERRIDE {
|
| + EXPECT_CALL(signal_strategy_, AddListener(_));
|
| + EXPECT_CALL(signal_strategy_, RemoveListener(_));
|
| + message_loop_proxy_ = base::MessageLoopProxy::current();
|
| + log_to_server_.reset(
|
| + new LogToServerClient(ServerLogEntry::ME2ME,
|
| + &signal_strategy_,
|
| + kTestBotJid));
|
| + }
|
| +
|
| + protected:
|
| + base::MessageLoop message_loop_;
|
| + scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
|
| + MockSignalStrategy signal_strategy_;
|
| + scoped_ptr<LogToServerClient> log_to_server_;
|
| +};
|
| +
|
| +TEST_F(LogToServerClientTest, LogStateChange) {
|
| + {
|
| + InSequence s;
|
| + EXPECT_CALL(signal_strategy_, GetLocalJid())
|
| + .WillRepeatedly(Return(kClientJid));
|
| + EXPECT_CALL(signal_strategy_, AddListener(_));
|
| + EXPECT_CALL(signal_strategy_, GetNextId());
|
| + EXPECT_CALL(signal_strategy_, SendStanzaPtr(
|
| + IsStateChange("connected", std::string())))
|
| + .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
|
| + EXPECT_CALL(signal_strategy_, RemoveListener(_))
|
| + .WillOnce(QuitMainMessageLoop(&message_loop_))
|
| + .RetiresOnSaturation();
|
| + }
|
| + log_to_server_->LogSessionStateChange(ConnectionToHost::CONNECTED,
|
| + protocol::OK);
|
| +
|
| + // Setting the state to CONNECTED causes the log to be sent. Setting the
|
| + // state to DISCONNECTED causes |signal_strategy_| to be cleaned up,
|
| + // which removes the listener and terminates the test.
|
| + log_to_server_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED);
|
| + log_to_server_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED);
|
| + message_loop_.Run();
|
| +}
|
| +
|
| +TEST_F(LogToServerClientTest, LogStateChangeError) {
|
| + {
|
| + InSequence s;
|
| + EXPECT_CALL(signal_strategy_, GetLocalJid())
|
| + .WillRepeatedly(Return(kClientJid));
|
| + EXPECT_CALL(signal_strategy_, AddListener(_));
|
| + EXPECT_CALL(signal_strategy_, GetNextId());
|
| + EXPECT_CALL(signal_strategy_, SendStanzaPtr(
|
| + IsStateChange("connection-failed", "host-is-offline")))
|
| + .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
|
| + EXPECT_CALL(signal_strategy_, RemoveListener(_))
|
| + .WillOnce(QuitMainMessageLoop(&message_loop_))
|
| + .RetiresOnSaturation();
|
| + }
|
| + log_to_server_->LogSessionStateChange(ConnectionToHost::FAILED,
|
| + protocol::PEER_IS_OFFLINE);
|
| +
|
| + log_to_server_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED);
|
| + log_to_server_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED);
|
| + message_loop_.Run();
|
| +}
|
| +
|
| +TEST_F(LogToServerClientTest, LogStatistics) {
|
| + {
|
| + InSequence s;
|
| + EXPECT_CALL(signal_strategy_, GetLocalJid())
|
| + .WillRepeatedly(Return(kClientJid));
|
| + EXPECT_CALL(signal_strategy_, AddListener(_));
|
| + EXPECT_CALL(signal_strategy_, GetNextId());
|
| + EXPECT_CALL(signal_strategy_, SendStanzaPtr(
|
| + IsStatisticsLog()))
|
| + .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
|
| + EXPECT_CALL(signal_strategy_, RemoveListener(_))
|
| + .WillOnce(QuitMainMessageLoop(&message_loop_))
|
| + .RetiresOnSaturation();
|
| + }
|
| +
|
| + ChromotingStats stats;
|
| + log_to_server_->LogStatistics(&stats);
|
| +
|
| + log_to_server_->OnSignalStrategyStateChange(SignalStrategy::CONNECTED);
|
| + log_to_server_->OnSignalStrategyStateChange(SignalStrategy::DISCONNECTED);
|
| + message_loop_.Run();
|
| +}
|
| +
|
| +} // namespace remoting
|
|
|