Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Unified Diff: remoting/test/chromoting_instance_unittest.cc

Issue 976233003: Adding the base ChromotingInstance implementation and unittests. This class will be used by the ap… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing a unit test name Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/test/chromoting_instance_unittest.cc
diff --git a/remoting/test/chromoting_instance_unittest.cc b/remoting/test/chromoting_instance_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..65eae1260d812c873545d6ac1a1de1c4f672b94d
--- /dev/null
+++ b/remoting/test/chromoting_instance_unittest.cc
@@ -0,0 +1,266 @@
+// Copyright 2015 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 <string>
+
+#include "base/message_loop/message_loop.h"
+#include "remoting/protocol/fake_connection_to_host.h"
+#include "remoting/protocol/protocol_mock_objects.h"
+#include "remoting/test/chromoting_instance.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+const char kTestUserName[] = "test_user@faux_address.com";
+const char kAccessToken[] = "faux_access_token";
+}
+
+namespace remoting {
+namespace test {
+
+using testing::_;
+
+// Provides base functionality for the ChromotingInstance Tests below. This
+// fixture also creates an IO MessageLoop, if necessary, for use by the
+// ChromotingInstance. Overrides a subset of the RemoteConnectionObserver
+// interface to track connection status changes for result verification.
+class ChromotingInstanceTest :
+ public ::testing::Test,
+ public RemoteConnectionObserver {
+ public:
+ ChromotingInstanceTest();
+ ~ChromotingInstanceTest() override;
+
+ protected:
+ // Test interface.
+ void SetUp() override;
+ void TearDown() override;
+
+ // Used for result verification.
+ bool is_connected_to_host_;
+ protocol::ConnectionToHost::State connection_state_;
+ protocol::ErrorCode error_code_;
+
+ // Used for simulating different conditions for the ChromotingInstance.
+ RemoteHostInfo remote_host_info_;
+ FakeConnectionToHost fake_connection_to_host_;
+ protocol::MockConnectionToHost* mock_connection_to_host_;
+
+ scoped_ptr<remoting::test::ChromotingInstance> chromoting_instance_;
+
+ private:
+ // RemoteConnectionObserver interface.
+ void ConnectionStateChanged(
+ protocol::ConnectionToHost::State state,
+ protocol::ErrorCode error_code) override;
+ void ConnectedToRemoteHost() override;
+ void DisconnectedFromRemoteHost() override;
+
+ // Used as return values in ON_CALL overrides for MockConnectionToHost.
+ protocol::MockHostStub mock_host_stub_;
+ protocol::SessionConfig session_config_;
+
+ scoped_ptr<base::MessageLoopForIO> message_loop_;
Sergey Ulanov 2015/03/09 06:44:41 Usually message_loop_ is defined as a first field
Sergey Ulanov 2015/03/09 06:44:41 Don't need this to be a pointer, see my next comme
joedow 2015/03/09 21:09:26 Done.
joedow 2015/03/09 21:09:26 Done.
+
+ DISALLOW_COPY_AND_ASSIGN(ChromotingInstanceTest);
+};
+
+ChromotingInstanceTest::ChromotingInstanceTest() :
+ is_connected_to_host_(false),
+ connection_state_(protocol::ConnectionToHost::INITIALIZING),
+ error_code_(protocol::OK),
+ mock_connection_to_host_(nullptr) {}
+
+ChromotingInstanceTest::~ChromotingInstanceTest() {}
+
+void ChromotingInstanceTest::SetUp() {
+ if (!base::MessageLoop::current()) {
+ // Create a temporary message loop if the current thread does not already
Sergey Ulanov 2015/03/09 06:44:41 This code is never expected to be invoked with a M
joedow 2015/03/09 21:09:26 Done.
+ // have one so we can use its task runner to create a request object.
+ message_loop_.reset(new base::MessageLoopForIO);
+ }
+
+ chromoting_instance_.reset(new remoting::test::ChromotingInstance);
+ chromoting_instance_->AddRemoteConnectionObserver(this);
+
+ // Pass ownership of the MockConnectionToHost to the chromoting instance but
+ // keep the ptr around so we can use it to simulate state changes. It will
+ // remain valid until |chromoting_instance_| is destroyed.
+ mock_connection_to_host_ = new protocol::MockConnectionToHost();
+ chromoting_instance_->SetConnectionToHostForTests(
+ make_scoped_ptr(mock_connection_to_host_));
+
+ session_config_ = protocol::SessionConfig::ForTest();
+ remote_host_info_.remote_host_status = kRemoteHostStatusReady;
+
+ // We want to redirect some of the calls to the mock objects to real objects
+ // which implement a simplified version of the method so ON_CALL is used.
+ ON_CALL(*mock_connection_to_host_,
+ ConnectPtr(_, _, _, _, _)).WillByDefault(testing::Invoke(
+ &fake_connection_to_host_, &FakeConnectionToHost::ConnectPtr));
Sergey Ulanov 2015/03/09 06:44:41 Do you need MockConnectionToHost, given that there
joedow 2015/03/09 21:09:26 Thanks for this info, I see GMOCK used often in th
+ ON_CALL(*mock_connection_to_host_,
+ OnSessionStateChange(_)).WillByDefault(testing::Invoke(
+ &fake_connection_to_host_,
+ &FakeConnectionToHost::OnSessionStateChange));
+ ON_CALL(*mock_connection_to_host_,
+ OnVideoChannelStatus(_)).WillByDefault(testing::Invoke(
+ &fake_connection_to_host_,
+ &FakeConnectionToHost::OnVideoChannelStatus));
+ ON_CALL(*mock_connection_to_host_, config()).WillByDefault(
+ testing::ReturnRef(session_config_));
+ ON_CALL(*mock_connection_to_host_, host_stub()).WillByDefault(
+ testing::Return(&mock_host_stub_));
+
+ EXPECT_CALL(mock_host_stub_, SetCapabilities(_))
+ .Times(testing::AtMost(1));
+ EXPECT_CALL(*mock_connection_to_host_, ConnectPtr(_, _, _, _, _))
+ .Times(testing::AtMost(1));
+ EXPECT_CALL(*mock_connection_to_host_, OnSessionStateChange(_))
+ .Times(testing::AnyNumber());
+ EXPECT_CALL(*mock_connection_to_host_, OnVideoChannelStatus(_))
+ .Times(testing::AnyNumber());
+ EXPECT_CALL(*mock_connection_to_host_, config())
+ .Times(testing::AnyNumber());
+ EXPECT_CALL(*mock_connection_to_host_, host_stub())
+ .Times(testing::AnyNumber());
+}
+
+void ChromotingInstanceTest::TearDown() {
+ chromoting_instance_->RemoveRemoteConnectionObserver(this);
+ mock_connection_to_host_ = nullptr;
+
+ // The chromoting instance must be destroyed before the message loop.
+ chromoting_instance_.reset();
+
+ // The LibjingleTransportFactory destroys the PortAllocator via a DeleteSoon
+ // operation. If we do not allow the message loop to run here, we run the
+ // risk of the DeleteSoon task being dropped and incurring a memory leak.
+ message_loop_->RunUntilIdle();
+
+ // Now that the message loop is clear, we can destroy it.
+ message_loop_.reset();
+}
+
+void ChromotingInstanceTest::ConnectionStateChanged(
+ protocol::ConnectionToHost::State state,
+ protocol::ErrorCode error_code) {
+ connection_state_ = state;
+ error_code_ = error_code;
+}
+
+void ChromotingInstanceTest::ConnectedToRemoteHost() {
+ is_connected_to_host_ = true;
+}
+
+void ChromotingInstanceTest::DisconnectedFromRemoteHost() {
+ is_connected_to_host_ = false;
+}
+
+TEST_F(ChromotingInstanceTest, StartConnectionAndDisconnect) {
+ chromoting_instance_->StartConnection(
+ kTestUserName,
+ kAccessToken,
+ remote_host_info_);
+ EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTING, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ // Simulate an AUTHENTICATED message being sent from the Jingle session.
+ mock_connection_to_host_->OnSessionStateChange(
+ protocol::Session::AUTHENTICATED);
+ EXPECT_EQ(protocol::ConnectionToHost::State::AUTHENTICATED,
+ connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ // Simulate a CONNECTED message being sent from the Jingle session.
+ mock_connection_to_host_->OnSessionStateChange(protocol::Session::CONNECTED);
+ EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ // The chromoting instance will consider its connection to the host complete
+ // once the video channel is active.
+ mock_connection_to_host_->OnVideoChannelStatus(true);
+ EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_TRUE(is_connected_to_host_);
+
+ chromoting_instance_->EndConnection();
+ EXPECT_EQ(protocol::ConnectionToHost::State::CLOSED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+}
+
+TEST_F(ChromotingInstanceTest, StartConnectionThenFailWithAuthenticationError) {
+ chromoting_instance_->StartConnection(
+ kTestUserName,
+ kAccessToken,
+ remote_host_info_);
+ EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTING, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ fake_connection_to_host_.set_session_state_change_error_code(
+ protocol::AUTHENTICATION_FAILED);
+ mock_connection_to_host_->OnSessionStateChange(protocol::Session::FAILED);
+ EXPECT_EQ(protocol::ConnectionToHost::State::FAILED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::AUTHENTICATION_FAILED, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ // Close the connection via the ChromotingInstance and verify the error state
+ // is persisted.
+ chromoting_instance_->EndConnection();
+ EXPECT_EQ(protocol::ConnectionToHost::State::FAILED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::AUTHENTICATION_FAILED, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+}
+
+TEST_F(ChromotingInstanceTest, StartConnectionThenFailWithUnknownError) {
+ chromoting_instance_->StartConnection(
+ kTestUserName,
+ kAccessToken,
+ remote_host_info_);
+ EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTING, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ // Simulate an AUTHENTICATED message being sent from the Jingle session.
+ mock_connection_to_host_->OnSessionStateChange(
+ protocol::Session::AUTHENTICATED);
+ EXPECT_EQ(protocol::ConnectionToHost::State::AUTHENTICATED,
+ connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ // Simulate a CONNECTED message being sent from the Jingle session.
+ mock_connection_to_host_->OnSessionStateChange(protocol::Session::CONNECTED);
+ EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ // The chromoting instance will consider its connection to the host complete
+ // once the video channel is active.
+ mock_connection_to_host_->OnVideoChannelStatus(true);
+ EXPECT_EQ(protocol::ConnectionToHost::State::CONNECTED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::OK, error_code_);
+ EXPECT_TRUE(is_connected_to_host_);
+
+ fake_connection_to_host_.set_session_state_change_error_code(
+ protocol::UNKNOWN_ERROR);
+ mock_connection_to_host_->OnSessionStateChange(protocol::Session::FAILED);
+ EXPECT_EQ(protocol::ConnectionToHost::State::FAILED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::UNKNOWN_ERROR, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+
+ // Close the connection via the ChromotingInstance and verify the error state
+ // is persisted.
+ chromoting_instance_->EndConnection();
+ EXPECT_EQ(protocol::ConnectionToHost::State::FAILED, connection_state_);
+ EXPECT_EQ(protocol::ErrorCode::UNKNOWN_ERROR, error_code_);
+ EXPECT_FALSE(is_connected_to_host_);
+}
+
+} // namespace test
+} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698