2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
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.
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 #include "webrtc/test/testsupport/gtest_disable.h"
25 class PhysicalSocketTest : public SocketTest {
28 TEST_F(PhysicalSocketTest, TestConnectIPv4) {
29 SocketTest::TestConnectIPv4();
32 TEST_F(PhysicalSocketTest, TestConnectIPv6) {
33 SocketTest::TestConnectIPv6();
36 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
37 SocketTest::TestConnectWithDnsLookupIPv4();
40 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
41 SocketTest::TestConnectWithDnsLookupIPv6();
44 TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
45 SocketTest::TestConnectFailIPv4();
48 TEST_F(PhysicalSocketTest, TestConnectFailIPv6) {
49 SocketTest::TestConnectFailIPv6();
52 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
53 SocketTest::TestConnectWithDnsLookupFailIPv4();
57 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) {
58 SocketTest::TestConnectWithDnsLookupFailIPv6();
62 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
63 SocketTest::TestConnectWithClosedSocketIPv4();
66 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) {
67 SocketTest::TestConnectWithClosedSocketIPv6();
70 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
71 SocketTest::TestConnectWhileNotClosedIPv4();
74 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) {
75 SocketTest::TestConnectWhileNotClosedIPv6();
78 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
79 SocketTest::TestServerCloseDuringConnectIPv4();
82 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) {
83 SocketTest::TestServerCloseDuringConnectIPv6();
86 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
87 SocketTest::TestClientCloseDuringConnectIPv4();
90 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) {
91 SocketTest::TestClientCloseDuringConnectIPv6();
94 TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
95 SocketTest::TestServerCloseIPv4();
98 TEST_F(PhysicalSocketTest, TestServerCloseIPv6) {
99 SocketTest::TestServerCloseIPv6();
102 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
103 SocketTest::TestCloseInClosedCallbackIPv4();
106 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) {
107 SocketTest::TestCloseInClosedCallbackIPv6();
110 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
111 SocketTest::TestSocketServerWaitIPv4();
114 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) {
115 SocketTest::TestSocketServerWaitIPv6();
118 TEST_F(PhysicalSocketTest, TestTcpIPv4) {
119 SocketTest::TestTcpIPv4();
122 TEST_F(PhysicalSocketTest, TestTcpIPv6) {
123 SocketTest::TestTcpIPv6();
126 TEST_F(PhysicalSocketTest, TestUdpIPv4) {
127 SocketTest::TestUdpIPv4();
130 TEST_F(PhysicalSocketTest, TestUdpIPv6) {
131 SocketTest::TestUdpIPv6();
134 // Disable for TSan v2, see
135 // https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
136 #if !defined(THREAD_SANITIZER)
138 TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv4) {
139 SocketTest::TestUdpReadyToSendIPv4();
142 #endif // if !defined(THREAD_SANITIZER)
144 TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
145 SocketTest::TestUdpReadyToSendIPv6();
148 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
149 SocketTest::TestGetSetOptionsIPv4();
152 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
153 SocketTest::TestGetSetOptionsIPv6();
156 #if defined(WEBRTC_POSIX)
158 class PosixSignalDeliveryTest : public testing::Test {
160 static void RecordSignal(int signum) {
161 signals_received_.push_back(signum);
162 signaled_thread_ = Thread::Current();
167 ss_.reset(new PhysicalSocketServer());
172 signals_received_.clear();
173 signaled_thread_ = NULL;
176 bool ExpectSignal(int signum) {
177 if (signals_received_.empty()) {
178 LOG(LS_ERROR) << "ExpectSignal(): No signal received";
181 if (signals_received_[0] != signum) {
182 LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
183 signals_received_[0] << ", expected " << signum;
186 signals_received_.erase(signals_received_.begin());
191 bool ret = signals_received_.empty();
193 LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
194 << ", expected none";
199 static std::vector<int> signals_received_;
200 static Thread *signaled_thread_;
202 scoped_ptr<PhysicalSocketServer> ss_;
205 std::vector<int> PosixSignalDeliveryTest::signals_received_;
206 Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
208 // Test receiving a synchronous signal while not in Wait() and then entering
209 // Wait() afterwards.
210 TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
211 ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
213 EXPECT_TRUE(ss_->Wait(0, true));
214 EXPECT_TRUE(ExpectSignal(SIGTERM));
215 EXPECT_TRUE(ExpectNone());
218 // Test that we can handle getting tons of repeated signals and that we see all
219 // the different ones.
220 TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
221 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
222 ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
223 for (int i = 0; i < 10000; ++i) {
227 EXPECT_TRUE(ss_->Wait(0, true));
228 // Order will be lowest signal numbers first.
229 EXPECT_TRUE(ExpectSignal(SIGINT));
230 EXPECT_TRUE(ExpectSignal(SIGTERM));
231 EXPECT_TRUE(ExpectNone());
234 // Test that a signal during a Wait() call is detected.
235 TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
236 ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
238 EXPECT_TRUE(ss_->Wait(1500, true));
239 EXPECT_TRUE(ExpectSignal(SIGALRM));
240 EXPECT_TRUE(ExpectNone());
243 class RaiseSigTermRunnable : public Runnable {
244 void Run(Thread *thread) {
245 thread->socketserver()->Wait(1000, false);
247 // Allow SIGTERM. This will be the only thread with it not masked so it will
248 // be delivered to us.
251 pthread_sigmask(SIG_SETMASK, &mask, NULL);
258 // Test that it works no matter what thread the kernel chooses to give the
259 // signal to (since it's not guaranteed to be the one that Wait() runs on).
260 TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
261 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
262 // Mask out SIGTERM so that it can't be delivered to this thread.
265 sigaddset(&mask, SIGTERM);
266 EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
267 // Start a new thread that raises it. It will have to be delivered to that
268 // thread. Our implementation should safely handle it and dispatch
269 // RecordSignal() on this thread.
270 scoped_ptr<Thread> thread(new Thread());
271 scoped_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
272 thread->Start(runnable.get());
273 EXPECT_TRUE(ss_->Wait(1500, true));
274 EXPECT_TRUE(ExpectSignal(SIGTERM));
275 EXPECT_EQ(Thread::Current(), signaled_thread_);
276 EXPECT_TRUE(ExpectNone());