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