Home | History | Annotate | Download | only in base
      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