blob: 3b7ed7bff2cc5e1495bf0b914c933a86030398cf [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
25class PhysicalSocketTest : public SocketTest {
26};
27
28TEST_F(PhysicalSocketTest, TestConnectIPv4) {
29 SocketTest::TestConnectIPv4();
30}
31
32TEST_F(PhysicalSocketTest, TestConnectIPv6) {
33 SocketTest::TestConnectIPv6();
34}
35
36TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
37 SocketTest::TestConnectWithDnsLookupIPv4();
38}
39
40TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
41 SocketTest::TestConnectWithDnsLookupIPv6();
42}
43
44TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
45 SocketTest::TestConnectFailIPv4();
46}
47
48TEST_F(PhysicalSocketTest, TestConnectFailIPv6) {
49 SocketTest::TestConnectFailIPv6();
50}
51
52TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
53 SocketTest::TestConnectWithDnsLookupFailIPv4();
54}
55
56
57TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) {
58 SocketTest::TestConnectWithDnsLookupFailIPv6();
59}
60
61
62TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
63 SocketTest::TestConnectWithClosedSocketIPv4();
64}
65
66TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) {
67 SocketTest::TestConnectWithClosedSocketIPv6();
68}
69
70TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
71 SocketTest::TestConnectWhileNotClosedIPv4();
72}
73
74TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) {
75 SocketTest::TestConnectWhileNotClosedIPv6();
76}
77
78TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
79 SocketTest::TestServerCloseDuringConnectIPv4();
80}
81
82TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) {
83 SocketTest::TestServerCloseDuringConnectIPv6();
84}
85
86TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
87 SocketTest::TestClientCloseDuringConnectIPv4();
88}
89
90TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) {
91 SocketTest::TestClientCloseDuringConnectIPv6();
92}
93
94TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
95 SocketTest::TestServerCloseIPv4();
96}
97
98TEST_F(PhysicalSocketTest, TestServerCloseIPv6) {
99 SocketTest::TestServerCloseIPv6();
100}
101
102TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
103 SocketTest::TestCloseInClosedCallbackIPv4();
104}
105
106TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) {
107 SocketTest::TestCloseInClosedCallbackIPv6();
108}
109
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000110TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000111 SocketTest::TestSocketServerWaitIPv4();
112}
113
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000114TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000115 SocketTest::TestSocketServerWaitIPv6();
116}
117
118TEST_F(PhysicalSocketTest, TestTcpIPv4) {
119 SocketTest::TestTcpIPv4();
120}
121
122TEST_F(PhysicalSocketTest, TestTcpIPv6) {
123 SocketTest::TestTcpIPv6();
124}
125
126TEST_F(PhysicalSocketTest, TestUdpIPv4) {
127 SocketTest::TestUdpIPv4();
128}
129
130TEST_F(PhysicalSocketTest, TestUdpIPv6) {
131 SocketTest::TestUdpIPv6();
132}
133
henrike@webrtc.org6f833c32014-06-27 16:21:49 +0000134// Disable for TSan v2, see
135// https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
136#if !defined(THREAD_SANITIZER)
137
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000138TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv4) {
139 SocketTest::TestUdpReadyToSendIPv4();
140}
141
henrike@webrtc.org6f833c32014-06-27 16:21:49 +0000142#endif // if !defined(THREAD_SANITIZER)
143
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000144TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000145 SocketTest::TestUdpReadyToSendIPv6();
146}
147
148TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
149 SocketTest::TestGetSetOptionsIPv4();
150}
151
152TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
153 SocketTest::TestGetSetOptionsIPv6();
154}
155
156#if defined(WEBRTC_POSIX)
157
158class PosixSignalDeliveryTest : public testing::Test {
159 public:
160 static void RecordSignal(int signum) {
161 signals_received_.push_back(signum);
162 signaled_thread_ = Thread::Current();
163 }
164
165 protected:
166 void SetUp() {
167 ss_.reset(new PhysicalSocketServer());
168 }
169
170 void TearDown() {
171 ss_.reset(NULL);
172 signals_received_.clear();
173 signaled_thread_ = NULL;
174 }
175
176 bool ExpectSignal(int signum) {
177 if (signals_received_.empty()) {
178 LOG(LS_ERROR) << "ExpectSignal(): No signal received";
179 return false;
180 }
181 if (signals_received_[0] != signum) {
182 LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
183 signals_received_[0] << ", expected " << signum;
184 return false;
185 }
186 signals_received_.erase(signals_received_.begin());
187 return true;
188 }
189
190 bool ExpectNone() {
191 bool ret = signals_received_.empty();
192 if (!ret) {
193 LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
194 << ", expected none";
195 }
196 return ret;
197 }
198
199 static std::vector<int> signals_received_;
200 static Thread *signaled_thread_;
201
202 scoped_ptr<PhysicalSocketServer> ss_;
203};
204
205std::vector<int> PosixSignalDeliveryTest::signals_received_;
206Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
207
208// Test receiving a synchronous signal while not in Wait() and then entering
209// Wait() afterwards.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000210TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000211 ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
212 raise(SIGTERM);
213 EXPECT_TRUE(ss_->Wait(0, true));
214 EXPECT_TRUE(ExpectSignal(SIGTERM));
215 EXPECT_TRUE(ExpectNone());
216}
217
218// Test that we can handle getting tons of repeated signals and that we see all
219// the different ones.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000220TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000221 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
222 ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
223 for (int i = 0; i < 10000; ++i) {
224 raise(SIGTERM);
225 }
226 raise(SIGINT);
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());
232}
233
234// Test that a signal during a Wait() call is detected.
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000235TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000236 ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
237 alarm(1);
238 EXPECT_TRUE(ss_->Wait(1500, true));
239 EXPECT_TRUE(ExpectSignal(SIGALRM));
240 EXPECT_TRUE(ExpectNone());
241}
242
243class RaiseSigTermRunnable : public Runnable {
244 void Run(Thread *thread) {
245 thread->socketserver()->Wait(1000, false);
246
247 // Allow SIGTERM. This will be the only thread with it not masked so it will
248 // be delivered to us.
249 sigset_t mask;
250 sigemptyset(&mask);
251 pthread_sigmask(SIG_SETMASK, &mask, NULL);
252
253 // Raise it.
254 raise(SIGTERM);
255 }
256};
257
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).
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000260TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000261 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
262 // Mask out SIGTERM so that it can't be delivered to this thread.
263 sigset_t mask;
264 sigemptyset(&mask);
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());
277}
278
279#endif
280
281} // namespace rtc