blob: 6750648a3f091591d16fd864a31819c245a879ce [file] [log] [blame]
Sergey Ulanov2a0b0192017-08-31 23:09:401// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Sergey Ulanov7de85802018-01-19 19:50:345#include "net/test/tcp_socket_proxy.h"
Sergey Ulanov2a0b0192017-08-31 23:09:406
Carlos Caballerodd8bf7b042019-07-30 14:14:157#include "base/message_loop/message_pump_type.h"
Sergey Ulanov2a0b0192017-08-31 23:09:408#include "base/threading/thread.h"
Rohit Rao77cc1c92018-01-23 19:46:319#include "build/build_config.h"
Sergey Ulanov2a0b0192017-08-31 23:09:4010#include "net/base/io_buffer.h"
11#include "net/base/test_completion_callback.h"
12#include "net/socket/tcp_client_socket.h"
13#include "net/socket/tcp_server_socket.h"
14#include "net/test/gtest_util.h"
Gabriel Charettec7108742019-08-23 03:31:4015#include "net/test/test_with_task_environment.h"
Ramin Halavati0a08cc82018-02-06 07:46:3816#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Sergey Ulanov2a0b0192017-08-31 23:09:4017#include "testing/gmock/include/gmock/gmock.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20using net::test::IsOk;
21
22namespace net {
23
Gabriel Charette694c3c332019-08-19 14:53:0524class TcpSocketProxyTest : public TestWithTaskEnvironment {
Sergey Ulanov2a0b0192017-08-31 23:09:4025 public:
Sergey Ulanov7de85802018-01-19 19:50:3426 TcpSocketProxyTest() : io_thread_("TcpSocketProxyTest IO Thread") {
Sergey Ulanov2a0b0192017-08-31 23:09:4027 EXPECT_TRUE(io_thread_.StartWithOptions(
Carlos Caballerodd8bf7b042019-07-30 14:14:1528 base::Thread::Options(base::MessagePumpType::IO, 0)));
Sergey Ulanov2a0b0192017-08-31 23:09:4029
30 listen_socket_ =
31 std::make_unique<TCPServerSocket>(nullptr, net::NetLogSource());
32 int result =
33 listen_socket_->Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0), 5);
34 EXPECT_THAT(result, IsOk());
35
36 // Get local address.
37 IPEndPoint address;
38 result = listen_socket_->GetLocalAddress(&address);
39 EXPECT_THAT(result, IsOk());
40
Sergey Ulanov7de85802018-01-19 19:50:3441 proxy_ = std::make_unique<TcpSocketProxy>(io_thread_.task_runner());
42 EXPECT_TRUE(proxy_->Initialize());
43
Sergey Ulanov2a0b0192017-08-31 23:09:4044 proxy_address_ =
45 IPEndPoint(IPAddress::IPv4Localhost(), proxy_->local_port());
Sergey Ulanovee7c8db2017-12-08 00:18:3946 proxy_->Start(address);
Sergey Ulanov2a0b0192017-08-31 23:09:4047 }
48
49 void MakeConnection(std::unique_ptr<StreamSocket>* client_socket,
50 std::unique_ptr<StreamSocket>* server_socket) {
51 TestCompletionCallback connect_callback;
52 *client_socket = std::make_unique<TCPClientSocket>(
53 AddressList(proxy_address_), nullptr, nullptr, NetLogSource());
54 int connect_result = (*client_socket)->Connect(connect_callback.callback());
55
56 TestCompletionCallback accept_callback;
57 int result =
58 listen_socket_->Accept(server_socket, accept_callback.callback());
59
60 ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
61 ASSERT_THAT(accept_callback.GetResult(result), IsOk());
62
63 EXPECT_TRUE((*server_socket)->IsConnected());
64 EXPECT_TRUE((*client_socket)->IsConnected());
65 }
66
67 void SendAndReceiveData(StreamSocket* socket1, StreamSocket* socket2) {
68 // Send just one byte to ensure we will need only one Write() and only one
69 // Read().
70 char test_message = '0';
71
Victor Costan9c7302b2018-08-27 16:39:4472 scoped_refptr<IOBuffer> write_buffer = base::MakeRefCounted<IOBuffer>(1);
Sergey Ulanov2a0b0192017-08-31 23:09:4073 *write_buffer->data() = test_message;
74 TestCompletionCallback write_callback;
75 int write_result =
Ramin Halavati0a08cc82018-02-06 07:46:3876 socket1->Write(write_buffer.get(), 1, write_callback.callback(),
77 TRAFFIC_ANNOTATION_FOR_TESTS);
Sergey Ulanov2a0b0192017-08-31 23:09:4078
Victor Costan9c7302b2018-08-27 16:39:4479 scoped_refptr<IOBufferWithSize> read_buffer =
80 base::MakeRefCounted<IOBufferWithSize>(1024);
Sergey Ulanov2a0b0192017-08-31 23:09:4081 TestCompletionCallback read_callback;
82 int read_result = socket2->Read(read_buffer.get(), read_buffer->size(),
83 read_callback.callback());
84
85 ASSERT_EQ(write_callback.GetResult(write_result), 1);
86 ASSERT_EQ(read_callback.GetResult(read_result), 1);
87
88 EXPECT_EQ(test_message, *read_buffer->data());
89 }
90
91 void ExpectClosed(StreamSocket* socket) {
Victor Costan9c7302b2018-08-27 16:39:4492 scoped_refptr<IOBufferWithSize> read_buffer =
93 base::MakeRefCounted<IOBufferWithSize>(1024);
Sergey Ulanov2a0b0192017-08-31 23:09:4094 TestCompletionCallback read_callback;
95 int read_result = socket->Read(read_buffer.get(), read_buffer->size(),
96 read_callback.callback());
97
98 EXPECT_EQ(read_callback.GetResult(read_result), 0);
99 EXPECT_FALSE(socket->IsConnected());
100 }
101
102 protected:
103 base::Thread io_thread_;
104
Sergey Ulanov7de85802018-01-19 19:50:34105 // Server socket that simulates testserver that TcpSocketProxy normally
Sergey Ulanov2a0b0192017-08-31 23:09:40106 // would connect to.
107 std::unique_ptr<TCPServerSocket> listen_socket_;
108
Sergey Ulanov7de85802018-01-19 19:50:34109 std::unique_ptr<TcpSocketProxy> proxy_;
Bence Béky98447b12018-05-08 03:14:01110
111 private:
Sergey Ulanov2a0b0192017-08-31 23:09:40112 IPEndPoint proxy_address_;
113};
114
Sergey Ulanov7de85802018-01-19 19:50:34115TEST_F(TcpSocketProxyTest, SendAndReceive) {
Sergey Ulanov2a0b0192017-08-31 23:09:40116 std::unique_ptr<StreamSocket> client_socket;
117 std::unique_ptr<StreamSocket> server_socket;
118 MakeConnection(&client_socket, &server_socket);
119 SendAndReceiveData(client_socket.get(), server_socket.get());
120 SendAndReceiveData(server_socket.get(), client_socket.get());
121}
122
Sergey Ulanov7de85802018-01-19 19:50:34123TEST_F(TcpSocketProxyTest, TwoConnections) {
Sergey Ulanov2a0b0192017-08-31 23:09:40124 std::unique_ptr<StreamSocket> client_socket1;
125 std::unique_ptr<StreamSocket> server_socket1;
126 MakeConnection(&client_socket1, &server_socket1);
127
128 std::unique_ptr<StreamSocket> client_socket2;
129 std::unique_ptr<StreamSocket> server_socket2;
130 MakeConnection(&client_socket2, &server_socket2);
131
132 SendAndReceiveData(client_socket1.get(), server_socket1.get());
133 SendAndReceiveData(client_socket2.get(), server_socket2.get());
134 SendAndReceiveData(server_socket1.get(), client_socket1.get());
135 SendAndReceiveData(server_socket2.get(), client_socket2.get());
136}
137
138// Close socket on the server side and verify that it's closed on the client
139// side.
Rohit Rao77cc1c92018-01-23 19:46:31140// TODO(crbug.com/804429): This test hangs occasionally on iOS.
141#if defined(OS_IOS)
142#define MAYBE_DisconnectServer DISABLED_DisconnectServer
143#else
144#define MAYBE_DisconnectServer DisconnectServer
145#endif
146TEST_F(TcpSocketProxyTest, MAYBE_DisconnectServer) {
Sergey Ulanov2a0b0192017-08-31 23:09:40147 std::unique_ptr<StreamSocket> client_socket;
148 std::unique_ptr<StreamSocket> server_socket;
149 MakeConnection(&client_socket, &server_socket);
150 server_socket.reset();
151 ExpectClosed(client_socket.get());
152}
153
154// Close socket on the client side and verify that it's closed on the server
155// side.
Rohit Rao77cc1c92018-01-23 19:46:31156// TODO(crbug.com/804429): This test hangs occasionally on iOS.
157#if defined(OS_IOS)
158#define MAYBE_DisconnectClient DISABLED_DisconnectClient
159#else
160#define MAYBE_DisconnectClient DisconnectClient
161#endif
162TEST_F(TcpSocketProxyTest, MAYBE_DisconnectClient) {
Sergey Ulanov2a0b0192017-08-31 23:09:40163 std::unique_ptr<StreamSocket> client_socket;
164 std::unique_ptr<StreamSocket> server_socket;
165 MakeConnection(&client_socket, &server_socket);
166 client_socket.reset();
167 ExpectClosed(server_socket.get());
168}
169
Sergey Ulanov7de85802018-01-19 19:50:34170// Initialize() must fail if the port is in use.
171TEST_F(TcpSocketProxyTest, PortInUse) {
172 // Try initializing second proxy on the same port.
173 auto proxy2 = std::make_unique<TcpSocketProxy>(io_thread_.task_runner());
174 EXPECT_FALSE(proxy2->Initialize(proxy_->local_port()));
175}
176
Sergey Ulanov2a0b0192017-08-31 23:09:40177} // namespace net