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

Side by Side Diff: net/base/listen_socket_unittest.cc

Issue 10108015: Upstream changes making ListenSocket an abstract class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add listen_socket.cc. Created 8 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/listen_socket_unittest.h ('k') | net/base/tcp_listen_socket.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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
5 #include "net/base/listen_socket_unittest.h"
6
7 #include <fcntl.h>
8 #include <sys/types.h>
9
10 #include "base/bind.h"
11 #include "base/eintr_wrapper.h"
12 #include "base/sys_byteorder.h"
13 #include "net/base/net_util.h"
14 #include "testing/platform_test.h"
15
16 namespace net {
17
18 const int ListenSocketTester::kTestPort = 9999;
19
20 static const int kReadBufSize = 1024;
21 static const char kHelloWorld[] = "HELLO, WORLD";
22 static const int kMaxQueueSize = 20;
23 static const char kLoopback[] = "127.0.0.1";
24 static const int kDefaultTimeoutMs = 5000;
25
26 ListenSocketTester::ListenSocketTester()
27 : thread_(NULL),
28 loop_(NULL),
29 server_(NULL),
30 connection_(NULL),
31 cv_(&lock_) {
32 }
33
34 void ListenSocketTester::SetUp() {
35 base::Thread::Options options;
36 options.message_loop_type = MessageLoop::TYPE_IO;
37 thread_.reset(new base::Thread("socketio_test"));
38 thread_->StartWithOptions(options);
39 loop_ = reinterpret_cast<MessageLoopForIO*>(thread_->message_loop());
40
41 loop_->PostTask(FROM_HERE, base::Bind(&ListenSocketTester::Listen, this));
42
43 // verify Listen succeeded
44 NextAction();
45 ASSERT_FALSE(server_ == NULL);
46 ASSERT_EQ(ACTION_LISTEN, last_action_.type());
47
48 // verify the connect/accept and setup test_socket_
49 test_socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
50 ASSERT_NE(INVALID_SOCKET, test_socket_);
51 struct sockaddr_in client;
52 client.sin_family = AF_INET;
53 client.sin_addr.s_addr = inet_addr(kLoopback);
54 client.sin_port = base::HostToNet16(kTestPort);
55 int ret = HANDLE_EINTR(
56 connect(test_socket_, reinterpret_cast<sockaddr*>(&client),
57 sizeof(client)));
58 ASSERT_NE(ret, SOCKET_ERROR);
59
60 NextAction();
61 ASSERT_EQ(ACTION_ACCEPT, last_action_.type());
62 }
63
64 void ListenSocketTester::TearDown() {
65 #if defined(OS_WIN)
66 ASSERT_EQ(0, closesocket(test_socket_));
67 #elif defined(OS_POSIX)
68 ASSERT_EQ(0, HANDLE_EINTR(close(test_socket_)));
69 #endif
70 NextAction();
71 ASSERT_EQ(ACTION_CLOSE, last_action_.type());
72
73 loop_->PostTask(FROM_HERE, base::Bind(&ListenSocketTester::Shutdown, this));
74 NextAction();
75 ASSERT_EQ(ACTION_SHUTDOWN, last_action_.type());
76
77 thread_.reset();
78 loop_ = NULL;
79 }
80
81 void ListenSocketTester::ReportAction(const ListenSocketTestAction& action) {
82 base::AutoLock locked(lock_);
83 queue_.push_back(action);
84 cv_.Broadcast();
85 }
86
87 void ListenSocketTester::NextAction() {
88 base::AutoLock locked(lock_);
89 while (queue_.empty())
90 cv_.Wait();
91 last_action_ = queue_.front();
92 queue_.pop_front();
93 }
94
95 int ListenSocketTester::ClearTestSocket() {
96 char buf[kReadBufSize];
97 int len_ret = 0;
98 do {
99 int len = HANDLE_EINTR(recv(test_socket_, buf, kReadBufSize, 0));
100 if (len == SOCKET_ERROR || len == 0) {
101 break;
102 } else {
103 len_ret += len;
104 }
105 } while (true);
106 return len_ret;
107 }
108
109 void ListenSocketTester::Shutdown() {
110 connection_->Release();
111 connection_ = NULL;
112 server_->Release();
113 server_ = NULL;
114 ReportAction(ListenSocketTestAction(ACTION_SHUTDOWN));
115 }
116
117 void ListenSocketTester::Listen() {
118 server_ = DoListen();
119 if (server_) {
120 server_->AddRef();
121 ReportAction(ListenSocketTestAction(ACTION_LISTEN));
122 }
123 }
124
125 void ListenSocketTester::SendFromTester() {
126 connection_->Send(kHelloWorld);
127 ReportAction(ListenSocketTestAction(ACTION_SEND));
128 }
129
130 void ListenSocketTester::TestClientSend() {
131 ASSERT_TRUE(Send(test_socket_, kHelloWorld));
132 NextAction();
133 ASSERT_EQ(ACTION_READ, last_action_.type());
134 ASSERT_EQ(last_action_.data(), kHelloWorld);
135 }
136
137 void ListenSocketTester::TestClientSendLong() {
138 size_t hello_len = strlen(kHelloWorld);
139 std::string long_string;
140 size_t long_len = 0;
141 for (int i = 0; i < 200; i++) {
142 long_string += kHelloWorld;
143 long_len += hello_len;
144 }
145 ASSERT_TRUE(Send(test_socket_, long_string));
146 size_t read_len = 0;
147 while (read_len < long_len) {
148 NextAction();
149 ASSERT_EQ(ACTION_READ, last_action_.type());
150 std::string last_data = last_action_.data();
151 size_t len = last_data.length();
152 if (long_string.compare(read_len, len, last_data)) {
153 ASSERT_EQ(long_string.compare(read_len, len, last_data), 0);
154 }
155 read_len += last_data.length();
156 }
157 ASSERT_EQ(read_len, long_len);
158 }
159
160 void ListenSocketTester::TestServerSend() {
161 loop_->PostTask(FROM_HERE, base::Bind(
162 &ListenSocketTester::SendFromTester, this));
163 NextAction();
164 ASSERT_EQ(ACTION_SEND, last_action_.type());
165 const int buf_len = 200;
166 char buf[buf_len+1];
167 unsigned recv_len = 0;
168 while (recv_len < strlen(kHelloWorld)) {
169 int r = HANDLE_EINTR(recv(test_socket_, buf, buf_len, 0));
170 ASSERT_GE(r, 0);
171 recv_len += static_cast<unsigned>(r);
172 if (!r)
173 break;
174 }
175 buf[recv_len] = 0;
176 ASSERT_STREQ(buf, kHelloWorld);
177 }
178
179 bool ListenSocketTester::Send(SOCKET sock, const std::string& str) {
180 int len = static_cast<int>(str.length());
181 int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0));
182 if (send_len == SOCKET_ERROR) {
183 LOG(ERROR) << "send failed: " << errno;
184 return false;
185 } else if (send_len != len) {
186 return false;
187 }
188 return true;
189 }
190
191 void ListenSocketTester::DidAccept(ListenSocket *server,
192 ListenSocket *connection) {
193 connection_ = connection;
194 connection_->AddRef();
195 ReportAction(ListenSocketTestAction(ACTION_ACCEPT));
196 }
197
198 void ListenSocketTester::DidRead(ListenSocket *connection,
199 const char* data,
200 int len) {
201 std::string str(data, len);
202 ReportAction(ListenSocketTestAction(ACTION_READ, str));
203 }
204
205 void ListenSocketTester::DidClose(ListenSocket *sock) {
206 ReportAction(ListenSocketTestAction(ACTION_CLOSE));
207 }
208
209 ListenSocketTester::~ListenSocketTester() {}
210
211 ListenSocket* ListenSocketTester::DoListen() {
212 return ListenSocket::Listen(kLoopback, kTestPort, this);
213 }
214
215 class ListenSocketTest: public PlatformTest {
216 public:
217 ListenSocketTest() {
218 tester_ = NULL;
219 }
220
221 virtual void SetUp() {
222 PlatformTest::SetUp();
223 tester_ = new ListenSocketTester();
224 tester_->SetUp();
225 }
226
227 virtual void TearDown() {
228 PlatformTest::TearDown();
229 tester_->TearDown();
230 tester_ = NULL;
231 }
232
233 scoped_refptr<ListenSocketTester> tester_;
234 };
235
236 TEST_F(ListenSocketTest, ClientSend) {
237 tester_->TestClientSend();
238 }
239
240 TEST_F(ListenSocketTest, ClientSendLong) {
241 tester_->TestClientSendLong();
242 }
243
244 TEST_F(ListenSocketTest, ServerSend) {
245 tester_->TestServerSend();
246 }
247
248 } // namespace net
OLDNEW
« no previous file with comments | « net/base/listen_socket_unittest.h ('k') | net/base/tcp_listen_socket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698