Update CrOS OOBE throbber to MD throbber; delete old asset
[chromium-blink-merge.git] / chrome / test / chromedriver / net / port_server_unittest.cc
blobd711710e5469227998bed6172ecb06ff634964db
1 // Copyright (c) 2013 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.
5 #include <string>
7 #include "base/bind.h"
8 #include "base/guid.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/sync_socket.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/threading/thread.h"
14 #include "base/time/time.h"
15 #include "chrome/test/chromedriver/chrome/status.h"
16 #include "chrome/test/chromedriver/net/port_server.h"
17 #include "net/base/sys_addrinfo.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 #if defined(OS_LINUX)
21 #include <fcntl.h>
22 #include <sys/socket.h>
23 #include <sys/un.h>
24 #endif
26 namespace {
28 void SetOnCall(bool* called) {
29 *called = true;
32 } // namespace
34 TEST(PortReservationTest, Normal) {
35 bool called = false;
37 PortReservation r(base::Bind(&SetOnCall, &called), 100);
39 ASSERT_TRUE(called);
42 TEST(PortReservationTest, Leak) {
43 bool called = false;
45 PortReservation r(base::Bind(&SetOnCall, &called), 100);
46 r.Leak();
48 ASSERT_FALSE(called);
51 TEST(PortReservationTest, MultipleLeaks) {
52 bool called = false;
54 PortReservation r(base::Bind(&SetOnCall, &called), 100);
55 r.Leak();
56 r.Leak();
58 ASSERT_FALSE(called);
61 #if defined(OS_LINUX)
62 namespace {
64 void RunServerOnThread(const std::string& path,
65 const std::string& response,
66 base::WaitableEvent* listen_event,
67 std::string* request) {
68 int server_sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
69 ASSERT_GE(server_sock_fd, 0);
70 ASSERT_GE(fcntl(server_sock_fd, F_SETFL, O_NONBLOCK), 0);
71 base::SyncSocket server_sock(server_sock_fd);
73 struct sockaddr_un addr;
74 memset(&addr, 0, sizeof(addr));
75 addr.sun_family = AF_UNIX;
76 memcpy(addr.sun_path, &path[0], path.length());
77 ASSERT_EQ(0,
78 bind(server_sock_fd,
79 reinterpret_cast<struct sockaddr*>(&addr),
80 sizeof(sa_family_t) + path.length()));
81 ASSERT_EQ(0, listen(server_sock_fd, 1));
82 listen_event->Signal();
84 struct sockaddr_un cli_addr;
85 socklen_t clilen = sizeof(cli_addr);
86 base::TimeTicks deadline =
87 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(2);
88 int client_sock_fd = -1;
89 while (base::TimeTicks::Now() < deadline && client_sock_fd < 0) {
90 client_sock_fd = accept(
91 server_sock_fd, reinterpret_cast<struct sockaddr*>(&cli_addr), &clilen);
93 ASSERT_GE(client_sock_fd, 0);
94 base::SyncSocket sock(client_sock_fd);
95 do {
96 char c = 0;
97 size_t rv = sock.Receive(&c, 1);
98 if (!rv)
99 break;
100 request->push_back(c);
101 } while (sock.Peek());
102 sock.Send(response.c_str(), response.length());
105 std::string GenerateRandomPath() {
106 std::string path = base::GenerateGUID();
107 if (!path.empty()) {
108 std::string pre_path;
109 pre_path.push_back(0); // Linux abstract namespace.
110 path = pre_path + path;
112 return path;
115 } // namespace
117 class PortServerTest : public testing::Test {
118 public:
119 PortServerTest() : thread_("server") {
120 EXPECT_TRUE(thread_.Start());
123 void RunServer(const std::string& path,
124 const std::string& response,
125 std::string* request) {
126 base::WaitableEvent listen_event(false, false);
127 thread_.task_runner()->PostTask(
128 FROM_HERE,
129 base::Bind(&RunServerOnThread, path, response, &listen_event, request));
130 ASSERT_TRUE(listen_event.TimedWait(base::TimeDelta::FromSeconds(5)));
133 private:
134 base::Thread thread_;
137 TEST_F(PortServerTest, Reserve) {
138 std::string path = GenerateRandomPath();
139 PortServer server(path);
141 std::string request;
142 RunServer(path, "12345\n", &request);
144 uint16 port = 0;
145 scoped_ptr<PortReservation> reservation;
146 Status status = server.ReservePort(&port, &reservation);
147 ASSERT_EQ(kOk, status.code()) << status.message();
148 ASSERT_EQ(12345u, port);
151 TEST_F(PortServerTest, ReserveResetReserve) {
152 std::string path = GenerateRandomPath();
153 PortServer server(path);
155 std::string request;
156 RunServer(path, "12345\n", &request);
158 uint16 port = 0;
159 scoped_ptr<PortReservation> reservation;
160 Status status = server.ReservePort(&port, &reservation);
161 ASSERT_EQ(kOk, status.code()) << status.message();
162 ASSERT_EQ(12345u, port);
164 reservation.reset();
165 status = server.ReservePort(&port, &reservation);
166 ASSERT_EQ(kOk, status.code()) << status.message();
167 ASSERT_EQ(12345u, port);
170 TEST_F(PortServerTest, ReserveReserve) {
171 std::string path = GenerateRandomPath();
172 PortServer server(path);
174 std::string request;
175 RunServer(path, "12345\n", &request);
177 uint16 port = 0;
178 scoped_ptr<PortReservation> reservation;
179 Status status = server.ReservePort(&port, &reservation);
180 ASSERT_EQ(kOk, status.code()) << status.message();
181 ASSERT_EQ(12345u, port);
183 RunServer(path, "12346\n", &request);
184 status = server.ReservePort(&port, &reservation);
185 ASSERT_EQ(kOk, status.code()) << status.message();
186 ASSERT_EQ(12346u, port);
188 #endif
190 TEST(PortManagerTest, ReservePort) {
191 PortManager mgr(15000, 16000);
192 uint16 port = 0;
193 scoped_ptr<PortReservation> reservation;
194 Status status = mgr.ReservePort(&port, &reservation);
195 ASSERT_EQ(kOk, status.code()) << status.message();
197 ASSERT_GE(port, 15000);
198 ASSERT_LE(port, 16000);
199 ASSERT_TRUE(reservation);
202 TEST(PortManagerTest, ReservePortFromPool) {
203 PortManager mgr(15000, 16000);
204 uint16 first_port = 0, port = 1;
205 for (int i = 0; i < 10; i++) {
206 scoped_ptr<PortReservation> reservation;
207 Status status = mgr.ReservePortFromPool(&port, &reservation);
208 ASSERT_EQ(kOk, status.code()) << status.message();
209 ASSERT_TRUE(reservation);
210 ASSERT_GE(port, 15000);
211 ASSERT_LE(port, 16000);
212 if (i == 0)
213 first_port = port;
214 ASSERT_EQ(port, first_port);