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 #include "webrtc/test/testsupport/gtest_disable.h" 22 23 namespace rtc { 24 25 class PhysicalSocketTest : public SocketTest { 26 }; 27 28 TEST_F(PhysicalSocketTest, TestConnectIPv4) { 29 SocketTest::TestConnectIPv4(); 30 } 31 32 TEST_F(PhysicalSocketTest, TestConnectIPv6) { 33 SocketTest::TestConnectIPv6(); 34 } 35 36 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) { 37 SocketTest::TestConnectWithDnsLookupIPv4(); 38 } 39 40 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) { 41 SocketTest::TestConnectWithDnsLookupIPv6(); 42 } 43 44 TEST_F(PhysicalSocketTest, TestConnectFailIPv4) { 45 SocketTest::TestConnectFailIPv4(); 46 } 47 48 TEST_F(PhysicalSocketTest, TestConnectFailIPv6) { 49 SocketTest::TestConnectFailIPv6(); 50 } 51 52 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) { 53 SocketTest::TestConnectWithDnsLookupFailIPv4(); 54 } 55 56 57 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) { 58 SocketTest::TestConnectWithDnsLookupFailIPv6(); 59 } 60 61 62 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) { 63 SocketTest::TestConnectWithClosedSocketIPv4(); 64 } 65 66 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) { 67 SocketTest::TestConnectWithClosedSocketIPv6(); 68 } 69 70 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) { 71 SocketTest::TestConnectWhileNotClosedIPv4(); 72 } 73 74 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) { 75 SocketTest::TestConnectWhileNotClosedIPv6(); 76 } 77 78 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) { 79 SocketTest::TestServerCloseDuringConnectIPv4(); 80 } 81 82 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) { 83 SocketTest::TestServerCloseDuringConnectIPv6(); 84 } 85 86 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) { 87 SocketTest::TestClientCloseDuringConnectIPv4(); 88 } 89 90 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) { 91 SocketTest::TestClientCloseDuringConnectIPv6(); 92 } 93 94 TEST_F(PhysicalSocketTest, TestServerCloseIPv4) { 95 SocketTest::TestServerCloseIPv4(); 96 } 97 98 TEST_F(PhysicalSocketTest, TestServerCloseIPv6) { 99 SocketTest::TestServerCloseIPv6(); 100 } 101 102 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) { 103 SocketTest::TestCloseInClosedCallbackIPv4(); 104 } 105 106 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) { 107 SocketTest::TestCloseInClosedCallbackIPv6(); 108 } 109 110 TEST_F(PhysicalSocketTest, DISABLED_ON_MAC(TestSocketServerWaitIPv4)) { 111 SocketTest::TestSocketServerWaitIPv4(); 112 } 113 114 TEST_F(PhysicalSocketTest, DISABLED_ON_MAC(TestSocketServerWaitIPv6)) { 115 SocketTest::TestSocketServerWaitIPv6(); 116 } 117 118 TEST_F(PhysicalSocketTest, TestTcpIPv4) { 119 SocketTest::TestTcpIPv4(); 120 } 121 122 TEST_F(PhysicalSocketTest, TestTcpIPv6) { 123 SocketTest::TestTcpIPv6(); 124 } 125 126 TEST_F(PhysicalSocketTest, TestUdpIPv4) { 127 SocketTest::TestUdpIPv4(); 128 } 129 130 TEST_F(PhysicalSocketTest, TestUdpIPv6) { 131 SocketTest::TestUdpIPv6(); 132 } 133 134 // Disable for TSan v2, see 135 // https://code.google.com/p/webrtc/issues/detail?id=3498 for details. 136 #if !defined(THREAD_SANITIZER) 137 138 TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv4) { 139 SocketTest::TestUdpReadyToSendIPv4(); 140 } 141 142 #endif // if !defined(THREAD_SANITIZER) 143 144 TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) { 145 SocketTest::TestUdpReadyToSendIPv6(); 146 } 147 148 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) { 149 SocketTest::TestGetSetOptionsIPv4(); 150 } 151 152 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) { 153 SocketTest::TestGetSetOptionsIPv6(); 154 } 155 156 #if defined(WEBRTC_POSIX) 157 158 class 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 205 std::vector<int> PosixSignalDeliveryTest::signals_received_; 206 Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL; 207 208 // Test receiving a synchronous signal while not in Wait() and then entering 209 // Wait() afterwards. 210 TEST_F(PosixSignalDeliveryTest, DISABLED_ON_MAC(RaiseThenWait)) { 211 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. 220 TEST_F(PosixSignalDeliveryTest, DISABLED_ON_MAC(InsanelyManySignals)) { 221 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. 235 TEST_F(PosixSignalDeliveryTest, DISABLED_ON_MAC(SignalDuringWait)) { 236 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 243 class 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). 260 TEST_F(PosixSignalDeliveryTest, DISABLED_ON_MAC(SignalOnDifferentThread)) { 261 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 282