blob: 6de8a90ea87890f5a6c33968ad232ee494597a2c [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
jbauch555604a2016-04-26 03:13:22 -070011#include <memory>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000012#include <signal.h>
13#include <stdarg.h>
14
15#include "webrtc/base/gunit.h"
16#include "webrtc/base/logging.h"
17#include "webrtc/base/physicalsocketserver.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000018#include "webrtc/base/socket_unittest.h"
19#include "webrtc/base/testutils.h"
20#include "webrtc/base/thread.h"
21
22namespace rtc {
23
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070024#define MAYBE_SKIP_IPV6 \
25 if (!HasIPv6Enabled()) { \
26 LOG(LS_INFO) << "No IPv6... skipping"; \
27 return; \
28 }
29
jbauch095ae152015-12-18 01:39:55 -080030class PhysicalSocketTest;
31
32class FakeSocketDispatcher : public SocketDispatcher {
33 public:
34 explicit FakeSocketDispatcher(PhysicalSocketServer* ss)
35 : SocketDispatcher(ss) {
36 }
37
jbauchf2a2bf42016-02-03 16:45:32 -080038 FakeSocketDispatcher(SOCKET s, PhysicalSocketServer* ss)
39 : SocketDispatcher(s, ss) {
40 }
41
jbauch095ae152015-12-18 01:39:55 -080042 protected:
43 SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override;
jbauchf2a2bf42016-02-03 16:45:32 -080044 int DoSend(SOCKET socket, const char* buf, int len, int flags) override;
45 int DoSendTo(SOCKET socket, const char* buf, int len, int flags,
46 const struct sockaddr* dest_addr, socklen_t addrlen) override;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047};
48
jbauch095ae152015-12-18 01:39:55 -080049class FakePhysicalSocketServer : public PhysicalSocketServer {
50 public:
51 explicit FakePhysicalSocketServer(PhysicalSocketTest* test)
52 : test_(test) {
53 }
54
55 AsyncSocket* CreateAsyncSocket(int type) override {
56 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
jbauchf2a2bf42016-02-03 16:45:32 -080057 if (!dispatcher->Create(type)) {
jbauch095ae152015-12-18 01:39:55 -080058 delete dispatcher;
59 return nullptr;
60 }
jbauchf2a2bf42016-02-03 16:45:32 -080061 return dispatcher;
jbauch095ae152015-12-18 01:39:55 -080062 }
63
64 AsyncSocket* CreateAsyncSocket(int family, int type) override {
65 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
jbauchf2a2bf42016-02-03 16:45:32 -080066 if (!dispatcher->Create(family, type)) {
jbauch095ae152015-12-18 01:39:55 -080067 delete dispatcher;
68 return nullptr;
69 }
jbauchf2a2bf42016-02-03 16:45:32 -080070 return dispatcher;
71 }
72
73 AsyncSocket* WrapSocket(SOCKET s) override {
74 SocketDispatcher* dispatcher = new FakeSocketDispatcher(s, this);
75 if (!dispatcher->Initialize()) {
76 delete dispatcher;
77 return nullptr;
78 }
79 return dispatcher;
jbauch095ae152015-12-18 01:39:55 -080080 }
81
82 PhysicalSocketTest* GetTest() const { return test_; }
83
84 private:
85 PhysicalSocketTest* test_;
86};
87
88class PhysicalSocketTest : public SocketTest {
89 public:
90 // Set flag to simluate failures when calling "::accept" on a AsyncSocket.
91 void SetFailAccept(bool fail) { fail_accept_ = fail; }
92 bool FailAccept() const { return fail_accept_; }
93
jbauchf2a2bf42016-02-03 16:45:32 -080094 // Maximum size to ::send to a socket. Set to < 0 to disable limiting.
95 void SetMaxSendSize(int max_size) { max_send_size_ = max_size; }
96 int MaxSendSize() const { return max_send_size_; }
97
jbauch095ae152015-12-18 01:39:55 -080098 protected:
99 PhysicalSocketTest()
100 : server_(new FakePhysicalSocketServer(this)),
101 scope_(server_.get()),
jbauchf2a2bf42016-02-03 16:45:32 -0800102 fail_accept_(false),
103 max_send_size_(-1) {
jbauch095ae152015-12-18 01:39:55 -0800104 }
105
106 void ConnectInternalAcceptError(const IPAddress& loopback);
jbauchf2a2bf42016-02-03 16:45:32 -0800107 void WritableAfterPartialWrite(const IPAddress& loopback);
jbauch095ae152015-12-18 01:39:55 -0800108
jbauch555604a2016-04-26 03:13:22 -0700109 std::unique_ptr<FakePhysicalSocketServer> server_;
jbauch095ae152015-12-18 01:39:55 -0800110 SocketServerScope scope_;
111 bool fail_accept_;
jbauchf2a2bf42016-02-03 16:45:32 -0800112 int max_send_size_;
jbauch095ae152015-12-18 01:39:55 -0800113};
114
115SOCKET FakeSocketDispatcher::DoAccept(SOCKET socket,
116 sockaddr* addr,
117 socklen_t* addrlen) {
118 FakePhysicalSocketServer* ss =
119 static_cast<FakePhysicalSocketServer*>(socketserver());
120 if (ss->GetTest()->FailAccept()) {
121 return INVALID_SOCKET;
122 }
123
124 return SocketDispatcher::DoAccept(socket, addr, addrlen);
125}
126
jbauchf2a2bf42016-02-03 16:45:32 -0800127int FakeSocketDispatcher::DoSend(SOCKET socket, const char* buf, int len,
128 int flags) {
129 FakePhysicalSocketServer* ss =
130 static_cast<FakePhysicalSocketServer*>(socketserver());
131 if (ss->GetTest()->MaxSendSize() >= 0) {
132 len = std::min(len, ss->GetTest()->MaxSendSize());
133 }
134
135 return SocketDispatcher::DoSend(socket, buf, len, flags);
136}
137
138int FakeSocketDispatcher::DoSendTo(SOCKET socket, const char* buf, int len,
139 int flags, const struct sockaddr* dest_addr, socklen_t addrlen) {
140 FakePhysicalSocketServer* ss =
141 static_cast<FakePhysicalSocketServer*>(socketserver());
142 if (ss->GetTest()->MaxSendSize() >= 0) {
143 len = std::min(len, ss->GetTest()->MaxSendSize());
144 }
145
146 return SocketDispatcher::DoSendTo(socket, buf, len, flags, dest_addr,
147 addrlen);
148}
149
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000150TEST_F(PhysicalSocketTest, TestConnectIPv4) {
151 SocketTest::TestConnectIPv4();
152}
153
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700154TEST_F(PhysicalSocketTest, 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.
jbauch555604a2016-04-26 03:13:22 -0700175 std::unique_ptr<AsyncSocket> client1(
176 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch095ae152015-12-18 01:39:55 -0800177 sink.Monitor(client1.get());
178 EXPECT_EQ(AsyncSocket::CS_CLOSED, client1->GetState());
179 EXPECT_PRED1(IsUnspecOrEmptyIP, client1->GetLocalAddress().ipaddr());
180
jbauch555604a2016-04-26 03:13:22 -0700181 std::unique_ptr<AsyncSocket> client2(
182 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch095ae152015-12-18 01:39:55 -0800183 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.
jbauch555604a2016-04-26 03:13:22 -0700188 std::unique_ptr<AsyncSocket> server(
jbauch095ae152015-12-18 01:39:55 -0800189 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);
jbauch555604a2016-04-26 03:13:22 -0700214 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
jbauch095ae152015-12-18 01:39:55 -0800215 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);
jbauch555604a2016-04-26 03:13:22 -0700236 std::unique_ptr<AsyncSocket> accepted2(server->Accept(&accept_addr));
jbauch095ae152015-12-18 01:39:55 -0800237 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
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700246TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv6) {
247 MAYBE_SKIP_IPV6;
jbauch095ae152015-12-18 01:39:55 -0800248 ConnectInternalAcceptError(kIPv6Loopback);
249}
250
jbauchf2a2bf42016-02-03 16:45:32 -0800251void PhysicalSocketTest::WritableAfterPartialWrite(const IPAddress& loopback) {
252 // Simulate a really small maximum send size.
253 const int kMaxSendSize = 128;
254 SetMaxSendSize(kMaxSendSize);
255
256 // Run the default send/receive socket tests with a smaller amount of data
257 // to avoid long running times due to the small maximum send size.
258 const size_t kDataSize = 128 * 1024;
259 TcpInternal(loopback, kDataSize, kMaxSendSize);
260}
261
danilchapb7b9dca2016-08-05 05:55:43 -0700262// https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
263#if defined(WEBRTC_WIN)
264#define MAYBE_TestWritableAfterPartialWriteIPv4 DISABLED_TestWritableAfterPartialWriteIPv4
265#else
266#define MAYBE_TestWritableAfterPartialWriteIPv4 TestWritableAfterPartialWriteIPv4
267#endif
268TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv4) {
jbauchf2a2bf42016-02-03 16:45:32 -0800269 WritableAfterPartialWrite(kIPv4Loopback);
270}
271
danilchapb7b9dca2016-08-05 05:55:43 -0700272// https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
273#if defined(WEBRTC_WIN)
274#define MAYBE_TestWritableAfterPartialWriteIPv6 DISABLED_TestWritableAfterPartialWriteIPv6
275#else
276#define MAYBE_TestWritableAfterPartialWriteIPv6 TestWritableAfterPartialWriteIPv6
277#endif
278TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv6) {
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700279 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800280 WritableAfterPartialWrite(kIPv6Loopback);
281}
282
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700283TEST_F(PhysicalSocketTest, TestConnectFailIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000284 SocketTest::TestConnectFailIPv6();
285}
286
287TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
288 SocketTest::TestConnectWithDnsLookupFailIPv4();
289}
290
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700291TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000292 SocketTest::TestConnectWithDnsLookupFailIPv6();
293}
294
295
296TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
297 SocketTest::TestConnectWithClosedSocketIPv4();
298}
299
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700300TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000301 SocketTest::TestConnectWithClosedSocketIPv6();
302}
303
304TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
305 SocketTest::TestConnectWhileNotClosedIPv4();
306}
307
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700308TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000309 SocketTest::TestConnectWhileNotClosedIPv6();
310}
311
312TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
313 SocketTest::TestServerCloseDuringConnectIPv4();
314}
315
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700316TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000317 SocketTest::TestServerCloseDuringConnectIPv6();
318}
319
320TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
321 SocketTest::TestClientCloseDuringConnectIPv4();
322}
323
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700324TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000325 SocketTest::TestClientCloseDuringConnectIPv6();
326}
327
328TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
329 SocketTest::TestServerCloseIPv4();
330}
331
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700332TEST_F(PhysicalSocketTest, TestServerCloseIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000333 SocketTest::TestServerCloseIPv6();
334}
335
336TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
337 SocketTest::TestCloseInClosedCallbackIPv4();
338}
339
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700340TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000341 SocketTest::TestCloseInClosedCallbackIPv6();
342}
343
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000344TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000345 SocketTest::TestSocketServerWaitIPv4();
346}
347
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700348TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000349 SocketTest::TestSocketServerWaitIPv6();
350}
351
352TEST_F(PhysicalSocketTest, TestTcpIPv4) {
353 SocketTest::TestTcpIPv4();
354}
355
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700356TEST_F(PhysicalSocketTest, TestTcpIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000357 SocketTest::TestTcpIPv6();
358}
359
360TEST_F(PhysicalSocketTest, TestUdpIPv4) {
361 SocketTest::TestUdpIPv4();
362}
363
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700364TEST_F(PhysicalSocketTest, TestUdpIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000365 SocketTest::TestUdpIPv6();
366}
367
henrike@webrtc.org6f833c32014-06-27 16:21:49 +0000368// Disable for TSan v2, see
369// https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
deadbeefc97be6a2015-09-25 11:00:38 -0700370// Also disable for MSan, see:
371// https://code.google.com/p/webrtc/issues/detail?id=4958
372// TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
minyuedf200d12015-10-17 13:10:46 -0700373// Also disable for ASan.
Henrik Kjellander0be3e042015-10-30 21:21:03 +0100374// Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
ivocf399f212015-11-19 06:44:32 -0800375// Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233
minyuedf200d12015-10-17 13:10:46 -0700376#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
ivocf399f212015-11-19 06:44:32 -0800377 defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) || \
378 defined(WEBRTC_LINUX)
minyuedf200d12015-10-17 13:10:46 -0700379#define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
380#else
381#define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
382#endif
383TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000384 SocketTest::TestUdpReadyToSendIPv4();
385}
386
danilchapb7b9dca2016-08-05 05:55:43 -0700387// https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
388#if defined(WEBRTC_WIN)
389#define MAYBE_TestUdpReadyToSendIPv6 DISABLED_TestUdpReadyToSendIPv6
390#else
391#define MAYBE_TestUdpReadyToSendIPv6 TestUdpReadyToSendIPv6
392#endif
393TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000394 SocketTest::TestUdpReadyToSendIPv6();
395}
396
397TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
398 SocketTest::TestGetSetOptionsIPv4();
399}
400
401TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
402 SocketTest::TestGetSetOptionsIPv6();
403}
404
405#if defined(WEBRTC_POSIX)
406
Stefan Holmer9131efd2016-05-23 18:19:26 +0200407#if !defined(WEBRTC_MAC)
408TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv4) {
409 SocketTest::TestSocketRecvTimestamp();
410}
411
412#if defined(WEBRTC_LINUX)
413#define MAYBE_TestSocketRecvTimestampIPv6 DISABLED_TestSocketRecvTimestampIPv6
414#else
415#define MAYBE_TestSocketRecvTimestampIPv6 TestSocketRecvTimestampIPv6
416#endif
417TEST_F(PhysicalSocketTest, MAYBE_TestSocketRecvTimestampIPv6) {
418 SocketTest::TestSocketRecvTimestamp();
419}
420#endif
421
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000422class PosixSignalDeliveryTest : public testing::Test {
423 public:
424 static void RecordSignal(int signum) {
425 signals_received_.push_back(signum);
426 signaled_thread_ = Thread::Current();
427 }
428
429 protected:
430 void SetUp() {
431 ss_.reset(new PhysicalSocketServer());
432 }
433
434 void TearDown() {
435 ss_.reset(NULL);
436 signals_received_.clear();
437 signaled_thread_ = NULL;
438 }
439
440 bool ExpectSignal(int signum) {
441 if (signals_received_.empty()) {
442 LOG(LS_ERROR) << "ExpectSignal(): No signal received";
443 return false;
444 }
445 if (signals_received_[0] != signum) {
446 LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
447 signals_received_[0] << ", expected " << signum;
448 return false;
449 }
450 signals_received_.erase(signals_received_.begin());
451 return true;
452 }
453
454 bool ExpectNone() {
455 bool ret = signals_received_.empty();
456 if (!ret) {
457 LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
458 << ", expected none";
459 }
460 return ret;
461 }
462
463 static std::vector<int> signals_received_;
464 static Thread *signaled_thread_;
465
jbauch555604a2016-04-26 03:13:22 -0700466 std::unique_ptr<PhysicalSocketServer> ss_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000467};
468
469std::vector<int> PosixSignalDeliveryTest::signals_received_;
470Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
471
472// Test receiving a synchronous signal while not in Wait() and then entering
473// Wait() afterwards.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000474TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000475 ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
476 raise(SIGTERM);
477 EXPECT_TRUE(ss_->Wait(0, true));
478 EXPECT_TRUE(ExpectSignal(SIGTERM));
479 EXPECT_TRUE(ExpectNone());
480}
481
482// Test that we can handle getting tons of repeated signals and that we see all
483// the different ones.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000484TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000485 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
486 ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
487 for (int i = 0; i < 10000; ++i) {
488 raise(SIGTERM);
489 }
490 raise(SIGINT);
491 EXPECT_TRUE(ss_->Wait(0, true));
492 // Order will be lowest signal numbers first.
493 EXPECT_TRUE(ExpectSignal(SIGINT));
494 EXPECT_TRUE(ExpectSignal(SIGTERM));
495 EXPECT_TRUE(ExpectNone());
496}
497
498// Test that a signal during a Wait() call is detected.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000499TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000500 ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
501 alarm(1);
502 EXPECT_TRUE(ss_->Wait(1500, true));
503 EXPECT_TRUE(ExpectSignal(SIGALRM));
504 EXPECT_TRUE(ExpectNone());
505}
506
507class RaiseSigTermRunnable : public Runnable {
508 void Run(Thread *thread) {
509 thread->socketserver()->Wait(1000, false);
510
511 // Allow SIGTERM. This will be the only thread with it not masked so it will
512 // be delivered to us.
513 sigset_t mask;
514 sigemptyset(&mask);
515 pthread_sigmask(SIG_SETMASK, &mask, NULL);
516
517 // Raise it.
518 raise(SIGTERM);
519 }
520};
521
522// Test that it works no matter what thread the kernel chooses to give the
523// signal to (since it's not guaranteed to be the one that Wait() runs on).
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000524TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000525 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
526 // Mask out SIGTERM so that it can't be delivered to this thread.
527 sigset_t mask;
528 sigemptyset(&mask);
529 sigaddset(&mask, SIGTERM);
530 EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
531 // Start a new thread that raises it. It will have to be delivered to that
532 // thread. Our implementation should safely handle it and dispatch
533 // RecordSignal() on this thread.
jbauch555604a2016-04-26 03:13:22 -0700534 std::unique_ptr<Thread> thread(new Thread());
535 std::unique_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000536 thread->Start(runnable.get());
537 EXPECT_TRUE(ss_->Wait(1500, true));
538 EXPECT_TRUE(ExpectSignal(SIGTERM));
539 EXPECT_EQ(Thread::Current(), signaled_thread_);
540 EXPECT_TRUE(ExpectNone());
541}
542
543#endif
544
545} // namespace rtc