• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
22 namespace rtc {
23 
24 class PhysicalSocketTest;
25 
26 class FakeSocketDispatcher : public SocketDispatcher {
27  public:
FakeSocketDispatcher(PhysicalSocketServer * ss)28   explicit FakeSocketDispatcher(PhysicalSocketServer* ss)
29     : SocketDispatcher(ss) {
30   }
31 
32  protected:
33   SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override;
34 };
35 
36 class FakePhysicalSocketServer : public PhysicalSocketServer {
37  public:
FakePhysicalSocketServer(PhysicalSocketTest * test)38   explicit FakePhysicalSocketServer(PhysicalSocketTest* test)
39     : test_(test) {
40   }
41 
CreateAsyncSocket(int type)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 
CreateAsyncSocket(int family,int type)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 
GetTest() const62   PhysicalSocketTest* GetTest() const { return test_; }
63 
64  private:
65   PhysicalSocketTest* test_;
66 };
67 
68 class PhysicalSocketTest : public SocketTest {
69  public:
70   // Set flag to simluate failures when calling "::accept" on a AsyncSocket.
SetFailAccept(bool fail)71   void SetFailAccept(bool fail) { fail_accept_ = fail; }
FailAccept() const72   bool FailAccept() const { return fail_accept_; }
73 
74  protected:
PhysicalSocketTest()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 
DoAccept(SOCKET socket,sockaddr * addr,socklen_t * addrlen)88 SOCKET 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 
TEST_F(PhysicalSocketTest,TestConnectIPv4)100 TEST_F(PhysicalSocketTest, TestConnectIPv4) {
101   SocketTest::TestConnectIPv4();
102 }
103 
104 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestConnectIPv6)110 TEST_F(PhysicalSocketTest, MAYBE_TestConnectIPv6) {
111   SocketTest::TestConnectIPv6();
112 }
113 
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupIPv4)114 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
115   SocketTest::TestConnectWithDnsLookupIPv4();
116 }
117 
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupIPv6)118 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
119   SocketTest::TestConnectWithDnsLookupIPv6();
120 }
121 
TEST_F(PhysicalSocketTest,TestConnectFailIPv4)122 TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
123   SocketTest::TestConnectFailIPv4();
124 }
125 
ConnectInternalAcceptError(const IPAddress & loopback)126 void 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 
TEST_F(PhysicalSocketTest,TestConnectAcceptErrorIPv4)198 TEST_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
TEST_F(PhysicalSocketTest,MAYBE_TestConnectAcceptErrorIPv6)208 TEST_F(PhysicalSocketTest, MAYBE_TestConnectAcceptErrorIPv6) {
209   ConnectInternalAcceptError(kIPv6Loopback);
210 }
211 
212 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestConnectFailIPv6)218 TEST_F(PhysicalSocketTest, MAYBE_TestConnectFailIPv6) {
219   SocketTest::TestConnectFailIPv6();
220 }
221 
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupFailIPv4)222 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
223   SocketTest::TestConnectWithDnsLookupFailIPv4();
224 }
225 
226 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestConnectWithDnsLookupFailIPv6)234 TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithDnsLookupFailIPv6) {
235   SocketTest::TestConnectWithDnsLookupFailIPv6();
236 }
237 
238 
TEST_F(PhysicalSocketTest,TestConnectWithClosedSocketIPv4)239 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
240   SocketTest::TestConnectWithClosedSocketIPv4();
241 }
242 
243 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestConnectWithClosedSocketIPv6)250 TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithClosedSocketIPv6) {
251   SocketTest::TestConnectWithClosedSocketIPv6();
252 }
253 
TEST_F(PhysicalSocketTest,TestConnectWhileNotClosedIPv4)254 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
255   SocketTest::TestConnectWhileNotClosedIPv4();
256 }
257 
258 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestConnectWhileNotClosedIPv6)265 TEST_F(PhysicalSocketTest, MAYBE_TestConnectWhileNotClosedIPv6) {
266   SocketTest::TestConnectWhileNotClosedIPv6();
267 }
268 
TEST_F(PhysicalSocketTest,TestServerCloseDuringConnectIPv4)269 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
270   SocketTest::TestServerCloseDuringConnectIPv4();
271 }
272 
273 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestServerCloseDuringConnectIPv6)280 TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseDuringConnectIPv6) {
281   SocketTest::TestServerCloseDuringConnectIPv6();
282 }
283 
TEST_F(PhysicalSocketTest,TestClientCloseDuringConnectIPv4)284 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
285   SocketTest::TestClientCloseDuringConnectIPv4();
286 }
287 
288 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestClientCloseDuringConnectIPv6)295 TEST_F(PhysicalSocketTest, MAYBE_TestClientCloseDuringConnectIPv6) {
296   SocketTest::TestClientCloseDuringConnectIPv6();
297 }
298 
TEST_F(PhysicalSocketTest,TestServerCloseIPv4)299 TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
300   SocketTest::TestServerCloseIPv4();
301 }
302 
303 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestServerCloseIPv6)309 TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseIPv6) {
310   SocketTest::TestServerCloseIPv6();
311 }
312 
TEST_F(PhysicalSocketTest,TestCloseInClosedCallbackIPv4)313 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
314   SocketTest::TestCloseInClosedCallbackIPv4();
315 }
316 
317 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestCloseInClosedCallbackIPv6)324 TEST_F(PhysicalSocketTest, MAYBE_TestCloseInClosedCallbackIPv6) {
325   SocketTest::TestCloseInClosedCallbackIPv6();
326 }
327 
TEST_F(PhysicalSocketTest,TestSocketServerWaitIPv4)328 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
329   SocketTest::TestSocketServerWaitIPv4();
330 }
331 
332 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestSocketServerWaitIPv6)338 TEST_F(PhysicalSocketTest, MAYBE_TestSocketServerWaitIPv6) {
339   SocketTest::TestSocketServerWaitIPv6();
340 }
341 
TEST_F(PhysicalSocketTest,TestTcpIPv4)342 TEST_F(PhysicalSocketTest, TestTcpIPv4) {
343   SocketTest::TestTcpIPv4();
344 }
345 
346 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestTcpIPv6)352 TEST_F(PhysicalSocketTest, MAYBE_TestTcpIPv6) {
353   SocketTest::TestTcpIPv6();
354 }
355 
TEST_F(PhysicalSocketTest,TestUdpIPv4)356 TEST_F(PhysicalSocketTest, TestUdpIPv4) {
357   SocketTest::TestUdpIPv4();
358 }
359 
360 // 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
TEST_F(PhysicalSocketTest,MAYBE_TestUdpIPv6)366 TEST_F(PhysicalSocketTest, MAYBE_TestUdpIPv6) {
367   SocketTest::TestUdpIPv6();
368 }
369 
370 // Disable for TSan v2, see
371 // https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
372 // 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.
375 // Also disable for ASan.
376 // Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
377 // Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233
378 #if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
379     defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) ||  \
380     defined(WEBRTC_LINUX)
381 #define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
382 #else
383 #define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
384 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestUdpReadyToSendIPv4)385 TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
386   SocketTest::TestUdpReadyToSendIPv4();
387 }
388 
TEST_F(PhysicalSocketTest,TestUdpReadyToSendIPv6)389 TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
390   SocketTest::TestUdpReadyToSendIPv6();
391 }
392 
TEST_F(PhysicalSocketTest,TestGetSetOptionsIPv4)393 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
394   SocketTest::TestGetSetOptionsIPv4();
395 }
396 
TEST_F(PhysicalSocketTest,TestGetSetOptionsIPv6)397 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
398   SocketTest::TestGetSetOptionsIPv6();
399 }
400 
401 #if defined(WEBRTC_POSIX)
402 
403 class PosixSignalDeliveryTest : public testing::Test {
404  public:
RecordSignal(int signum)405   static void RecordSignal(int signum) {
406     signals_received_.push_back(signum);
407     signaled_thread_ = Thread::Current();
408   }
409 
410  protected:
SetUp()411   void SetUp() {
412     ss_.reset(new PhysicalSocketServer());
413   }
414 
TearDown()415   void TearDown() {
416     ss_.reset(NULL);
417     signals_received_.clear();
418     signaled_thread_ = NULL;
419   }
420 
ExpectSignal(int signum)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 
ExpectNone()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 
450 std::vector<int> PosixSignalDeliveryTest::signals_received_;
451 Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
452 
453 // Test receiving a synchronous signal while not in Wait() and then entering
454 // Wait() afterwards.
TEST_F(PosixSignalDeliveryTest,RaiseThenWait)455 TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
456   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.
TEST_F(PosixSignalDeliveryTest,InsanelyManySignals)465 TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
466   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.
TEST_F(PosixSignalDeliveryTest,SignalDuringWait)480 TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
481   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 
488 class RaiseSigTermRunnable : public Runnable {
Run(Thread * thread)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).
TEST_F(PosixSignalDeliveryTest,SignalOnDifferentThread)505 TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
506   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
527