15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/channel_multiplexer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/run_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/stream_socket.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/constants.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/connection_tester.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/fake_session.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AtMost;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::InvokeWithoutArgs;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protocol {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMessageSize = 1024;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMessages = 100;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMuxChannelName[] = "mux";
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTestChannelName[] = "test";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTestChannelName2[] = "test2";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuitCurrentThread() {
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE,
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         base::MessageLoop::QuitClosure());
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockSocketCallback {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(OnDone, void(int result));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockConnectCallback {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(OnConnectedPtr, void(net::StreamSocket* socket));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnConnected(scoped_ptr<net::StreamSocket> socket) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnConnectedPtr(socket.release());
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChannelMultiplexerTest : public testing::Test {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteAll() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_socket1_.reset();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_socket2_.reset();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_socket1_.reset();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_socket2_.reset();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_mux_.reset();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_mux_.reset();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteAfterSessionFail() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_mux_->CancelChannelCreation(kTestChannelName2);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeleteAll();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create pair of multiplexers and connect them to each other.
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    host_mux_.reset(new ChannelMultiplexer(
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        host_session_.GetTransportChannelFactory(), kMuxChannelName));
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    client_mux_.reset(new ChannelMultiplexer(
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        client_session_.GetTransportChannelFactory(), kMuxChannelName));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect sockets to each other. Must be called after we've created at least
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one channel with each multiplexer.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectSockets() {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FakeStreamSocket* host_socket =
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        host_session_.fake_channel_factory().GetFakeChannel(
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ChannelMultiplexer::kMuxChannelName);
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FakeStreamSocket* client_socket =
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        client_session_.fake_channel_factory().GetFakeChannel(
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ChannelMultiplexer::kMuxChannelName);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_socket->PairWith(client_socket);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make writes asynchronous in one direction.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_socket->set_async_write(true);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateChannel(const std::string& name,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     scoped_ptr<net::StreamSocket>* host_socket,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     scoped_ptr<net::StreamSocket>* client_socket) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int counter = 2;
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    host_mux_->CreateChannel(name, base::Bind(
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ChannelMultiplexerTest::OnChannelConnected, base::Unretained(this),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_socket, &counter));
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    client_mux_->CreateChannel(name, base::Bind(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ChannelMultiplexerTest::OnChannelConnected, base::Unretained(this),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        client_socket, &counter));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_.Run();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_socket->get());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(client_socket->get());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnChannelConnected(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<net::StreamSocket>* storage,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int* counter,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<net::StreamSocket> socket) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *storage = socket.Pass();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --(*counter);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GE(*counter, 0);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (*counter == 0)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      QuitCurrentThread();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> CreateTestBuffer(int size) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::IOBufferWithSize> result =
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::IOBufferWithSize(size);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i< size; ++i) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->data()[i] = rand() % 256;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeSession host_session_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeSession client_session_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ChannelMultiplexer> host_mux_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ChannelMultiplexer> client_mux_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket1_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket1_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket2_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket2_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChannelMultiplexerTest, OneChannel) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName, &host_socket, &client_socket));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectSockets();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamConnectionTester tester(host_socket.get(), client_socket.get(),
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                kMessageSize, kMessages);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester.Start();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_.Run();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester.CheckResults();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChannelMultiplexerTest, TwoChannels) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket1_;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket1_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName, &host_socket1_, &client_socket1_));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket2_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket2_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName2, &host_socket2_, &client_socket2_));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectSockets();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamConnectionTester tester1(host_socket1_.get(), client_socket1_.get(),
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                kMessageSize, kMessages);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamConnectionTester tester2(host_socket2_.get(), client_socket2_.get(),
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMessageSize, kMessages);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester1.Start();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester2.Start();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!tester1.done() || !tester2.done()) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_.Run();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester1.CheckResults();
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester2.CheckResults();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Four channels, two in each direction
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChannelMultiplexerTest, FourChannels) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket1_;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket1_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName, &host_socket1_, &client_socket1_));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket2_;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket2_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName2, &host_socket2_, &client_socket2_));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket3;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket3;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel("test3", &host_socket3, &client_socket3));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket4;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket4;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel("ch4", &host_socket4, &client_socket4));
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectSockets();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamConnectionTester tester1(host_socket1_.get(), client_socket1_.get(),
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                kMessageSize, kMessages);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamConnectionTester tester2(host_socket2_.get(), client_socket2_.get(),
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMessageSize, kMessages);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamConnectionTester tester3(client_socket3.get(), host_socket3.get(),
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMessageSize, kMessages);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamConnectionTester tester4(client_socket4.get(), host_socket4.get(),
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMessageSize, kMessages);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester1.Start();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester2.Start();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester3.Start();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester4.Start();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!tester1.done() || !tester2.done() ||
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         !tester3.done() || !tester4.done()) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_.Run();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester1.CheckResults();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester2.CheckResults();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester3.CheckResults();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tester4.CheckResults();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChannelMultiplexerTest, WriteFailSync) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket1_;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket1_;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName, &host_socket1_, &client_socket1_));
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> host_socket2_;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::StreamSocket> client_socket2_;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName2, &host_socket2_, &client_socket2_));
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectSockets();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_session_.fake_channel_factory().GetFakeChannel(kMuxChannelName)->
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_next_write_error(net::ERR_FAILED);
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_session_.fake_channel_factory().GetFakeChannel(kMuxChannelName)->
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_async_write(false);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSocketCallback cb1;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSocketCallback cb2;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(cb1, OnDone(_))
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(0);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(cb2, OnDone(_))
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(0);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(net::ERR_FAILED,
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            host_socket1_->Write(buf.get(),
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 buf->size(),
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 base::Bind(&MockSocketCallback::OnDone,
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            base::Unretained(&cb1))));
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(net::ERR_FAILED,
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            host_socket2_->Write(buf.get(),
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 buf->size(),
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 base::Bind(&MockSocketCallback::OnDone,
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            base::Unretained(&cb2))));
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChannelMultiplexerTest, WriteFailAsync) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName, &host_socket1_, &client_socket1_));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName2, &host_socket2_, &client_socket2_));
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectSockets();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_session_.fake_channel_factory().GetFakeChannel(kMuxChannelName)->
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_next_write_error(net::ERR_FAILED);
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_session_.fake_channel_factory().GetFakeChannel(kMuxChannelName)->
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_async_write(true);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSocketCallback cb1;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSocketCallback cb2;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(cb1, OnDone(net::ERR_FAILED));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(cb2, OnDone(net::ERR_FAILED));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING,
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            host_socket1_->Write(buf.get(),
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 buf->size(),
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 base::Bind(&MockSocketCallback::OnDone,
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            base::Unretained(&cb1))));
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING,
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            host_socket2_->Write(buf.get(),
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 buf->size(),
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 base::Bind(&MockSocketCallback::OnDone,
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            base::Unretained(&cb2))));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChannelMultiplexerTest, DeleteWhenFailed) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName, &host_socket1_, &client_socket1_));
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateChannel(kTestChannelName2, &host_socket2_, &client_socket2_));
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectSockets();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_session_.fake_channel_factory().GetFakeChannel(kMuxChannelName)->
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_next_write_error(net::ERR_FAILED);
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_session_.fake_channel_factory().GetFakeChannel(kMuxChannelName)->
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_async_write(true);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSocketCallback cb1;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockSocketCallback cb2;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(cb1, OnDone(net::ERR_FAILED))
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(AtMost(1))
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(cb2, OnDone(net::ERR_FAILED))
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(AtMost(1))
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING,
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            host_socket1_->Write(buf.get(),
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 buf->size(),
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 base::Bind(&MockSocketCallback::OnDone,
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            base::Unretained(&cb1))));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING,
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            host_socket2_->Write(buf.get(),
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 buf->size(),
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 base::Bind(&MockSocketCallback::OnDone,
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            base::Unretained(&cb2))));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the sockets were destroyed.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host_mux_.get());
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ChannelMultiplexerTest, SessionFail) {
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_session_.fake_channel_factory().set_asynchronous_create(true);
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_session_.fake_channel_factory().set_fail_create(true);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnectCallback cb1;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnectCallback cb2;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_mux_->CreateChannel(kTestChannelName, base::Bind(
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &MockConnectCallback::OnConnected, base::Unretained(&cb1)));
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_mux_->CreateChannel(kTestChannelName2, base::Bind(
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &MockConnectCallback::OnConnected, base::Unretained(&cb2)));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(cb1, OnConnectedPtr(NULL))
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(AtMost(1))
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          this, &ChannelMultiplexerTest::DeleteAfterSessionFail));
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(cb2, OnConnectedPtr(_))
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(0);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protocol
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
378