blob: c53441d1a055bdc5cf580b3ed873d7d2c6704936 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <signal.h>
12#include <stdarg.h>
13
14#include "webrtc/base/gunit.h"
15#include "webrtc/base/logging.h"
16#include "webrtc/base/physicalsocketserver.h"
17#include "webrtc/base/scoped_ptr.h"
18#include "webrtc/base/socket_unittest.h"
19#include "webrtc/base/testutils.h"
20#include "webrtc/base/thread.h"
21
22namespace rtc {
23
jbauch095ae152015-12-18 01:39:55 -080024class PhysicalSocketTest;
25
26class FakeSocketDispatcher : public SocketDispatcher {
27 public:
28 explicit FakeSocketDispatcher(PhysicalSocketServer* ss)
29 : SocketDispatcher(ss) {
30 }
31
jbauchf2a2bf42016-02-03 16:45:32 -080032 FakeSocketDispatcher(SOCKET s, PhysicalSocketServer* ss)
33 : SocketDispatcher(s, ss) {
34 }
35
jbauch095ae152015-12-18 01:39:55 -080036 protected:
37 SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override;
jbauchf2a2bf42016-02-03 16:45:32 -080038 int DoSend(SOCKET socket, const char* buf, int len, int flags) override;
39 int DoSendTo(SOCKET socket, const char* buf, int len, int flags,
40 const struct sockaddr* dest_addr, socklen_t addrlen) override;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000041};
42
jbauch095ae152015-12-18 01:39:55 -080043class FakePhysicalSocketServer : public PhysicalSocketServer {
44 public:
45 explicit FakePhysicalSocketServer(PhysicalSocketTest* test)
46 : test_(test) {
47 }
48
49 AsyncSocket* CreateAsyncSocket(int type) override {
50 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
jbauchf2a2bf42016-02-03 16:45:32 -080051 if (!dispatcher->Create(type)) {
jbauch095ae152015-12-18 01:39:55 -080052 delete dispatcher;
53 return nullptr;
54 }
jbauchf2a2bf42016-02-03 16:45:32 -080055 return dispatcher;
jbauch095ae152015-12-18 01:39:55 -080056 }
57
58 AsyncSocket* CreateAsyncSocket(int family, int type) override {
59 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
jbauchf2a2bf42016-02-03 16:45:32 -080060 if (!dispatcher->Create(family, type)) {
jbauch095ae152015-12-18 01:39:55 -080061 delete dispatcher;
62 return nullptr;
63 }
jbauchf2a2bf42016-02-03 16:45:32 -080064 return dispatcher;
65 }
66
67 AsyncSocket* WrapSocket(SOCKET s) override {
68 SocketDispatcher* dispatcher = new FakeSocketDispatcher(s, this);
69 if (!dispatcher->Initialize()) {
70 delete dispatcher;
71 return nullptr;
72 }
73 return dispatcher;
jbauch095ae152015-12-18 01:39:55 -080074 }
75
76 PhysicalSocketTest* GetTest() const { return test_; }
77
78 private:
79 PhysicalSocketTest* test_;
80};
81
82class PhysicalSocketTest : public SocketTest {
83 public:
84 // Set flag to simluate failures when calling "::accept" on a AsyncSocket.
85 void SetFailAccept(bool fail) { fail_accept_ = fail; }
86 bool FailAccept() const { return fail_accept_; }
87
jbauchf2a2bf42016-02-03 16:45:32 -080088 // Maximum size to ::send to a socket. Set to < 0 to disable limiting.
89 void SetMaxSendSize(int max_size) { max_send_size_ = max_size; }
90 int MaxSendSize() const { return max_send_size_; }
91
jbauch095ae152015-12-18 01:39:55 -080092 protected:
93 PhysicalSocketTest()
94 : server_(new FakePhysicalSocketServer(this)),
95 scope_(server_.get()),
jbauchf2a2bf42016-02-03 16:45:32 -080096 fail_accept_(false),
97 max_send_size_(-1) {
jbauch095ae152015-12-18 01:39:55 -080098 }
99
100 void ConnectInternalAcceptError(const IPAddress& loopback);
jbauchf2a2bf42016-02-03 16:45:32 -0800101 void WritableAfterPartialWrite(const IPAddress& loopback);
jbauch095ae152015-12-18 01:39:55 -0800102
103 rtc::scoped_ptr<FakePhysicalSocketServer> server_;
104 SocketServerScope scope_;
105 bool fail_accept_;
jbauchf2a2bf42016-02-03 16:45:32 -0800106 int max_send_size_;
jbauch095ae152015-12-18 01:39:55 -0800107};
108
109SOCKET FakeSocketDispatcher::DoAccept(SOCKET socket,
110 sockaddr* addr,
111 socklen_t* addrlen) {
112 FakePhysicalSocketServer* ss =
113 static_cast<FakePhysicalSocketServer*>(socketserver());
114 if (ss->GetTest()->FailAccept()) {
115 return INVALID_SOCKET;
116 }
117
118 return SocketDispatcher::DoAccept(socket, addr, addrlen);
119}
120
jbauchf2a2bf42016-02-03 16:45:32 -0800121int FakeSocketDispatcher::DoSend(SOCKET socket, const char* buf, int len,
122 int flags) {
123 FakePhysicalSocketServer* ss =
124 static_cast<FakePhysicalSocketServer*>(socketserver());
125 if (ss->GetTest()->MaxSendSize() >= 0) {
126 len = std::min(len, ss->GetTest()->MaxSendSize());
127 }
128
129 return SocketDispatcher::DoSend(socket, buf, len, flags);
130}
131
132int FakeSocketDispatcher::DoSendTo(SOCKET socket, const char* buf, int len,
133 int flags, const struct sockaddr* dest_addr, socklen_t addrlen) {
134 FakePhysicalSocketServer* ss =
135 static_cast<FakePhysicalSocketServer*>(socketserver());
136 if (ss->GetTest()->MaxSendSize() >= 0) {
137 len = std::min(len, ss->GetTest()->MaxSendSize());
138 }
139
140 return SocketDispatcher::DoSendTo(socket, buf, len, flags, dest_addr,
141 addrlen);
142}
143
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000144TEST_F(PhysicalSocketTest, TestConnectIPv4) {
145 SocketTest::TestConnectIPv4();
146}
147
minyue5d696482015-08-19 04:42:03 -0700148// Crashes on Linux. See webrtc:4923.
149#if defined(WEBRTC_LINUX)
150#define MAYBE_TestConnectIPv6 DISABLED_TestConnectIPv6
151#else
152#define MAYBE_TestConnectIPv6 TestConnectIPv6
153#endif
154TEST_F(PhysicalSocketTest, MAYBE_TestConnectIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000155 SocketTest::TestConnectIPv6();
156}
157
158TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
159 SocketTest::TestConnectWithDnsLookupIPv4();
160}
161
162TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
163 SocketTest::TestConnectWithDnsLookupIPv6();
164}
165
166TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
167 SocketTest::TestConnectFailIPv4();
168}
169
jbauch095ae152015-12-18 01:39:55 -0800170void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) {
171 testing::StreamSink sink;
172 SocketAddress accept_addr;
173
174 // Create two clients.
175 scoped_ptr<AsyncSocket> client1(server_->CreateAsyncSocket(loopback.family(),
176 SOCK_STREAM));
177 sink.Monitor(client1.get());
178 EXPECT_EQ(AsyncSocket::CS_CLOSED, client1->GetState());
179 EXPECT_PRED1(IsUnspecOrEmptyIP, client1->GetLocalAddress().ipaddr());
180
181 scoped_ptr<AsyncSocket> client2(server_->CreateAsyncSocket(loopback.family(),
182 SOCK_STREAM));
183 sink.Monitor(client2.get());
184 EXPECT_EQ(AsyncSocket::CS_CLOSED, client2->GetState());
185 EXPECT_PRED1(IsUnspecOrEmptyIP, client2->GetLocalAddress().ipaddr());
186
187 // Create server and listen.
188 scoped_ptr<AsyncSocket> server(
189 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
190 sink.Monitor(server.get());
191 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
192 EXPECT_EQ(0, server->Listen(5));
193 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
194
195 // Ensure no pending server connections, since we haven't done anything yet.
196 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
197 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
198 EXPECT_TRUE(accept_addr.IsNil());
199
200 // Attempt first connect to listening socket.
201 EXPECT_EQ(0, client1->Connect(server->GetLocalAddress()));
202 EXPECT_FALSE(client1->GetLocalAddress().IsNil());
203 EXPECT_NE(server->GetLocalAddress(), client1->GetLocalAddress());
204
205 // Client is connecting, outcome not yet determined.
206 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client1->GetState());
207 EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_OPEN));
208 EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_CLOSE));
209
210 // Server has pending connection, try to accept it (will fail).
211 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
212 // Simulate "::accept" returning an error.
213 SetFailAccept(true);
214 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
215 EXPECT_FALSE(accepted);
216 ASSERT_TRUE(accept_addr.IsNil());
217
218 // Ensure no more pending server connections.
219 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
220 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
221 EXPECT_TRUE(accept_addr.IsNil());
222
223 // Attempt second connect to listening socket.
224 EXPECT_EQ(0, client2->Connect(server->GetLocalAddress()));
225 EXPECT_FALSE(client2->GetLocalAddress().IsNil());
226 EXPECT_NE(server->GetLocalAddress(), client2->GetLocalAddress());
227
228 // Client is connecting, outcome not yet determined.
229 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client2->GetState());
230 EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_OPEN));
231 EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_CLOSE));
232
233 // Server has pending connection, try to accept it (will succeed).
234 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
235 SetFailAccept(false);
236 scoped_ptr<AsyncSocket> accepted2(server->Accept(&accept_addr));
237 ASSERT_TRUE(accepted2);
238 EXPECT_FALSE(accept_addr.IsNil());
239 EXPECT_EQ(accepted2->GetRemoteAddress(), accept_addr);
240}
241
242TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv4) {
243 ConnectInternalAcceptError(kIPv4Loopback);
244}
245
246// Crashes on Linux. See webrtc:4923.
247#if defined(WEBRTC_LINUX)
248#define MAYBE_TestConnectAcceptErrorIPv6 DISABLED_TestConnectAcceptErrorIPv6
249#else
250#define MAYBE_TestConnectAcceptErrorIPv6 TestConnectAcceptErrorIPv6
251#endif
252TEST_F(PhysicalSocketTest, MAYBE_TestConnectAcceptErrorIPv6) {
253 ConnectInternalAcceptError(kIPv6Loopback);
254}
255
jbauchf2a2bf42016-02-03 16:45:32 -0800256void PhysicalSocketTest::WritableAfterPartialWrite(const IPAddress& loopback) {
257 // Simulate a really small maximum send size.
258 const int kMaxSendSize = 128;
259 SetMaxSendSize(kMaxSendSize);
260
261 // Run the default send/receive socket tests with a smaller amount of data
262 // to avoid long running times due to the small maximum send size.
263 const size_t kDataSize = 128 * 1024;
264 TcpInternal(loopback, kDataSize, kMaxSendSize);
265}
266
267TEST_F(PhysicalSocketTest, TestWritableAfterPartialWriteIPv4) {
268 WritableAfterPartialWrite(kIPv4Loopback);
269}
270
271// Crashes on Linux. See webrtc:4923.
272#if defined(WEBRTC_LINUX)
273#define MAYBE_TestWritableAfterPartialWriteIPv6 \
274 DISABLED_TestWritableAfterPartialWriteIPv6
275#else
276#define MAYBE_TestWritableAfterPartialWriteIPv6 \
277 TestWritableAfterPartialWriteIPv6
278#endif
279TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv6) {
280 WritableAfterPartialWrite(kIPv6Loopback);
281}
282
minyue5d696482015-08-19 04:42:03 -0700283// Crashes on Linux. See webrtc:4923.
284#if defined(WEBRTC_LINUX)
285#define MAYBE_TestConnectFailIPv6 DISABLED_TestConnectFailIPv6
286#else
287#define MAYBE_TestConnectFailIPv6 TestConnectFailIPv6
288#endif
289TEST_F(PhysicalSocketTest, MAYBE_TestConnectFailIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000290 SocketTest::TestConnectFailIPv6();
291}
292
293TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
294 SocketTest::TestConnectWithDnsLookupFailIPv4();
295}
296
minyue5d696482015-08-19 04:42:03 -0700297// Crashes on Linux. See webrtc:4923.
298#if defined(WEBRTC_LINUX)
299#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
300 DISABLED_TestConnectWithDnsLookupFailIPv6
301#else
302#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
303 TestConnectWithDnsLookupFailIPv6
304#endif
305TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithDnsLookupFailIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000306 SocketTest::TestConnectWithDnsLookupFailIPv6();
307}
308
309
310TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
311 SocketTest::TestConnectWithClosedSocketIPv4();
312}
313
minyue5d696482015-08-19 04:42:03 -0700314// Crashes on Linux. See webrtc:4923.
315#if defined(WEBRTC_LINUX)
316#define MAYBE_TestConnectWithClosedSocketIPv6 \
317 DISABLED_TestConnectWithClosedSocketIPv6
318#else
319#define MAYBE_TestConnectWithClosedSocketIPv6 TestConnectWithClosedSocketIPv6
320#endif
321TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithClosedSocketIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000322 SocketTest::TestConnectWithClosedSocketIPv6();
323}
324
325TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
326 SocketTest::TestConnectWhileNotClosedIPv4();
327}
328
minyue5d696482015-08-19 04:42:03 -0700329// Crashes on Linux. See webrtc:4923.
330#if defined(WEBRTC_LINUX)
331#define MAYBE_TestConnectWhileNotClosedIPv6 \
332 DISABLED_TestConnectWhileNotClosedIPv6
333#else
334#define MAYBE_TestConnectWhileNotClosedIPv6 TestConnectWhileNotClosedIPv6
335#endif
336TEST_F(PhysicalSocketTest, MAYBE_TestConnectWhileNotClosedIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000337 SocketTest::TestConnectWhileNotClosedIPv6();
338}
339
340TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
341 SocketTest::TestServerCloseDuringConnectIPv4();
342}
343
minyue5d696482015-08-19 04:42:03 -0700344// Crashes on Linux. See webrtc:4923.
345#if defined(WEBRTC_LINUX)
346#define MAYBE_TestServerCloseDuringConnectIPv6 \
347 DISABLED_TestServerCloseDuringConnectIPv6
348#else
349#define MAYBE_TestServerCloseDuringConnectIPv6 TestServerCloseDuringConnectIPv6
350#endif
351TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseDuringConnectIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000352 SocketTest::TestServerCloseDuringConnectIPv6();
353}
354
355TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
356 SocketTest::TestClientCloseDuringConnectIPv4();
357}
358
minyue5d696482015-08-19 04:42:03 -0700359// Crashes on Linux. See webrtc:4923.
360#if defined(WEBRTC_LINUX)
361#define MAYBE_TestClientCloseDuringConnectIPv6 \
362 DISABLED_TestClientCloseDuringConnectIPv6
363#else
364#define MAYBE_TestClientCloseDuringConnectIPv6 TestClientCloseDuringConnectIPv6
365#endif
366TEST_F(PhysicalSocketTest, MAYBE_TestClientCloseDuringConnectIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000367 SocketTest::TestClientCloseDuringConnectIPv6();
368}
369
370TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
371 SocketTest::TestServerCloseIPv4();
372}
373
minyue5d696482015-08-19 04:42:03 -0700374// Crashes on Linux. See webrtc:4923.
375#if defined(WEBRTC_LINUX)
376#define MAYBE_TestServerCloseIPv6 DISABLED_TestServerCloseIPv6
377#else
378#define MAYBE_TestServerCloseIPv6 TestServerCloseIPv6
379#endif
380TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000381 SocketTest::TestServerCloseIPv6();
382}
383
384TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
385 SocketTest::TestCloseInClosedCallbackIPv4();
386}
387
minyue5d696482015-08-19 04:42:03 -0700388// Crashes on Linux. See webrtc:4923.
389#if defined(WEBRTC_LINUX)
390#define MAYBE_TestCloseInClosedCallbackIPv6 \
391 DISABLED_TestCloseInClosedCallbackIPv6
392#else
393#define MAYBE_TestCloseInClosedCallbackIPv6 TestCloseInClosedCallbackIPv6
394#endif
395TEST_F(PhysicalSocketTest, MAYBE_TestCloseInClosedCallbackIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000396 SocketTest::TestCloseInClosedCallbackIPv6();
397}
398
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000399TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000400 SocketTest::TestSocketServerWaitIPv4();
401}
402
minyue5d696482015-08-19 04:42:03 -0700403// Crashes on Linux. See webrtc:4923.
404#if defined(WEBRTC_LINUX)
405#define MAYBE_TestSocketServerWaitIPv6 DISABLED_TestSocketServerWaitIPv6
406#else
407#define MAYBE_TestSocketServerWaitIPv6 TestSocketServerWaitIPv6
408#endif
409TEST_F(PhysicalSocketTest, MAYBE_TestSocketServerWaitIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000410 SocketTest::TestSocketServerWaitIPv6();
411}
412
413TEST_F(PhysicalSocketTest, TestTcpIPv4) {
414 SocketTest::TestTcpIPv4();
415}
416
minyue5d696482015-08-19 04:42:03 -0700417// Crashes on Linux. See webrtc:4923.
418#if defined(WEBRTC_LINUX)
419#define MAYBE_TestTcpIPv6 DISABLED_TestTcpIPv6
420#else
421#define MAYBE_TestTcpIPv6 TestTcpIPv6
422#endif
423TEST_F(PhysicalSocketTest, MAYBE_TestTcpIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000424 SocketTest::TestTcpIPv6();
425}
426
427TEST_F(PhysicalSocketTest, TestUdpIPv4) {
428 SocketTest::TestUdpIPv4();
429}
430
minyue5d696482015-08-19 04:42:03 -0700431// Crashes on Linux. See webrtc:4923.
432#if defined(WEBRTC_LINUX)
433#define MAYBE_TestUdpIPv6 DISABLED_TestUdpIPv6
434#else
435#define MAYBE_TestUdpIPv6 TestUdpIPv6
436#endif
437TEST_F(PhysicalSocketTest, MAYBE_TestUdpIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000438 SocketTest::TestUdpIPv6();
439}
440
henrike@webrtc.org6f833c32014-06-27 16:21:49 +0000441// Disable for TSan v2, see
442// https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
deadbeefc97be6a2015-09-25 11:00:38 -0700443// Also disable for MSan, see:
444// https://code.google.com/p/webrtc/issues/detail?id=4958
445// TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
minyuedf200d12015-10-17 13:10:46 -0700446// Also disable for ASan.
Henrik Kjellander0be3e042015-10-30 21:21:03 +0100447// Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
ivocf399f212015-11-19 06:44:32 -0800448// Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233
minyuedf200d12015-10-17 13:10:46 -0700449#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
ivocf399f212015-11-19 06:44:32 -0800450 defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) || \
451 defined(WEBRTC_LINUX)
minyuedf200d12015-10-17 13:10:46 -0700452#define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
453#else
454#define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
455#endif
456TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000457 SocketTest::TestUdpReadyToSendIPv4();
458}
459
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000460TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000461 SocketTest::TestUdpReadyToSendIPv6();
462}
463
464TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
465 SocketTest::TestGetSetOptionsIPv4();
466}
467
468TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
469 SocketTest::TestGetSetOptionsIPv6();
470}
471
472#if defined(WEBRTC_POSIX)
473
474class PosixSignalDeliveryTest : public testing::Test {
475 public:
476 static void RecordSignal(int signum) {
477 signals_received_.push_back(signum);
478 signaled_thread_ = Thread::Current();
479 }
480
481 protected:
482 void SetUp() {
483 ss_.reset(new PhysicalSocketServer());
484 }
485
486 void TearDown() {
487 ss_.reset(NULL);
488 signals_received_.clear();
489 signaled_thread_ = NULL;
490 }
491
492 bool ExpectSignal(int signum) {
493 if (signals_received_.empty()) {
494 LOG(LS_ERROR) << "ExpectSignal(): No signal received";
495 return false;
496 }
497 if (signals_received_[0] != signum) {
498 LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
499 signals_received_[0] << ", expected " << signum;
500 return false;
501 }
502 signals_received_.erase(signals_received_.begin());
503 return true;
504 }
505
506 bool ExpectNone() {
507 bool ret = signals_received_.empty();
508 if (!ret) {
509 LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
510 << ", expected none";
511 }
512 return ret;
513 }
514
515 static std::vector<int> signals_received_;
516 static Thread *signaled_thread_;
517
518 scoped_ptr<PhysicalSocketServer> ss_;
519};
520
521std::vector<int> PosixSignalDeliveryTest::signals_received_;
522Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
523
524// Test receiving a synchronous signal while not in Wait() and then entering
525// Wait() afterwards.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000526TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000527 ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
528 raise(SIGTERM);
529 EXPECT_TRUE(ss_->Wait(0, true));
530 EXPECT_TRUE(ExpectSignal(SIGTERM));
531 EXPECT_TRUE(ExpectNone());
532}
533
534// Test that we can handle getting tons of repeated signals and that we see all
535// the different ones.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000536TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000537 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
538 ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
539 for (int i = 0; i < 10000; ++i) {
540 raise(SIGTERM);
541 }
542 raise(SIGINT);
543 EXPECT_TRUE(ss_->Wait(0, true));
544 // Order will be lowest signal numbers first.
545 EXPECT_TRUE(ExpectSignal(SIGINT));
546 EXPECT_TRUE(ExpectSignal(SIGTERM));
547 EXPECT_TRUE(ExpectNone());
548}
549
550// Test that a signal during a Wait() call is detected.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000551TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000552 ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
553 alarm(1);
554 EXPECT_TRUE(ss_->Wait(1500, true));
555 EXPECT_TRUE(ExpectSignal(SIGALRM));
556 EXPECT_TRUE(ExpectNone());
557}
558
559class RaiseSigTermRunnable : public Runnable {
560 void Run(Thread *thread) {
561 thread->socketserver()->Wait(1000, false);
562
563 // Allow SIGTERM. This will be the only thread with it not masked so it will
564 // be delivered to us.
565 sigset_t mask;
566 sigemptyset(&mask);
567 pthread_sigmask(SIG_SETMASK, &mask, NULL);
568
569 // Raise it.
570 raise(SIGTERM);
571 }
572};
573
574// Test that it works no matter what thread the kernel chooses to give the
575// signal to (since it's not guaranteed to be the one that Wait() runs on).
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000576TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000577 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
578 // Mask out SIGTERM so that it can't be delivered to this thread.
579 sigset_t mask;
580 sigemptyset(&mask);
581 sigaddset(&mask, SIGTERM);
582 EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
583 // Start a new thread that raises it. It will have to be delivered to that
584 // thread. Our implementation should safely handle it and dispatch
585 // RecordSignal() on this thread.
586 scoped_ptr<Thread> thread(new Thread());
587 scoped_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
588 thread->Start(runnable.get());
589 EXPECT_TRUE(ss_->Wait(1500, true));
590 EXPECT_TRUE(ExpectSignal(SIGTERM));
591 EXPECT_EQ(Thread::Current(), signaled_thread_);
592 EXPECT_TRUE(ExpectNone());
593}
594
595#endif
596
597} // namespace rtc