async_connection_unittest.cc revision 22f1fbc11b69ee41af8370ec38f1b90577db6c3c
1f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart// Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 2f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart// Use of this source code is governed by a BSD-style license that can be 3f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart// found in the LICENSE file. 4f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 5f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart#include "shill/async_connection.h" 6f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 7f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart#include <netinet/in.h> 8f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 9f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart#include <vector> 10f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 113e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood#include <base/bind.h> 12f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart#include <gtest/gtest.h> 13f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 14f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart#include "shill/ip_address.h" 15f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart#include "shill/mock_event_dispatcher.h" 16f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart#include "shill/mock_sockets.h" 17f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 183e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Bind; 193e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Callback; 203e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Unretained; 21f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartusing std::string; 22f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartusing ::testing::_; 23f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartusing ::testing::Return; 24f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartusing ::testing::ReturnNew; 25f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartusing ::testing::StrEq; 26f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartusing ::testing::StrictMock; 27f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartusing ::testing::Test; 28f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 29f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartnamespace shill { 30f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 31f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartnamespace { 32f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartconst char kInterfaceName[] = "int0"; 33f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiuconst char kIPv4Address[] = "10.11.12.13"; 34f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiuconst char kIPv6Address[] = "2001:db8::1"; 35f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartconst int kConnectPort = 10203; 36f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartconst int kErrorNumber = 30405; 37f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartconst int kSocketFD = 60708; 388a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko} // namespace 39f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 40f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewartclass AsyncConnectionTest : public Test { 41f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart public: 42f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart AsyncConnectionTest() 438585b207dc9502256c2a428611e948e105db96b6Paul Stewart : async_connection_( 448585b207dc9502256c2a428611e948e105db96b6Paul Stewart new AsyncConnection(kInterfaceName, &dispatcher_, &sockets_, 458585b207dc9502256c2a428611e948e105db96b6Paul Stewart callback_target_.callback())), 46f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu ipv4_address_(IPAddress::kFamilyIPv4), 47f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu ipv6_address_(IPAddress::kFamilyIPv6) { } 48f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 49f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart virtual void SetUp() { 50f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_TRUE(ipv4_address_.SetAddressFromString(kIPv4Address)); 51f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_TRUE(ipv6_address_.SetAddressFromString(kIPv6Address)); 52f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart } 53f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart virtual void TearDown() { 548585b207dc9502256c2a428611e948e105db96b6Paul Stewart if (async_connection_.get() && async_connection_->fd_ >= 0) { 55f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Close(kSocketFD)) 56f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 57f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart } 58f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart } 598585b207dc9502256c2a428611e948e105db96b6Paul Stewart void InvokeFreeConnection(bool /*success*/, int /*fd*/) { 608585b207dc9502256c2a428611e948e105db96b6Paul Stewart async_connection_.reset(); 618585b207dc9502256c2a428611e948e105db96b6Paul Stewart } 62f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 63f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart protected: 64f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart class ConnectCallbackTarget { 65f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart public: 66f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ConnectCallbackTarget() 673e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood : callback_(Bind(&ConnectCallbackTarget::CallTarget, 683e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood Unretained(this))) {} 69f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 70f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart MOCK_METHOD2(CallTarget, void(bool success, int fd)); 713e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood const Callback<void(bool, int)> &callback() { return callback_; } 72f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 73f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart private: 743e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood Callback<void(bool, int)> callback_; 75f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart }; 76f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 77f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart void ExpectReset() { 788585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_STREQ(kInterfaceName, async_connection_->interface_name_.c_str()); 798585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_EQ(&dispatcher_, async_connection_->dispatcher_); 808585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_EQ(&sockets_, async_connection_->sockets_); 813e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood EXPECT_TRUE(callback_target_.callback(). 828585b207dc9502256c2a428611e948e105db96b6Paul Stewart Equals(async_connection_->callback_)); 838585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_EQ(-1, async_connection_->fd_); 848585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_FALSE(async_connection_->connect_completion_callback_.is_null()); 858585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_FALSE(async_connection_->connect_completion_handler_.get()); 86f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart } 87f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 88f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart void StartConnection() { 89f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets_, Socket(_, _, _)) 90f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kSocketFD)); 91f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets_, SetNonBlocking(kSocketFD)) 92f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 93f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets_, BindToDevice(kSocketFD, StrEq(kInterfaceName))) 94f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 953e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood EXPECT_CALL(sockets(), Connect(kSocketFD, _, _)) 963e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood .WillOnce(Return(-1)); 973e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood EXPECT_CALL(sockets_, Error()) 98f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(EINPROGRESS)); 993e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood EXPECT_CALL(dispatcher(), 1003e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood CreateReadyHandler(kSocketFD, IOHandler::kModeOutput, _)) 101f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(ReturnNew<IOHandler>()); 102f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_TRUE(async_connection().Start(ipv4_address_, kConnectPort)); 103f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart } 104f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 105f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart void OnConnectCompletion(int fd) { 1068585b207dc9502256c2a428611e948e105db96b6Paul Stewart async_connection_->OnConnectCompletion(fd); 107f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart } 1088585b207dc9502256c2a428611e948e105db96b6Paul Stewart AsyncConnection &async_connection() { return *async_connection_.get(); } 109f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart StrictMock<MockSockets> &sockets() { return sockets_; } 110f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart MockEventDispatcher &dispatcher() { return dispatcher_; } 111f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu const IPAddress &ipv4_address() { return ipv4_address_; } 112f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu const IPAddress &ipv6_address() { return ipv6_address_; } 1138585b207dc9502256c2a428611e948e105db96b6Paul Stewart int fd() { return async_connection_->fd_; } 1148585b207dc9502256c2a428611e948e105db96b6Paul Stewart void set_fd(int fd) { async_connection_->fd_ = fd; } 115f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart StrictMock<ConnectCallbackTarget> &callback_target() { 116f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart return callback_target_; 117f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart } 118f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 119f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart private: 120f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart MockEventDispatcher dispatcher_; 121f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart StrictMock<MockSockets> sockets_; 122f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart StrictMock<ConnectCallbackTarget> callback_target_; 12322f1fbc11b69ee41af8370ec38f1b90577db6c3cBen Chan std::unique_ptr<AsyncConnection> async_connection_; 124f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu IPAddress ipv4_address_; 125f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu IPAddress ipv6_address_; 126f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart}; 127f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 128f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, InitState) { 129f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ExpectReset(); 130f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_EQ(string(), async_connection().error()); 131f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 132f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 133f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, StartSocketFailure) { 134f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Socket(_, _, _)) 135f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(-1)); 136f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Error()) 137f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kErrorNumber)); 138f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_FALSE(async_connection().Start(ipv4_address(), kConnectPort)); 139f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ExpectReset(); 140f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_STREQ(strerror(kErrorNumber), async_connection().error().c_str()); 141f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 142f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 143f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, StartNonBlockingFailure) { 144f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Socket(_, _, _)) 145f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kSocketFD)); 146f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), SetNonBlocking(kSocketFD)) 147f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(-1)); 148f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Error()) 149f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kErrorNumber)); 150f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Close(kSocketFD)) 151f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 152f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_FALSE(async_connection().Start(ipv4_address(), kConnectPort)); 153f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ExpectReset(); 154f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_STREQ(strerror(kErrorNumber), async_connection().error().c_str()); 155f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 156f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 157f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, StartBindToDeviceFailure) { 158f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Socket(_, _, _)) 159f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kSocketFD)); 160f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), SetNonBlocking(kSocketFD)) 161f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 162f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), BindToDevice(kSocketFD, StrEq(kInterfaceName))) 163f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(-1)); 164f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Error()) 165f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kErrorNumber)); 166f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Close(kSocketFD)) 167f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 168f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_FALSE(async_connection().Start(ipv4_address(), kConnectPort)); 169f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ExpectReset(); 170f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_STREQ(strerror(kErrorNumber), async_connection().error().c_str()); 171f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 172f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 173f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, SynchronousFailure) { 174f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Socket(_, _, _)) 175f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kSocketFD)); 176f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), SetNonBlocking(kSocketFD)) 177f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 178f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), BindToDevice(kSocketFD, StrEq(kInterfaceName))) 179f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 180f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Connect(kSocketFD, _, _)) 181f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(-1)); 182f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Error()) 183f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .Times(2) 184f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillRepeatedly(Return(0)); 185f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Close(kSocketFD)) 186f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 187f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_FALSE(async_connection().Start(ipv4_address(), kConnectPort)); 188f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ExpectReset(); 189f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 190f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 191f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartMATCHER_P2(IsSocketAddress, address, port, "") { 192f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart const struct sockaddr_in *arg_saddr = 193f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart reinterpret_cast<const struct sockaddr_in *>(arg); 194f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart IPAddress arg_addr(IPAddress::kFamilyIPv4, 195f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ByteString(reinterpret_cast<const unsigned char *>( 196f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart &arg_saddr->sin_addr.s_addr), 197f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart sizeof(arg_saddr->sin_addr.s_addr))); 198f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart return address.Equals(arg_addr) && arg_saddr->sin_port == htons(port); 199f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 200f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 201f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter QiuMATCHER_P2(IsSocketIpv6Address, ipv6_address, port, "") { 202f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu const struct sockaddr_in6 *arg_saddr = 203f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu reinterpret_cast<const struct sockaddr_in6 *>(arg); 204f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu IPAddress arg_addr(IPAddress::kFamilyIPv6, 205f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu ByteString(reinterpret_cast<const unsigned char *>( 206f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu &arg_saddr->sin6_addr.s6_addr), 207f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu sizeof(arg_saddr->sin6_addr.s6_addr))); 208f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu return ipv6_address.Equals(arg_addr) && arg_saddr->sin6_port == htons(port); 209f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu} 210f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu 211f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, SynchronousStart) { 212f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Socket(_, _, _)) 213f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kSocketFD)); 214f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), SetNonBlocking(kSocketFD)) 215f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 216f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), BindToDevice(kSocketFD, StrEq(kInterfaceName))) 217f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 218f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Connect(kSocketFD, 219f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu IsSocketAddress(ipv4_address(), kConnectPort), 220f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart sizeof(struct sockaddr_in))) 221f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(-1)); 222f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(dispatcher(), 2233e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood CreateReadyHandler(kSocketFD, IOHandler::kModeOutput, _)) 224f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(ReturnNew<IOHandler>()); 225f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Error()) 226f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(EINPROGRESS)); 227f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_TRUE(async_connection().Start(ipv4_address(), kConnectPort)); 228f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_EQ(kSocketFD, fd()); 229f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu} 230f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu 231f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter QiuTEST_F(AsyncConnectionTest, SynchronousStartIpv6) { 232f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), Socket(_, _, _)) 233f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(kSocketFD)); 234f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), SetNonBlocking(kSocketFD)) 235f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(0)); 236f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), BindToDevice(kSocketFD, StrEq(kInterfaceName))) 237f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(0)); 238f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), Connect(kSocketFD, 239f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu IsSocketIpv6Address(ipv6_address(), 240f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu kConnectPort), 241f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu sizeof(struct sockaddr_in6))) 242f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(-1)); 243f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(dispatcher(), 244f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu CreateReadyHandler(kSocketFD, IOHandler::kModeOutput, _)) 245f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(ReturnNew<IOHandler>()); 246f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), Error()) 247f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(EINPROGRESS)); 248f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_TRUE(async_connection().Start(ipv6_address(), kConnectPort)); 249f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_EQ(kSocketFD, fd()); 250f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 251f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 252f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, AsynchronousFailure) { 253f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart StartConnection(); 254f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), GetSocketError(kSocketFD)) 255f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(1)); 256f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Error()) 257f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kErrorNumber)); 258f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(callback_target(), CallTarget(false, -1)); 259f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Close(kSocketFD)) 260f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 261f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart OnConnectCompletion(kSocketFD); 262f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ExpectReset(); 263f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_STREQ(strerror(kErrorNumber), async_connection().error().c_str()); 264f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 265f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 266f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, AsynchronousSuccess) { 267f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart StartConnection(); 268f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), GetSocketError(kSocketFD)) 269f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 270f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(callback_target(), CallTarget(true, kSocketFD)); 271f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart OnConnectCompletion(kSocketFD); 272f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ExpectReset(); 273f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 274f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 275f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul StewartTEST_F(AsyncConnectionTest, SynchronousSuccess) { 276f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Socket(_, _, _)) 277f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(kSocketFD)); 278f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), SetNonBlocking(kSocketFD)) 279f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 280f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), BindToDevice(kSocketFD, StrEq(kInterfaceName))) 281f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 282f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(sockets(), Connect(kSocketFD, 283f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu IsSocketAddress(ipv4_address(), kConnectPort), 284f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart sizeof(struct sockaddr_in))) 285f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart .WillOnce(Return(0)); 286f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart EXPECT_CALL(callback_target(), CallTarget(true, kSocketFD)); 287f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_TRUE(async_connection().Start(ipv4_address(), kConnectPort)); 288f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu ExpectReset(); 289f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu} 290f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu 291f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter QiuTEST_F(AsyncConnectionTest, SynchronousSuccessIpv6) { 292f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), Socket(_, _, _)) 293f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(kSocketFD)); 294f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), SetNonBlocking(kSocketFD)) 295f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(0)); 296f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), BindToDevice(kSocketFD, StrEq(kInterfaceName))) 297f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(0)); 298f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(sockets(), Connect(kSocketFD, 299f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu IsSocketIpv6Address(ipv6_address(), 300f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu kConnectPort), 301f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu sizeof(struct sockaddr_in6))) 302f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu .WillOnce(Return(0)); 303f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_CALL(callback_target(), CallTarget(true, kSocketFD)); 304f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu EXPECT_TRUE(async_connection().Start(ipv6_address(), kConnectPort)); 305f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart ExpectReset(); 306f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} 307f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart 3088585b207dc9502256c2a428611e948e105db96b6Paul StewartTEST_F(AsyncConnectionTest, FreeOnSuccessCallback) { 3098585b207dc9502256c2a428611e948e105db96b6Paul Stewart StartConnection(); 3108585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_CALL(sockets(), GetSocketError(kSocketFD)) 3118585b207dc9502256c2a428611e948e105db96b6Paul Stewart .WillOnce(Return(0)); 3128585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_CALL(callback_target(), CallTarget(true, kSocketFD)) 3138585b207dc9502256c2a428611e948e105db96b6Paul Stewart .WillOnce(Invoke(this, &AsyncConnectionTest::InvokeFreeConnection)); 3148585b207dc9502256c2a428611e948e105db96b6Paul Stewart OnConnectCompletion(kSocketFD); 3158585b207dc9502256c2a428611e948e105db96b6Paul Stewart} 3168585b207dc9502256c2a428611e948e105db96b6Paul Stewart 3178585b207dc9502256c2a428611e948e105db96b6Paul StewartTEST_F(AsyncConnectionTest, FreeOnFailureCallback) { 3188585b207dc9502256c2a428611e948e105db96b6Paul Stewart StartConnection(); 3198585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_CALL(sockets(), GetSocketError(kSocketFD)) 3208585b207dc9502256c2a428611e948e105db96b6Paul Stewart .WillOnce(Return(1)); 3218585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_CALL(callback_target(), CallTarget(false, -1)) 3228585b207dc9502256c2a428611e948e105db96b6Paul Stewart .WillOnce(Invoke(this, &AsyncConnectionTest::InvokeFreeConnection)); 3238585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_CALL(sockets(), Error()) 3248585b207dc9502256c2a428611e948e105db96b6Paul Stewart .WillOnce(Return(kErrorNumber)); 3258585b207dc9502256c2a428611e948e105db96b6Paul Stewart EXPECT_CALL(sockets(), Close(kSocketFD)) 3268585b207dc9502256c2a428611e948e105db96b6Paul Stewart .WillOnce(Return(0)); 3278585b207dc9502256c2a428611e948e105db96b6Paul Stewart OnConnectCompletion(kSocketFD); 3288585b207dc9502256c2a428611e948e105db96b6Paul Stewart} 3298585b207dc9502256c2a428611e948e105db96b6Paul Stewart 330f65320cc1c04ea9e09cc8656e87fe9912c601e9aPaul Stewart} // namespace shill 331