blob: a2fde80b42c951c640e80c1ef9fc28f8f0547176 [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
32 protected:
33 SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000034};
35
jbauch095ae152015-12-18 01:39:55 -080036class FakePhysicalSocketServer : public PhysicalSocketServer {
37 public:
38 explicit FakePhysicalSocketServer(PhysicalSocketTest* test)
39 : test_(test) {
40 }
41
42 AsyncSocket* CreateAsyncSocket(int type) override {
43 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
44 if (dispatcher->Create(type)) {
45 return dispatcher;
46 } else {
47 delete dispatcher;
48 return nullptr;
49 }
50 }
51
52 AsyncSocket* CreateAsyncSocket(int family, int type) override {
53 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
54 if (dispatcher->Create(family, type)) {
55 return dispatcher;
56 } else {
57 delete dispatcher;
58 return nullptr;
59 }
60 }
61
62 PhysicalSocketTest* GetTest() const { return test_; }
63
64 private:
65 PhysicalSocketTest* test_;
66};
67
68class PhysicalSocketTest : public SocketTest {
69 public:
70 // Set flag to simluate failures when calling "::accept" on a AsyncSocket.
71 void SetFailAccept(bool fail) { fail_accept_ = fail; }
72 bool FailAccept() const { return fail_accept_; }
73
74 protected:
75 PhysicalSocketTest()
76 : server_(new FakePhysicalSocketServer(this)),
77 scope_(server_.get()),
78 fail_accept_(false) {
79 }
80
81 void ConnectInternalAcceptError(const IPAddress& loopback);
82
83 rtc::scoped_ptr<FakePhysicalSocketServer> server_;
84 SocketServerScope scope_;
85 bool fail_accept_;
86};
87
88SOCKET FakeSocketDispatcher::DoAccept(SOCKET socket,
89 sockaddr* addr,
90 socklen_t* addrlen) {
91 FakePhysicalSocketServer* ss =
92 static_cast<FakePhysicalSocketServer*>(socketserver());
93 if (ss->GetTest()->FailAccept()) {
94 return INVALID_SOCKET;
95 }
96
97 return SocketDispatcher::DoAccept(socket, addr, addrlen);
98}
99
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000100TEST_F(PhysicalSocketTest, TestConnectIPv4) {
101 SocketTest::TestConnectIPv4();
102}
103
minyue5d696482015-08-19 04:42:03 -0700104// Crashes on Linux. See webrtc:4923.
105#if defined(WEBRTC_LINUX)
106#define MAYBE_TestConnectIPv6 DISABLED_TestConnectIPv6
107#else
108#define MAYBE_TestConnectIPv6 TestConnectIPv6
109#endif
110TEST_F(PhysicalSocketTest, MAYBE_TestConnectIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000111 SocketTest::TestConnectIPv6();
112}
113
114TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
115 SocketTest::TestConnectWithDnsLookupIPv4();
116}
117
118TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
119 SocketTest::TestConnectWithDnsLookupIPv6();
120}
121
122TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
123 SocketTest::TestConnectFailIPv4();
124}
125
jbauch095ae152015-12-18 01:39:55 -0800126void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) {
127 testing::StreamSink sink;
128 SocketAddress accept_addr;
129
130 // Create two clients.
131 scoped_ptr<AsyncSocket> client1(server_->CreateAsyncSocket(loopback.family(),
132 SOCK_STREAM));
133 sink.Monitor(client1.get());
134 EXPECT_EQ(AsyncSocket::CS_CLOSED, client1->GetState());
135 EXPECT_PRED1(IsUnspecOrEmptyIP, client1->GetLocalAddress().ipaddr());
136
137 scoped_ptr<AsyncSocket> client2(server_->CreateAsyncSocket(loopback.family(),
138 SOCK_STREAM));
139 sink.Monitor(client2.get());
140 EXPECT_EQ(AsyncSocket::CS_CLOSED, client2->GetState());
141 EXPECT_PRED1(IsUnspecOrEmptyIP, client2->GetLocalAddress().ipaddr());
142
143 // Create server and listen.
144 scoped_ptr<AsyncSocket> server(
145 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
146 sink.Monitor(server.get());
147 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
148 EXPECT_EQ(0, server->Listen(5));
149 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
150
151 // Ensure no pending server connections, since we haven't done anything yet.
152 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
153 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
154 EXPECT_TRUE(accept_addr.IsNil());
155
156 // Attempt first connect to listening socket.
157 EXPECT_EQ(0, client1->Connect(server->GetLocalAddress()));
158 EXPECT_FALSE(client1->GetLocalAddress().IsNil());
159 EXPECT_NE(server->GetLocalAddress(), client1->GetLocalAddress());
160
161 // Client is connecting, outcome not yet determined.
162 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client1->GetState());
163 EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_OPEN));
164 EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_CLOSE));
165
166 // Server has pending connection, try to accept it (will fail).
167 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
168 // Simulate "::accept" returning an error.
169 SetFailAccept(true);
170 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
171 EXPECT_FALSE(accepted);
172 ASSERT_TRUE(accept_addr.IsNil());
173
174 // Ensure no more pending server connections.
175 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
176 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
177 EXPECT_TRUE(accept_addr.IsNil());
178
179 // Attempt second connect to listening socket.
180 EXPECT_EQ(0, client2->Connect(server->GetLocalAddress()));
181 EXPECT_FALSE(client2->GetLocalAddress().IsNil());
182 EXPECT_NE(server->GetLocalAddress(), client2->GetLocalAddress());
183
184 // Client is connecting, outcome not yet determined.
185 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client2->GetState());
186 EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_OPEN));
187 EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_CLOSE));
188
189 // Server has pending connection, try to accept it (will succeed).
190 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
191 SetFailAccept(false);
192 scoped_ptr<AsyncSocket> accepted2(server->Accept(&accept_addr));
193 ASSERT_TRUE(accepted2);
194 EXPECT_FALSE(accept_addr.IsNil());
195 EXPECT_EQ(accepted2->GetRemoteAddress(), accept_addr);
196}
197
198TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv4) {
199 ConnectInternalAcceptError(kIPv4Loopback);
200}
201
202// Crashes on Linux. See webrtc:4923.
203#if defined(WEBRTC_LINUX)
204#define MAYBE_TestConnectAcceptErrorIPv6 DISABLED_TestConnectAcceptErrorIPv6
205#else
206#define MAYBE_TestConnectAcceptErrorIPv6 TestConnectAcceptErrorIPv6
207#endif
208TEST_F(PhysicalSocketTest, MAYBE_TestConnectAcceptErrorIPv6) {
209 ConnectInternalAcceptError(kIPv6Loopback);
210}
211
minyue5d696482015-08-19 04:42:03 -0700212// Crashes on Linux. See webrtc:4923.
213#if defined(WEBRTC_LINUX)
214#define MAYBE_TestConnectFailIPv6 DISABLED_TestConnectFailIPv6
215#else
216#define MAYBE_TestConnectFailIPv6 TestConnectFailIPv6
217#endif
218TEST_F(PhysicalSocketTest, MAYBE_TestConnectFailIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000219 SocketTest::TestConnectFailIPv6();
220}
221
222TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
223 SocketTest::TestConnectWithDnsLookupFailIPv4();
224}
225
minyue5d696482015-08-19 04:42:03 -0700226// Crashes on Linux. See webrtc:4923.
227#if defined(WEBRTC_LINUX)
228#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
229 DISABLED_TestConnectWithDnsLookupFailIPv6
230#else
231#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
232 TestConnectWithDnsLookupFailIPv6
233#endif
234TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithDnsLookupFailIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000235 SocketTest::TestConnectWithDnsLookupFailIPv6();
236}
237
238
239TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
240 SocketTest::TestConnectWithClosedSocketIPv4();
241}
242
minyue5d696482015-08-19 04:42:03 -0700243// Crashes on Linux. See webrtc:4923.
244#if defined(WEBRTC_LINUX)
245#define MAYBE_TestConnectWithClosedSocketIPv6 \
246 DISABLED_TestConnectWithClosedSocketIPv6
247#else
248#define MAYBE_TestConnectWithClosedSocketIPv6 TestConnectWithClosedSocketIPv6
249#endif
250TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithClosedSocketIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000251 SocketTest::TestConnectWithClosedSocketIPv6();
252}
253
254TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
255 SocketTest::TestConnectWhileNotClosedIPv4();
256}
257
minyue5d696482015-08-19 04:42:03 -0700258// Crashes on Linux. See webrtc:4923.
259#if defined(WEBRTC_LINUX)
260#define MAYBE_TestConnectWhileNotClosedIPv6 \
261 DISABLED_TestConnectWhileNotClosedIPv6
262#else
263#define MAYBE_TestConnectWhileNotClosedIPv6 TestConnectWhileNotClosedIPv6
264#endif
265TEST_F(PhysicalSocketTest, MAYBE_TestConnectWhileNotClosedIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000266 SocketTest::TestConnectWhileNotClosedIPv6();
267}
268
269TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
270 SocketTest::TestServerCloseDuringConnectIPv4();
271}
272
minyue5d696482015-08-19 04:42:03 -0700273// Crashes on Linux. See webrtc:4923.
274#if defined(WEBRTC_LINUX)
275#define MAYBE_TestServerCloseDuringConnectIPv6 \
276 DISABLED_TestServerCloseDuringConnectIPv6
277#else
278#define MAYBE_TestServerCloseDuringConnectIPv6 TestServerCloseDuringConnectIPv6
279#endif
280TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseDuringConnectIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000281 SocketTest::TestServerCloseDuringConnectIPv6();
282}
283
284TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
285 SocketTest::TestClientCloseDuringConnectIPv4();
286}
287
minyue5d696482015-08-19 04:42:03 -0700288// Crashes on Linux. See webrtc:4923.
289#if defined(WEBRTC_LINUX)
290#define MAYBE_TestClientCloseDuringConnectIPv6 \
291 DISABLED_TestClientCloseDuringConnectIPv6
292#else
293#define MAYBE_TestClientCloseDuringConnectIPv6 TestClientCloseDuringConnectIPv6
294#endif
295TEST_F(PhysicalSocketTest, MAYBE_TestClientCloseDuringConnectIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000296 SocketTest::TestClientCloseDuringConnectIPv6();
297}
298
299TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
300 SocketTest::TestServerCloseIPv4();
301}
302
minyue5d696482015-08-19 04:42:03 -0700303// Crashes on Linux. See webrtc:4923.
304#if defined(WEBRTC_LINUX)
305#define MAYBE_TestServerCloseIPv6 DISABLED_TestServerCloseIPv6
306#else
307#define MAYBE_TestServerCloseIPv6 TestServerCloseIPv6
308#endif
309TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000310 SocketTest::TestServerCloseIPv6();
311}
312
313TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
314 SocketTest::TestCloseInClosedCallbackIPv4();
315}
316
minyue5d696482015-08-19 04:42:03 -0700317// Crashes on Linux. See webrtc:4923.
318#if defined(WEBRTC_LINUX)
319#define MAYBE_TestCloseInClosedCallbackIPv6 \
320 DISABLED_TestCloseInClosedCallbackIPv6
321#else
322#define MAYBE_TestCloseInClosedCallbackIPv6 TestCloseInClosedCallbackIPv6
323#endif
324TEST_F(PhysicalSocketTest, MAYBE_TestCloseInClosedCallbackIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000325 SocketTest::TestCloseInClosedCallbackIPv6();
326}
327
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000328TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000329 SocketTest::TestSocketServerWaitIPv4();
330}
331
minyue5d696482015-08-19 04:42:03 -0700332// Crashes on Linux. See webrtc:4923.
333#if defined(WEBRTC_LINUX)
334#define MAYBE_TestSocketServerWaitIPv6 DISABLED_TestSocketServerWaitIPv6
335#else
336#define MAYBE_TestSocketServerWaitIPv6 TestSocketServerWaitIPv6
337#endif
338TEST_F(PhysicalSocketTest, MAYBE_TestSocketServerWaitIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000339 SocketTest::TestSocketServerWaitIPv6();
340}
341
342TEST_F(PhysicalSocketTest, TestTcpIPv4) {
343 SocketTest::TestTcpIPv4();
344}
345
minyue5d696482015-08-19 04:42:03 -0700346// Crashes on Linux. See webrtc:4923.
347#if defined(WEBRTC_LINUX)
348#define MAYBE_TestTcpIPv6 DISABLED_TestTcpIPv6
349#else
350#define MAYBE_TestTcpIPv6 TestTcpIPv6
351#endif
352TEST_F(PhysicalSocketTest, MAYBE_TestTcpIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000353 SocketTest::TestTcpIPv6();
354}
355
356TEST_F(PhysicalSocketTest, TestUdpIPv4) {
357 SocketTest::TestUdpIPv4();
358}
359
minyue5d696482015-08-19 04:42:03 -0700360// Crashes on Linux. See webrtc:4923.
361#if defined(WEBRTC_LINUX)
362#define MAYBE_TestUdpIPv6 DISABLED_TestUdpIPv6
363#else
364#define MAYBE_TestUdpIPv6 TestUdpIPv6
365#endif
366TEST_F(PhysicalSocketTest, MAYBE_TestUdpIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000367 SocketTest::TestUdpIPv6();
368}
369
henrike@webrtc.org6f833c32014-06-27 16:21:49 +0000370// Disable for TSan v2, see
371// https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
deadbeefc97be6a2015-09-25 11:00:38 -0700372// Also disable for MSan, see:
373// https://code.google.com/p/webrtc/issues/detail?id=4958
374// TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
minyuedf200d12015-10-17 13:10:46 -0700375// Also disable for ASan.
Henrik Kjellander0be3e042015-10-30 21:21:03 +0100376// Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
ivocf399f212015-11-19 06:44:32 -0800377// Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233
minyuedf200d12015-10-17 13:10:46 -0700378#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
ivocf399f212015-11-19 06:44:32 -0800379 defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) || \
380 defined(WEBRTC_LINUX)
minyuedf200d12015-10-17 13:10:46 -0700381#define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
382#else
383#define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
384#endif
385TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000386 SocketTest::TestUdpReadyToSendIPv4();
387}
388
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000389TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000390 SocketTest::TestUdpReadyToSendIPv6();
391}
392
393TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
394 SocketTest::TestGetSetOptionsIPv4();
395}
396
397TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
398 SocketTest::TestGetSetOptionsIPv6();
399}
400
401#if defined(WEBRTC_POSIX)
402
403class PosixSignalDeliveryTest : public testing::Test {
404 public:
405 static void RecordSignal(int signum) {
406 signals_received_.push_back(signum);
407 signaled_thread_ = Thread::Current();
408 }
409
410 protected:
411 void SetUp() {
412 ss_.reset(new PhysicalSocketServer());
413 }
414
415 void TearDown() {
416 ss_.reset(NULL);
417 signals_received_.clear();
418 signaled_thread_ = NULL;
419 }
420
421 bool ExpectSignal(int signum) {
422 if (signals_received_.empty()) {
423 LOG(LS_ERROR) << "ExpectSignal(): No signal received";
424 return false;
425 }
426 if (signals_received_[0] != signum) {
427 LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
428 signals_received_[0] << ", expected " << signum;
429 return false;
430 }
431 signals_received_.erase(signals_received_.begin());
432 return true;
433 }
434
435 bool ExpectNone() {
436 bool ret = signals_received_.empty();
437 if (!ret) {
438 LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
439 << ", expected none";
440 }
441 return ret;
442 }
443
444 static std::vector<int> signals_received_;
445 static Thread *signaled_thread_;
446
447 scoped_ptr<PhysicalSocketServer> ss_;
448};
449
450std::vector<int> PosixSignalDeliveryTest::signals_received_;
451Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
452
453// Test receiving a synchronous signal while not in Wait() and then entering
454// Wait() afterwards.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000455TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000456 ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
457 raise(SIGTERM);
458 EXPECT_TRUE(ss_->Wait(0, true));
459 EXPECT_TRUE(ExpectSignal(SIGTERM));
460 EXPECT_TRUE(ExpectNone());
461}
462
463// Test that we can handle getting tons of repeated signals and that we see all
464// the different ones.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000465TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000466 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
467 ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
468 for (int i = 0; i < 10000; ++i) {
469 raise(SIGTERM);
470 }
471 raise(SIGINT);
472 EXPECT_TRUE(ss_->Wait(0, true));
473 // Order will be lowest signal numbers first.
474 EXPECT_TRUE(ExpectSignal(SIGINT));
475 EXPECT_TRUE(ExpectSignal(SIGTERM));
476 EXPECT_TRUE(ExpectNone());
477}
478
479// Test that a signal during a Wait() call is detected.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000480TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000481 ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
482 alarm(1);
483 EXPECT_TRUE(ss_->Wait(1500, true));
484 EXPECT_TRUE(ExpectSignal(SIGALRM));
485 EXPECT_TRUE(ExpectNone());
486}
487
488class RaiseSigTermRunnable : public Runnable {
489 void Run(Thread *thread) {
490 thread->socketserver()->Wait(1000, false);
491
492 // Allow SIGTERM. This will be the only thread with it not masked so it will
493 // be delivered to us.
494 sigset_t mask;
495 sigemptyset(&mask);
496 pthread_sigmask(SIG_SETMASK, &mask, NULL);
497
498 // Raise it.
499 raise(SIGTERM);
500 }
501};
502
503// Test that it works no matter what thread the kernel chooses to give the
504// signal to (since it's not guaranteed to be the one that Wait() runs on).
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000505TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000506 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
507 // Mask out SIGTERM so that it can't be delivered to this thread.
508 sigset_t mask;
509 sigemptyset(&mask);
510 sigaddset(&mask, SIGTERM);
511 EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
512 // Start a new thread that raises it. It will have to be delivered to that
513 // thread. Our implementation should safely handle it and dispatch
514 // RecordSignal() on this thread.
515 scoped_ptr<Thread> thread(new Thread());
516 scoped_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
517 thread->Start(runnable.get());
518 EXPECT_TRUE(ss_->Wait(1500, true));
519 EXPECT_TRUE(ExpectSignal(SIGTERM));
520 EXPECT_EQ(Thread::Current(), signaled_thread_);
521 EXPECT_TRUE(ExpectNone());
522}
523
524#endif
525
526} // namespace rtc