Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: webrtc/base/physicalsocketserver_unittest.cc

Issue 2877023002: Move webrtc/{base => rtc_base} (Closed)
Patch Set: update presubmit.py and DEPS include rules Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/physicalsocketserver.cc ('k') | webrtc/base/platform_file.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 <memory>
12 #include <signal.h>
13 #include <stdarg.h>
14
15 #include "webrtc/base/gunit.h"
16 #include "webrtc/base/logging.h"
17 #include "webrtc/base/networkmonitor.h"
18 #include "webrtc/base/physicalsocketserver.h"
19 #include "webrtc/base/socket_unittest.h"
20 #include "webrtc/base/testutils.h"
21 #include "webrtc/base/thread.h"
22
23 namespace rtc {
24
25 #define MAYBE_SKIP_IPV4 \
26 if (!HasIPv4Enabled()) { \
27 LOG(LS_INFO) << "No IPv4... skipping"; \
28 return; \
29 }
30
31 #define MAYBE_SKIP_IPV6 \
32 if (!HasIPv6Enabled()) { \
33 LOG(LS_INFO) << "No IPv6... skipping"; \
34 return; \
35 }
36
37 class PhysicalSocketTest;
38
39 class FakeSocketDispatcher : public SocketDispatcher {
40 public:
41 explicit FakeSocketDispatcher(PhysicalSocketServer* ss)
42 : SocketDispatcher(ss) {
43 }
44
45 FakeSocketDispatcher(SOCKET s, PhysicalSocketServer* ss)
46 : SocketDispatcher(s, ss) {
47 }
48
49 protected:
50 SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override;
51 int DoSend(SOCKET socket, const char* buf, int len, int flags) override;
52 int DoSendTo(SOCKET socket, const char* buf, int len, int flags,
53 const struct sockaddr* dest_addr, socklen_t addrlen) override;
54 };
55
56 class FakePhysicalSocketServer : public PhysicalSocketServer {
57 public:
58 explicit FakePhysicalSocketServer(PhysicalSocketTest* test)
59 : test_(test) {
60 }
61
62 AsyncSocket* CreateAsyncSocket(int type) override {
63 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
64 if (!dispatcher->Create(type)) {
65 delete dispatcher;
66 return nullptr;
67 }
68 return dispatcher;
69 }
70
71 AsyncSocket* CreateAsyncSocket(int family, int type) override {
72 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
73 if (!dispatcher->Create(family, type)) {
74 delete dispatcher;
75 return nullptr;
76 }
77 return dispatcher;
78 }
79
80 AsyncSocket* WrapSocket(SOCKET s) override {
81 SocketDispatcher* dispatcher = new FakeSocketDispatcher(s, this);
82 if (!dispatcher->Initialize()) {
83 delete dispatcher;
84 return nullptr;
85 }
86 return dispatcher;
87 }
88
89 PhysicalSocketTest* GetTest() const { return test_; }
90
91 private:
92 PhysicalSocketTest* test_;
93 };
94
95 class FakeNetworkBinder : public NetworkBinderInterface {
96 public:
97 NetworkBindingResult BindSocketToNetwork(int, const IPAddress&) override {
98 ++num_binds_;
99 return result_;
100 }
101
102 void set_result(NetworkBindingResult result) { result_ = result; }
103
104 int num_binds() { return num_binds_; }
105
106 private:
107 NetworkBindingResult result_ = NetworkBindingResult::SUCCESS;
108 int num_binds_ = 0;
109 };
110
111 class PhysicalSocketTest : public SocketTest {
112 public:
113 // Set flag to simluate failures when calling "::accept" on a AsyncSocket.
114 void SetFailAccept(bool fail) { fail_accept_ = fail; }
115 bool FailAccept() const { return fail_accept_; }
116
117 // Maximum size to ::send to a socket. Set to < 0 to disable limiting.
118 void SetMaxSendSize(int max_size) { max_send_size_ = max_size; }
119 int MaxSendSize() const { return max_send_size_; }
120
121 protected:
122 PhysicalSocketTest()
123 : server_(new FakePhysicalSocketServer(this)),
124 thread_(server_.get()),
125 fail_accept_(false),
126 max_send_size_(-1) {}
127
128 void ConnectInternalAcceptError(const IPAddress& loopback);
129 void WritableAfterPartialWrite(const IPAddress& loopback);
130
131 std::unique_ptr<FakePhysicalSocketServer> server_;
132 rtc::AutoSocketServerThread thread_;
133 bool fail_accept_;
134 int max_send_size_;
135 };
136
137 SOCKET FakeSocketDispatcher::DoAccept(SOCKET socket,
138 sockaddr* addr,
139 socklen_t* addrlen) {
140 FakePhysicalSocketServer* ss =
141 static_cast<FakePhysicalSocketServer*>(socketserver());
142 if (ss->GetTest()->FailAccept()) {
143 return INVALID_SOCKET;
144 }
145
146 return SocketDispatcher::DoAccept(socket, addr, addrlen);
147 }
148
149 int FakeSocketDispatcher::DoSend(SOCKET socket, const char* buf, int len,
150 int flags) {
151 FakePhysicalSocketServer* ss =
152 static_cast<FakePhysicalSocketServer*>(socketserver());
153 if (ss->GetTest()->MaxSendSize() >= 0) {
154 len = std::min(len, ss->GetTest()->MaxSendSize());
155 }
156
157 return SocketDispatcher::DoSend(socket, buf, len, flags);
158 }
159
160 int FakeSocketDispatcher::DoSendTo(SOCKET socket, const char* buf, int len,
161 int flags, const struct sockaddr* dest_addr, socklen_t addrlen) {
162 FakePhysicalSocketServer* ss =
163 static_cast<FakePhysicalSocketServer*>(socketserver());
164 if (ss->GetTest()->MaxSendSize() >= 0) {
165 len = std::min(len, ss->GetTest()->MaxSendSize());
166 }
167
168 return SocketDispatcher::DoSendTo(socket, buf, len, flags, dest_addr,
169 addrlen);
170 }
171
172 TEST_F(PhysicalSocketTest, TestConnectIPv4) {
173 MAYBE_SKIP_IPV4;
174 SocketTest::TestConnectIPv4();
175 }
176
177 TEST_F(PhysicalSocketTest, TestConnectIPv6) {
178 SocketTest::TestConnectIPv6();
179 }
180
181 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
182 MAYBE_SKIP_IPV4;
183 SocketTest::TestConnectWithDnsLookupIPv4();
184 }
185
186 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
187 SocketTest::TestConnectWithDnsLookupIPv6();
188 }
189
190 TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
191 MAYBE_SKIP_IPV4;
192 SocketTest::TestConnectFailIPv4();
193 }
194
195 void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) {
196 webrtc::testing::StreamSink sink;
197 SocketAddress accept_addr;
198
199 // Create two clients.
200 std::unique_ptr<AsyncSocket> client1(
201 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
202 sink.Monitor(client1.get());
203 EXPECT_EQ(AsyncSocket::CS_CLOSED, client1->GetState());
204 EXPECT_PRED1(IsUnspecOrEmptyIP, client1->GetLocalAddress().ipaddr());
205
206 std::unique_ptr<AsyncSocket> client2(
207 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
208 sink.Monitor(client2.get());
209 EXPECT_EQ(AsyncSocket::CS_CLOSED, client2->GetState());
210 EXPECT_PRED1(IsUnspecOrEmptyIP, client2->GetLocalAddress().ipaddr());
211
212 // Create server and listen.
213 std::unique_ptr<AsyncSocket> server(
214 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
215 sink.Monitor(server.get());
216 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
217 EXPECT_EQ(0, server->Listen(5));
218 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
219
220 // Ensure no pending server connections, since we haven't done anything yet.
221 EXPECT_FALSE(sink.Check(server.get(), webrtc::testing::SSE_READ));
222 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
223 EXPECT_TRUE(accept_addr.IsNil());
224
225 // Attempt first connect to listening socket.
226 EXPECT_EQ(0, client1->Connect(server->GetLocalAddress()));
227 EXPECT_FALSE(client1->GetLocalAddress().IsNil());
228 EXPECT_NE(server->GetLocalAddress(), client1->GetLocalAddress());
229
230 // Client is connecting, outcome not yet determined.
231 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client1->GetState());
232 EXPECT_FALSE(sink.Check(client1.get(), webrtc::testing::SSE_OPEN));
233 EXPECT_FALSE(sink.Check(client1.get(), webrtc::testing::SSE_CLOSE));
234
235 // Server has pending connection, try to accept it (will fail).
236 EXPECT_TRUE_WAIT((sink.Check(server.get(), webrtc::testing::SSE_READ)),
237 kTimeout);
238 // Simulate "::accept" returning an error.
239 SetFailAccept(true);
240 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
241 EXPECT_FALSE(accepted);
242 ASSERT_TRUE(accept_addr.IsNil());
243
244 // Ensure no more pending server connections.
245 EXPECT_FALSE(sink.Check(server.get(), webrtc::testing::SSE_READ));
246 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
247 EXPECT_TRUE(accept_addr.IsNil());
248
249 // Attempt second connect to listening socket.
250 EXPECT_EQ(0, client2->Connect(server->GetLocalAddress()));
251 EXPECT_FALSE(client2->GetLocalAddress().IsNil());
252 EXPECT_NE(server->GetLocalAddress(), client2->GetLocalAddress());
253
254 // Client is connecting, outcome not yet determined.
255 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client2->GetState());
256 EXPECT_FALSE(sink.Check(client2.get(), webrtc::testing::SSE_OPEN));
257 EXPECT_FALSE(sink.Check(client2.get(), webrtc::testing::SSE_CLOSE));
258
259 // Server has pending connection, try to accept it (will succeed).
260 EXPECT_TRUE_WAIT((sink.Check(server.get(), webrtc::testing::SSE_READ)),
261 kTimeout);
262 SetFailAccept(false);
263 std::unique_ptr<AsyncSocket> accepted2(server->Accept(&accept_addr));
264 ASSERT_TRUE(accepted2);
265 EXPECT_FALSE(accept_addr.IsNil());
266 EXPECT_EQ(accepted2->GetRemoteAddress(), accept_addr);
267 }
268
269 TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv4) {
270 MAYBE_SKIP_IPV4;
271 ConnectInternalAcceptError(kIPv4Loopback);
272 }
273
274 TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv6) {
275 MAYBE_SKIP_IPV6;
276 ConnectInternalAcceptError(kIPv6Loopback);
277 }
278
279 void PhysicalSocketTest::WritableAfterPartialWrite(const IPAddress& loopback) {
280 // Simulate a really small maximum send size.
281 const int kMaxSendSize = 128;
282 SetMaxSendSize(kMaxSendSize);
283
284 // Run the default send/receive socket tests with a smaller amount of data
285 // to avoid long running times due to the small maximum send size.
286 const size_t kDataSize = 128 * 1024;
287 TcpInternal(loopback, kDataSize, kMaxSendSize);
288 }
289
290 // https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
291 #if defined(WEBRTC_WIN)
292 #define MAYBE_TestWritableAfterPartialWriteIPv4 DISABLED_TestWritableAfterPartia lWriteIPv4
293 #else
294 #define MAYBE_TestWritableAfterPartialWriteIPv4 TestWritableAfterPartialWriteIPv 4
295 #endif
296 TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv4) {
297 MAYBE_SKIP_IPV4;
298 WritableAfterPartialWrite(kIPv4Loopback);
299 }
300
301 // https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
302 #if defined(WEBRTC_WIN)
303 #define MAYBE_TestWritableAfterPartialWriteIPv6 DISABLED_TestWritableAfterPartia lWriteIPv6
304 #else
305 #define MAYBE_TestWritableAfterPartialWriteIPv6 TestWritableAfterPartialWriteIPv 6
306 #endif
307 TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv6) {
308 MAYBE_SKIP_IPV6;
309 WritableAfterPartialWrite(kIPv6Loopback);
310 }
311
312 TEST_F(PhysicalSocketTest, TestConnectFailIPv6) {
313 SocketTest::TestConnectFailIPv6();
314 }
315
316 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
317 MAYBE_SKIP_IPV4;
318 SocketTest::TestConnectWithDnsLookupFailIPv4();
319 }
320
321 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) {
322 SocketTest::TestConnectWithDnsLookupFailIPv6();
323 }
324
325
326 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
327 MAYBE_SKIP_IPV4;
328 SocketTest::TestConnectWithClosedSocketIPv4();
329 }
330
331 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) {
332 SocketTest::TestConnectWithClosedSocketIPv6();
333 }
334
335 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
336 MAYBE_SKIP_IPV4;
337 SocketTest::TestConnectWhileNotClosedIPv4();
338 }
339
340 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) {
341 SocketTest::TestConnectWhileNotClosedIPv6();
342 }
343
344 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
345 MAYBE_SKIP_IPV4;
346 SocketTest::TestServerCloseDuringConnectIPv4();
347 }
348
349 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) {
350 SocketTest::TestServerCloseDuringConnectIPv6();
351 }
352
353 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
354 MAYBE_SKIP_IPV4;
355 SocketTest::TestClientCloseDuringConnectIPv4();
356 }
357
358 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) {
359 SocketTest::TestClientCloseDuringConnectIPv6();
360 }
361
362 TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
363 MAYBE_SKIP_IPV4;
364 SocketTest::TestServerCloseIPv4();
365 }
366
367 TEST_F(PhysicalSocketTest, TestServerCloseIPv6) {
368 SocketTest::TestServerCloseIPv6();
369 }
370
371 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
372 MAYBE_SKIP_IPV4;
373 SocketTest::TestCloseInClosedCallbackIPv4();
374 }
375
376 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) {
377 SocketTest::TestCloseInClosedCallbackIPv6();
378 }
379
380 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
381 MAYBE_SKIP_IPV4;
382 SocketTest::TestSocketServerWaitIPv4();
383 }
384
385 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) {
386 SocketTest::TestSocketServerWaitIPv6();
387 }
388
389 TEST_F(PhysicalSocketTest, TestTcpIPv4) {
390 MAYBE_SKIP_IPV4;
391 SocketTest::TestTcpIPv4();
392 }
393
394 TEST_F(PhysicalSocketTest, TestTcpIPv6) {
395 SocketTest::TestTcpIPv6();
396 }
397
398 TEST_F(PhysicalSocketTest, TestUdpIPv4) {
399 MAYBE_SKIP_IPV4;
400 SocketTest::TestUdpIPv4();
401 }
402
403 TEST_F(PhysicalSocketTest, TestUdpIPv6) {
404 SocketTest::TestUdpIPv6();
405 }
406
407 // Disable for TSan v2, see
408 // https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
409 // Also disable for MSan, see:
410 // https://code.google.com/p/webrtc/issues/detail?id=4958
411 // TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
412 // Also disable for ASan.
413 // Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
414 // Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233
415 #if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
416 defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) || \
417 defined(WEBRTC_LINUX)
418 #define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
419 #else
420 #define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
421 #endif
422 TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
423 MAYBE_SKIP_IPV4;
424 SocketTest::TestUdpReadyToSendIPv4();
425 }
426
427 // https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
428 #if defined(WEBRTC_WIN)
429 #define MAYBE_TestUdpReadyToSendIPv6 DISABLED_TestUdpReadyToSendIPv6
430 #else
431 #define MAYBE_TestUdpReadyToSendIPv6 TestUdpReadyToSendIPv6
432 #endif
433 TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv6) {
434 SocketTest::TestUdpReadyToSendIPv6();
435 }
436
437 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
438 MAYBE_SKIP_IPV4;
439 SocketTest::TestGetSetOptionsIPv4();
440 }
441
442 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
443 SocketTest::TestGetSetOptionsIPv6();
444 }
445
446 #if defined(WEBRTC_POSIX)
447
448 // We don't get recv timestamps on Mac.
449 #if !defined(WEBRTC_MAC)
450 TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv4) {
451 MAYBE_SKIP_IPV4;
452 SocketTest::TestSocketRecvTimestampIPv4();
453 }
454
455 TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv6) {
456 SocketTest::TestSocketRecvTimestampIPv6();
457 }
458 #endif
459
460 // Verify that if the socket was unable to be bound to a real network interface
461 // (not loopback), Bind will return an error.
462 TEST_F(PhysicalSocketTest,
463 BindFailsIfNetworkBinderFailsForNonLoopbackInterface) {
464 MAYBE_SKIP_IPV4;
465 FakeNetworkBinder fake_network_binder;
466 server_->set_network_binder(&fake_network_binder);
467 std::unique_ptr<AsyncSocket> socket(
468 server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM));
469 fake_network_binder.set_result(NetworkBindingResult::FAILURE);
470 EXPECT_EQ(-1, socket->Bind(SocketAddress("192.168.0.1", 0)));
471 server_->set_network_binder(nullptr);
472 }
473
474 // Network binder shouldn't be used if the socket is bound to the "any" IP.
475 TEST_F(PhysicalSocketTest,
476 NetworkBinderIsNotUsedForAnyIp) {
477 MAYBE_SKIP_IPV4;
478 FakeNetworkBinder fake_network_binder;
479 server_->set_network_binder(&fake_network_binder);
480 std::unique_ptr<AsyncSocket> socket(
481 server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM));
482 EXPECT_EQ(0, socket->Bind(SocketAddress("0.0.0.0", 0)));
483 EXPECT_EQ(0, fake_network_binder.num_binds());
484 server_->set_network_binder(nullptr);
485 }
486
487 // For a loopback interface, failures to bind to the interface should be
488 // tolerated.
489 TEST_F(PhysicalSocketTest,
490 BindSucceedsIfNetworkBinderFailsForLoopbackInterface) {
491 MAYBE_SKIP_IPV4;
492 FakeNetworkBinder fake_network_binder;
493 server_->set_network_binder(&fake_network_binder);
494 std::unique_ptr<AsyncSocket> socket(
495 server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM));
496 fake_network_binder.set_result(NetworkBindingResult::FAILURE);
497 EXPECT_EQ(0, socket->Bind(SocketAddress(kIPv4Loopback, 0)));
498 server_->set_network_binder(nullptr);
499 }
500
501 class PosixSignalDeliveryTest : public testing::Test {
502 public:
503 static void RecordSignal(int signum) {
504 signals_received_.push_back(signum);
505 signaled_thread_ = Thread::Current();
506 }
507
508 protected:
509 void SetUp() {
510 ss_.reset(new PhysicalSocketServer());
511 }
512
513 void TearDown() {
514 ss_.reset(nullptr);
515 signals_received_.clear();
516 signaled_thread_ = nullptr;
517 }
518
519 bool ExpectSignal(int signum) {
520 if (signals_received_.empty()) {
521 LOG(LS_ERROR) << "ExpectSignal(): No signal received";
522 return false;
523 }
524 if (signals_received_[0] != signum) {
525 LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
526 signals_received_[0] << ", expected " << signum;
527 return false;
528 }
529 signals_received_.erase(signals_received_.begin());
530 return true;
531 }
532
533 bool ExpectNone() {
534 bool ret = signals_received_.empty();
535 if (!ret) {
536 LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
537 << ", expected none";
538 }
539 return ret;
540 }
541
542 static std::vector<int> signals_received_;
543 static Thread *signaled_thread_;
544
545 std::unique_ptr<PhysicalSocketServer> ss_;
546 };
547
548 std::vector<int> PosixSignalDeliveryTest::signals_received_;
549 Thread* PosixSignalDeliveryTest::signaled_thread_ = nullptr;
550
551 // Test receiving a synchronous signal while not in Wait() and then entering
552 // Wait() afterwards.
553 TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
554 ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
555 raise(SIGTERM);
556 EXPECT_TRUE(ss_->Wait(0, true));
557 EXPECT_TRUE(ExpectSignal(SIGTERM));
558 EXPECT_TRUE(ExpectNone());
559 }
560
561 // Test that we can handle getting tons of repeated signals and that we see all
562 // the different ones.
563 TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
564 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
565 ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
566 for (int i = 0; i < 10000; ++i) {
567 raise(SIGTERM);
568 }
569 raise(SIGINT);
570 EXPECT_TRUE(ss_->Wait(0, true));
571 // Order will be lowest signal numbers first.
572 EXPECT_TRUE(ExpectSignal(SIGINT));
573 EXPECT_TRUE(ExpectSignal(SIGTERM));
574 EXPECT_TRUE(ExpectNone());
575 }
576
577 // Test that a signal during a Wait() call is detected.
578 TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
579 ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
580 alarm(1);
581 EXPECT_TRUE(ss_->Wait(1500, true));
582 EXPECT_TRUE(ExpectSignal(SIGALRM));
583 EXPECT_TRUE(ExpectNone());
584 }
585
586 class RaiseSigTermRunnable : public Runnable {
587 void Run(Thread *thread) {
588 thread->socketserver()->Wait(1000, false);
589
590 // Allow SIGTERM. This will be the only thread with it not masked so it will
591 // be delivered to us.
592 sigset_t mask;
593 sigemptyset(&mask);
594 pthread_sigmask(SIG_SETMASK, &mask, nullptr);
595
596 // Raise it.
597 raise(SIGTERM);
598 }
599 };
600
601 // Test that it works no matter what thread the kernel chooses to give the
602 // signal to (since it's not guaranteed to be the one that Wait() runs on).
603 TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
604 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
605 // Mask out SIGTERM so that it can't be delivered to this thread.
606 sigset_t mask;
607 sigemptyset(&mask);
608 sigaddset(&mask, SIGTERM);
609 EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, nullptr));
610 // Start a new thread that raises it. It will have to be delivered to that
611 // thread. Our implementation should safely handle it and dispatch
612 // RecordSignal() on this thread.
613 std::unique_ptr<Thread> thread(new Thread());
614 std::unique_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
615 thread->Start(runnable.get());
616 EXPECT_TRUE(ss_->Wait(1500, true));
617 EXPECT_TRUE(ExpectSignal(SIGTERM));
618 EXPECT_EQ(Thread::Current(), signaled_thread_);
619 EXPECT_TRUE(ExpectNone());
620 }
621
622 #endif
623
624 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/physicalsocketserver.cc ('k') | webrtc/base/platform_file.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698