diff options
Diffstat (limited to 'remoting/host/host_status_sender_unittest.cc')
-rw-r--r-- | remoting/host/host_status_sender_unittest.cc | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/remoting/host/host_status_sender_unittest.cc b/remoting/host/host_status_sender_unittest.cc new file mode 100644 index 0000000..4e55e73 --- /dev/null +++ b/remoting/host/host_status_sender_unittest.cc @@ -0,0 +1,199 @@ +// Copyright 2013 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 "remoting/host/host_status_sender.h" + +#include "base/strings/string_number_conversions.h" +#include "remoting/base/constants.h" +#include "remoting/base/rsa_key_pair.h" +#include "remoting/base/test_rsa_key_pair.h" +#include "remoting/host/host_exit_codes.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::QName; +using buzz::XmlElement; + +using testing::DoAll; +using testing::NotNull; +using testing::Return; +using testing::SaveArg; + +namespace remoting { + +namespace { + +const char kTestBotJid[] = "remotingunittest@bot.talk.google.com"; +const char kHostId[] = "0"; +const char kTestJid[] = "user@gmail.com/chromoting123"; +const char kStanzaId[] = "123"; + +const HostExitCodes kTestExitCode = kInvalidHostConfigurationExitCode; +const char kTestExitCodeString[] = "INVALID_HOST_CONFIGURATION"; + +} // namespace + +class HostStatusSenderTest + : public testing::Test { + protected: + virtual void SetUp() OVERRIDE { + key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair); + ASSERT_TRUE(key_pair_.get()); + + host_status_sender_.reset(new HostStatusSender( + kHostId, &signal_strategy_, key_pair_, kTestBotJid)); + } + + virtual void TearDown() OVERRIDE { + host_status_sender_.reset(); + } + + void ValidateHostStatusStanza(XmlElement* stanza, + HostStatusSender::HostStatus status); + + void ValidateSignature( + XmlElement* signature, HostStatusSender::HostStatus status); + + MockSignalStrategy signal_strategy_; + scoped_refptr<RsaKeyPair> key_pair_; + scoped_ptr<HostStatusSender> host_status_sender_; +}; + +TEST_F(HostStatusSenderTest, SendOnlineStatus) { + XmlElement* sent_iq = NULL; + EXPECT_CALL(signal_strategy_, GetState()) + .WillOnce(Return(SignalStrategy::DISCONNECTED)) + .WillRepeatedly(Return(SignalStrategy::CONNECTED)); + EXPECT_CALL(signal_strategy_, GetLocalJid()) + .WillRepeatedly(Return(kTestJid)); + EXPECT_CALL(signal_strategy_, GetNextId()) + .WillOnce(Return(kStanzaId)); + EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) + .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); + + // Call SendOnlineStatus twice. The first call should be a + // no-op because |signal_strategy_| is diconnected. + // So we expect SendStanza to be called only once. + host_status_sender_->SendOnlineStatus(); + + host_status_sender_->OnSignalStrategyStateChange( + SignalStrategy::CONNECTED); + host_status_sender_->SendOnlineStatus(); + + scoped_ptr<XmlElement> stanza(sent_iq); + + ASSERT_TRUE(stanza != NULL); + LOG(INFO) << stanza->Str(); + + ValidateHostStatusStanza(stanza.get(), HostStatusSender::ONLINE); +} + +TEST_F(HostStatusSenderTest, SendOfflineStatus) { + XmlElement* sent_iq = NULL; + EXPECT_CALL(signal_strategy_, GetState()) + .WillOnce(Return(SignalStrategy::DISCONNECTED)) + .WillRepeatedly(Return(SignalStrategy::CONNECTED)); + EXPECT_CALL(signal_strategy_, GetLocalJid()) + .WillRepeatedly(Return(kTestJid)); + EXPECT_CALL(signal_strategy_, GetNextId()) + .WillOnce(Return(kStanzaId)); + EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) + .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); + + // Call SendOfflineStatus twice. The first call should be a + // no-op because |signal_strategy_| is diconnected. + // So we expect SendStanza to be called only once. + host_status_sender_->SendOfflineStatus(kTestExitCode); + + host_status_sender_->OnSignalStrategyStateChange( + SignalStrategy::CONNECTED); + host_status_sender_->SendOfflineStatus(kTestExitCode); + + scoped_ptr<XmlElement> stanza(sent_iq); + + ASSERT_TRUE(stanza != NULL); + LOG(INFO) << stanza->Str(); + + ValidateHostStatusStanza(stanza.get(), HostStatusSender::OFFLINE); +} + +// Validate a host status stanza. +void HostStatusSenderTest::ValidateHostStatusStanza( + XmlElement* stanza, HostStatusSender::HostStatus status) { + EXPECT_EQ(stanza->Attr(QName(std::string(), "to")), + std::string(kTestBotJid)); + EXPECT_EQ(stanza->Attr(QName(std::string(), "type")), "set"); + + XmlElement* host_status_stanza = + stanza->FirstNamed(QName(kChromotingXmlNamespace, "host-status")); + ASSERT_TRUE(host_status_stanza != NULL); + + if (status == HostStatusSender::ONLINE) { + EXPECT_EQ("ONLINE", + host_status_stanza->Attr( + QName(kChromotingXmlNamespace, "status"))); + EXPECT_FALSE(host_status_stanza->HasAttr( + QName(kChromotingXmlNamespace, "exit-code"))); + } else { + EXPECT_EQ("OFFLINE", + host_status_stanza->Attr( + QName(kChromotingXmlNamespace, "status"))); + EXPECT_EQ(kTestExitCodeString, + host_status_stanza->Attr( + QName(kChromotingXmlNamespace, "exit-code"))); + } + + EXPECT_EQ(std::string(kHostId), + host_status_stanza->Attr( + QName(kChromotingXmlNamespace, "hostid"))); + + QName signature_tag(kChromotingXmlNamespace, "signature"); + XmlElement* signature = host_status_stanza->FirstNamed(signature_tag); + ASSERT_TRUE(signature != NULL); + EXPECT_TRUE(host_status_stanza->NextNamed(signature_tag) == NULL); + + ValidateSignature(signature, status); +} + +// Validate the signature. +void HostStatusSenderTest::ValidateSignature( + XmlElement* signature, HostStatusSender::HostStatus status) { + + EXPECT_TRUE(signature->HasAttr( + QName(kChromotingXmlNamespace, "time"))); + + std::string time_str = + signature->Attr(QName(kChromotingXmlNamespace, "time")); + + int64 time; + ASSERT_TRUE(base::StringToInt64(time_str, &time)); + + std::string message; + message += kTestJid; + message += " "; + message += time_str; + message += " "; + + if (status == HostStatusSender::OFFLINE) { + message += "OFFLINE"; + message += " "; + message += kTestExitCodeString; + } else { + message += "ONLINE"; + } + + scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::FromString(kTestRsaKeyPair); + ASSERT_TRUE(key_pair.get()); + + std::string expected_signature = + key_pair->SignMessage(message); + EXPECT_EQ(expected_signature, signature->BodyText()); + + int64 now = static_cast<int64>(base::Time::Now().ToDoubleT()); + LOG(INFO) << "SendHostStatus took " << now - time << " seconds."; +} + +} // namespace remoting |