Index: webrtc/base/physicalsocketserver_unittest.cc |
diff --git a/webrtc/base/physicalsocketserver_unittest.cc b/webrtc/base/physicalsocketserver_unittest.cc |
deleted file mode 100644 |
index 20e66ce2b68f8e3b1982160f684249c86f3d52c4..0000000000000000000000000000000000000000 |
--- a/webrtc/base/physicalsocketserver_unittest.cc |
+++ /dev/null |
@@ -1,624 +0,0 @@ |
-/* |
- * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
- * |
- * Use of this source code is governed by a BSD-style license |
- * that can be found in the LICENSE file in the root of the source |
- * tree. An additional intellectual property rights grant can be found |
- * in the file PATENTS. All contributing project authors may |
- * be found in the AUTHORS file in the root of the source tree. |
- */ |
- |
-#include <memory> |
-#include <signal.h> |
-#include <stdarg.h> |
- |
-#include "webrtc/base/gunit.h" |
-#include "webrtc/base/logging.h" |
-#include "webrtc/base/networkmonitor.h" |
-#include "webrtc/base/physicalsocketserver.h" |
-#include "webrtc/base/socket_unittest.h" |
-#include "webrtc/base/testutils.h" |
-#include "webrtc/base/thread.h" |
- |
-namespace rtc { |
- |
-#define MAYBE_SKIP_IPV4 \ |
- if (!HasIPv4Enabled()) { \ |
- LOG(LS_INFO) << "No IPv4... skipping"; \ |
- return; \ |
- } |
- |
-#define MAYBE_SKIP_IPV6 \ |
- if (!HasIPv6Enabled()) { \ |
- LOG(LS_INFO) << "No IPv6... skipping"; \ |
- return; \ |
- } |
- |
-class PhysicalSocketTest; |
- |
-class FakeSocketDispatcher : public SocketDispatcher { |
- public: |
- explicit FakeSocketDispatcher(PhysicalSocketServer* ss) |
- : SocketDispatcher(ss) { |
- } |
- |
- FakeSocketDispatcher(SOCKET s, PhysicalSocketServer* ss) |
- : SocketDispatcher(s, ss) { |
- } |
- |
- protected: |
- SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override; |
- int DoSend(SOCKET socket, const char* buf, int len, int flags) override; |
- int DoSendTo(SOCKET socket, const char* buf, int len, int flags, |
- const struct sockaddr* dest_addr, socklen_t addrlen) override; |
-}; |
- |
-class FakePhysicalSocketServer : public PhysicalSocketServer { |
- public: |
- explicit FakePhysicalSocketServer(PhysicalSocketTest* test) |
- : test_(test) { |
- } |
- |
- AsyncSocket* CreateAsyncSocket(int type) override { |
- SocketDispatcher* dispatcher = new FakeSocketDispatcher(this); |
- if (!dispatcher->Create(type)) { |
- delete dispatcher; |
- return nullptr; |
- } |
- return dispatcher; |
- } |
- |
- AsyncSocket* CreateAsyncSocket(int family, int type) override { |
- SocketDispatcher* dispatcher = new FakeSocketDispatcher(this); |
- if (!dispatcher->Create(family, type)) { |
- delete dispatcher; |
- return nullptr; |
- } |
- return dispatcher; |
- } |
- |
- AsyncSocket* WrapSocket(SOCKET s) override { |
- SocketDispatcher* dispatcher = new FakeSocketDispatcher(s, this); |
- if (!dispatcher->Initialize()) { |
- delete dispatcher; |
- return nullptr; |
- } |
- return dispatcher; |
- } |
- |
- PhysicalSocketTest* GetTest() const { return test_; } |
- |
- private: |
- PhysicalSocketTest* test_; |
-}; |
- |
-class FakeNetworkBinder : public NetworkBinderInterface { |
- public: |
- NetworkBindingResult BindSocketToNetwork(int, const IPAddress&) override { |
- ++num_binds_; |
- return result_; |
- } |
- |
- void set_result(NetworkBindingResult result) { result_ = result; } |
- |
- int num_binds() { return num_binds_; } |
- |
- private: |
- NetworkBindingResult result_ = NetworkBindingResult::SUCCESS; |
- int num_binds_ = 0; |
-}; |
- |
-class PhysicalSocketTest : public SocketTest { |
- public: |
- // Set flag to simluate failures when calling "::accept" on a AsyncSocket. |
- void SetFailAccept(bool fail) { fail_accept_ = fail; } |
- bool FailAccept() const { return fail_accept_; } |
- |
- // Maximum size to ::send to a socket. Set to < 0 to disable limiting. |
- void SetMaxSendSize(int max_size) { max_send_size_ = max_size; } |
- int MaxSendSize() const { return max_send_size_; } |
- |
- protected: |
- PhysicalSocketTest() |
- : server_(new FakePhysicalSocketServer(this)), |
- thread_(server_.get()), |
- fail_accept_(false), |
- max_send_size_(-1) {} |
- |
- void ConnectInternalAcceptError(const IPAddress& loopback); |
- void WritableAfterPartialWrite(const IPAddress& loopback); |
- |
- std::unique_ptr<FakePhysicalSocketServer> server_; |
- rtc::AutoSocketServerThread thread_; |
- bool fail_accept_; |
- int max_send_size_; |
-}; |
- |
-SOCKET FakeSocketDispatcher::DoAccept(SOCKET socket, |
- sockaddr* addr, |
- socklen_t* addrlen) { |
- FakePhysicalSocketServer* ss = |
- static_cast<FakePhysicalSocketServer*>(socketserver()); |
- if (ss->GetTest()->FailAccept()) { |
- return INVALID_SOCKET; |
- } |
- |
- return SocketDispatcher::DoAccept(socket, addr, addrlen); |
-} |
- |
-int FakeSocketDispatcher::DoSend(SOCKET socket, const char* buf, int len, |
- int flags) { |
- FakePhysicalSocketServer* ss = |
- static_cast<FakePhysicalSocketServer*>(socketserver()); |
- if (ss->GetTest()->MaxSendSize() >= 0) { |
- len = std::min(len, ss->GetTest()->MaxSendSize()); |
- } |
- |
- return SocketDispatcher::DoSend(socket, buf, len, flags); |
-} |
- |
-int FakeSocketDispatcher::DoSendTo(SOCKET socket, const char* buf, int len, |
- int flags, const struct sockaddr* dest_addr, socklen_t addrlen) { |
- FakePhysicalSocketServer* ss = |
- static_cast<FakePhysicalSocketServer*>(socketserver()); |
- if (ss->GetTest()->MaxSendSize() >= 0) { |
- len = std::min(len, ss->GetTest()->MaxSendSize()); |
- } |
- |
- return SocketDispatcher::DoSendTo(socket, buf, len, flags, dest_addr, |
- addrlen); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestConnectIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectIPv6) { |
- SocketTest::TestConnectIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestConnectWithDnsLookupIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) { |
- SocketTest::TestConnectWithDnsLookupIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectFailIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestConnectFailIPv4(); |
-} |
- |
-void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) { |
- webrtc::testing::StreamSink sink; |
- SocketAddress accept_addr; |
- |
- // Create two clients. |
- std::unique_ptr<AsyncSocket> client1( |
- server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); |
- sink.Monitor(client1.get()); |
- EXPECT_EQ(AsyncSocket::CS_CLOSED, client1->GetState()); |
- EXPECT_PRED1(IsUnspecOrEmptyIP, client1->GetLocalAddress().ipaddr()); |
- |
- std::unique_ptr<AsyncSocket> client2( |
- server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); |
- sink.Monitor(client2.get()); |
- EXPECT_EQ(AsyncSocket::CS_CLOSED, client2->GetState()); |
- EXPECT_PRED1(IsUnspecOrEmptyIP, client2->GetLocalAddress().ipaddr()); |
- |
- // Create server and listen. |
- std::unique_ptr<AsyncSocket> server( |
- server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM)); |
- sink.Monitor(server.get()); |
- EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0))); |
- EXPECT_EQ(0, server->Listen(5)); |
- EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState()); |
- |
- // Ensure no pending server connections, since we haven't done anything yet. |
- EXPECT_FALSE(sink.Check(server.get(), webrtc::testing::SSE_READ)); |
- EXPECT_TRUE(nullptr == server->Accept(&accept_addr)); |
- EXPECT_TRUE(accept_addr.IsNil()); |
- |
- // Attempt first connect to listening socket. |
- EXPECT_EQ(0, client1->Connect(server->GetLocalAddress())); |
- EXPECT_FALSE(client1->GetLocalAddress().IsNil()); |
- EXPECT_NE(server->GetLocalAddress(), client1->GetLocalAddress()); |
- |
- // Client is connecting, outcome not yet determined. |
- EXPECT_EQ(AsyncSocket::CS_CONNECTING, client1->GetState()); |
- EXPECT_FALSE(sink.Check(client1.get(), webrtc::testing::SSE_OPEN)); |
- EXPECT_FALSE(sink.Check(client1.get(), webrtc::testing::SSE_CLOSE)); |
- |
- // Server has pending connection, try to accept it (will fail). |
- EXPECT_TRUE_WAIT((sink.Check(server.get(), webrtc::testing::SSE_READ)), |
- kTimeout); |
- // Simulate "::accept" returning an error. |
- SetFailAccept(true); |
- std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr)); |
- EXPECT_FALSE(accepted); |
- ASSERT_TRUE(accept_addr.IsNil()); |
- |
- // Ensure no more pending server connections. |
- EXPECT_FALSE(sink.Check(server.get(), webrtc::testing::SSE_READ)); |
- EXPECT_TRUE(nullptr == server->Accept(&accept_addr)); |
- EXPECT_TRUE(accept_addr.IsNil()); |
- |
- // Attempt second connect to listening socket. |
- EXPECT_EQ(0, client2->Connect(server->GetLocalAddress())); |
- EXPECT_FALSE(client2->GetLocalAddress().IsNil()); |
- EXPECT_NE(server->GetLocalAddress(), client2->GetLocalAddress()); |
- |
- // Client is connecting, outcome not yet determined. |
- EXPECT_EQ(AsyncSocket::CS_CONNECTING, client2->GetState()); |
- EXPECT_FALSE(sink.Check(client2.get(), webrtc::testing::SSE_OPEN)); |
- EXPECT_FALSE(sink.Check(client2.get(), webrtc::testing::SSE_CLOSE)); |
- |
- // Server has pending connection, try to accept it (will succeed). |
- EXPECT_TRUE_WAIT((sink.Check(server.get(), webrtc::testing::SSE_READ)), |
- kTimeout); |
- SetFailAccept(false); |
- std::unique_ptr<AsyncSocket> accepted2(server->Accept(&accept_addr)); |
- ASSERT_TRUE(accepted2); |
- EXPECT_FALSE(accept_addr.IsNil()); |
- EXPECT_EQ(accepted2->GetRemoteAddress(), accept_addr); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv4) { |
- MAYBE_SKIP_IPV4; |
- ConnectInternalAcceptError(kIPv4Loopback); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv6) { |
- MAYBE_SKIP_IPV6; |
- ConnectInternalAcceptError(kIPv6Loopback); |
-} |
- |
-void PhysicalSocketTest::WritableAfterPartialWrite(const IPAddress& loopback) { |
- // Simulate a really small maximum send size. |
- const int kMaxSendSize = 128; |
- SetMaxSendSize(kMaxSendSize); |
- |
- // Run the default send/receive socket tests with a smaller amount of data |
- // to avoid long running times due to the small maximum send size. |
- const size_t kDataSize = 128 * 1024; |
- TcpInternal(loopback, kDataSize, kMaxSendSize); |
-} |
- |
-// https://bugs.chromium.org/p/webrtc/issues/detail?id=6167 |
-#if defined(WEBRTC_WIN) |
-#define MAYBE_TestWritableAfterPartialWriteIPv4 DISABLED_TestWritableAfterPartialWriteIPv4 |
-#else |
-#define MAYBE_TestWritableAfterPartialWriteIPv4 TestWritableAfterPartialWriteIPv4 |
-#endif |
-TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv4) { |
- MAYBE_SKIP_IPV4; |
- WritableAfterPartialWrite(kIPv4Loopback); |
-} |
- |
-// https://bugs.chromium.org/p/webrtc/issues/detail?id=6167 |
-#if defined(WEBRTC_WIN) |
-#define MAYBE_TestWritableAfterPartialWriteIPv6 DISABLED_TestWritableAfterPartialWriteIPv6 |
-#else |
-#define MAYBE_TestWritableAfterPartialWriteIPv6 TestWritableAfterPartialWriteIPv6 |
-#endif |
-TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv6) { |
- MAYBE_SKIP_IPV6; |
- WritableAfterPartialWrite(kIPv6Loopback); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectFailIPv6) { |
- SocketTest::TestConnectFailIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestConnectWithDnsLookupFailIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) { |
- SocketTest::TestConnectWithDnsLookupFailIPv6(); |
-} |
- |
- |
-TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestConnectWithClosedSocketIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) { |
- SocketTest::TestConnectWithClosedSocketIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestConnectWhileNotClosedIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) { |
- SocketTest::TestConnectWhileNotClosedIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestServerCloseDuringConnectIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) { |
- SocketTest::TestServerCloseDuringConnectIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestClientCloseDuringConnectIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) { |
- SocketTest::TestClientCloseDuringConnectIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestServerCloseIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestServerCloseIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestServerCloseIPv6) { |
- SocketTest::TestServerCloseIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestCloseInClosedCallbackIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) { |
- SocketTest::TestCloseInClosedCallbackIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestSocketServerWaitIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) { |
- SocketTest::TestSocketServerWaitIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestTcpIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestTcpIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestTcpIPv6) { |
- SocketTest::TestTcpIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestUdpIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestUdpIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestUdpIPv6) { |
- SocketTest::TestUdpIPv6(); |
-} |
- |
-// Disable for TSan v2, see |
-// https://code.google.com/p/webrtc/issues/detail?id=3498 for details. |
-// Also disable for MSan, see: |
-// https://code.google.com/p/webrtc/issues/detail?id=4958 |
-// TODO(deadbeef): Enable again once test is reimplemented to be unflaky. |
-// Also disable for ASan. |
-// Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364 |
-// Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233 |
-#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \ |
- defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) || \ |
- defined(WEBRTC_LINUX) |
-#define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4 |
-#else |
-#define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4 |
-#endif |
-TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestUdpReadyToSendIPv4(); |
-} |
- |
-// https://bugs.chromium.org/p/webrtc/issues/detail?id=6167 |
-#if defined(WEBRTC_WIN) |
-#define MAYBE_TestUdpReadyToSendIPv6 DISABLED_TestUdpReadyToSendIPv6 |
-#else |
-#define MAYBE_TestUdpReadyToSendIPv6 TestUdpReadyToSendIPv6 |
-#endif |
-TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv6) { |
- SocketTest::TestUdpReadyToSendIPv6(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestGetSetOptionsIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) { |
- SocketTest::TestGetSetOptionsIPv6(); |
-} |
- |
-#if defined(WEBRTC_POSIX) |
- |
-// We don't get recv timestamps on Mac. |
-#if !defined(WEBRTC_MAC) |
-TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv4) { |
- MAYBE_SKIP_IPV4; |
- SocketTest::TestSocketRecvTimestampIPv4(); |
-} |
- |
-TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv6) { |
- SocketTest::TestSocketRecvTimestampIPv6(); |
-} |
-#endif |
- |
-// Verify that if the socket was unable to be bound to a real network interface |
-// (not loopback), Bind will return an error. |
-TEST_F(PhysicalSocketTest, |
- BindFailsIfNetworkBinderFailsForNonLoopbackInterface) { |
- MAYBE_SKIP_IPV4; |
- FakeNetworkBinder fake_network_binder; |
- server_->set_network_binder(&fake_network_binder); |
- std::unique_ptr<AsyncSocket> socket( |
- server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM)); |
- fake_network_binder.set_result(NetworkBindingResult::FAILURE); |
- EXPECT_EQ(-1, socket->Bind(SocketAddress("192.168.0.1", 0))); |
- server_->set_network_binder(nullptr); |
-} |
- |
-// Network binder shouldn't be used if the socket is bound to the "any" IP. |
-TEST_F(PhysicalSocketTest, |
- NetworkBinderIsNotUsedForAnyIp) { |
- MAYBE_SKIP_IPV4; |
- FakeNetworkBinder fake_network_binder; |
- server_->set_network_binder(&fake_network_binder); |
- std::unique_ptr<AsyncSocket> socket( |
- server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM)); |
- EXPECT_EQ(0, socket->Bind(SocketAddress("0.0.0.0", 0))); |
- EXPECT_EQ(0, fake_network_binder.num_binds()); |
- server_->set_network_binder(nullptr); |
-} |
- |
-// For a loopback interface, failures to bind to the interface should be |
-// tolerated. |
-TEST_F(PhysicalSocketTest, |
- BindSucceedsIfNetworkBinderFailsForLoopbackInterface) { |
- MAYBE_SKIP_IPV4; |
- FakeNetworkBinder fake_network_binder; |
- server_->set_network_binder(&fake_network_binder); |
- std::unique_ptr<AsyncSocket> socket( |
- server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM)); |
- fake_network_binder.set_result(NetworkBindingResult::FAILURE); |
- EXPECT_EQ(0, socket->Bind(SocketAddress(kIPv4Loopback, 0))); |
- server_->set_network_binder(nullptr); |
-} |
- |
-class PosixSignalDeliveryTest : public testing::Test { |
- public: |
- static void RecordSignal(int signum) { |
- signals_received_.push_back(signum); |
- signaled_thread_ = Thread::Current(); |
- } |
- |
- protected: |
- void SetUp() { |
- ss_.reset(new PhysicalSocketServer()); |
- } |
- |
- void TearDown() { |
- ss_.reset(nullptr); |
- signals_received_.clear(); |
- signaled_thread_ = nullptr; |
- } |
- |
- bool ExpectSignal(int signum) { |
- if (signals_received_.empty()) { |
- LOG(LS_ERROR) << "ExpectSignal(): No signal received"; |
- return false; |
- } |
- if (signals_received_[0] != signum) { |
- LOG(LS_ERROR) << "ExpectSignal(): Received signal " << |
- signals_received_[0] << ", expected " << signum; |
- return false; |
- } |
- signals_received_.erase(signals_received_.begin()); |
- return true; |
- } |
- |
- bool ExpectNone() { |
- bool ret = signals_received_.empty(); |
- if (!ret) { |
- LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0] |
- << ", expected none"; |
- } |
- return ret; |
- } |
- |
- static std::vector<int> signals_received_; |
- static Thread *signaled_thread_; |
- |
- std::unique_ptr<PhysicalSocketServer> ss_; |
-}; |
- |
-std::vector<int> PosixSignalDeliveryTest::signals_received_; |
-Thread* PosixSignalDeliveryTest::signaled_thread_ = nullptr; |
- |
-// Test receiving a synchronous signal while not in Wait() and then entering |
-// Wait() afterwards. |
-TEST_F(PosixSignalDeliveryTest, RaiseThenWait) { |
- ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal)); |
- raise(SIGTERM); |
- EXPECT_TRUE(ss_->Wait(0, true)); |
- EXPECT_TRUE(ExpectSignal(SIGTERM)); |
- EXPECT_TRUE(ExpectNone()); |
-} |
- |
-// Test that we can handle getting tons of repeated signals and that we see all |
-// the different ones. |
-TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) { |
- ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal); |
- ss_->SetPosixSignalHandler(SIGINT, &RecordSignal); |
- for (int i = 0; i < 10000; ++i) { |
- raise(SIGTERM); |
- } |
- raise(SIGINT); |
- EXPECT_TRUE(ss_->Wait(0, true)); |
- // Order will be lowest signal numbers first. |
- EXPECT_TRUE(ExpectSignal(SIGINT)); |
- EXPECT_TRUE(ExpectSignal(SIGTERM)); |
- EXPECT_TRUE(ExpectNone()); |
-} |
- |
-// Test that a signal during a Wait() call is detected. |
-TEST_F(PosixSignalDeliveryTest, SignalDuringWait) { |
- ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal); |
- alarm(1); |
- EXPECT_TRUE(ss_->Wait(1500, true)); |
- EXPECT_TRUE(ExpectSignal(SIGALRM)); |
- EXPECT_TRUE(ExpectNone()); |
-} |
- |
-class RaiseSigTermRunnable : public Runnable { |
- void Run(Thread *thread) { |
- thread->socketserver()->Wait(1000, false); |
- |
- // Allow SIGTERM. This will be the only thread with it not masked so it will |
- // be delivered to us. |
- sigset_t mask; |
- sigemptyset(&mask); |
- pthread_sigmask(SIG_SETMASK, &mask, nullptr); |
- |
- // Raise it. |
- raise(SIGTERM); |
- } |
-}; |
- |
-// Test that it works no matter what thread the kernel chooses to give the |
-// signal to (since it's not guaranteed to be the one that Wait() runs on). |
-TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) { |
- ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal); |
- // Mask out SIGTERM so that it can't be delivered to this thread. |
- sigset_t mask; |
- sigemptyset(&mask); |
- sigaddset(&mask, SIGTERM); |
- EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, nullptr)); |
- // Start a new thread that raises it. It will have to be delivered to that |
- // thread. Our implementation should safely handle it and dispatch |
- // RecordSignal() on this thread. |
- std::unique_ptr<Thread> thread(new Thread()); |
- std::unique_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable()); |
- thread->Start(runnable.get()); |
- EXPECT_TRUE(ss_->Wait(1500, true)); |
- EXPECT_TRUE(ExpectSignal(SIGTERM)); |
- EXPECT_EQ(Thread::Current(), signaled_thread_); |
- EXPECT_TRUE(ExpectNone()); |
-} |
- |
-#endif |
- |
-} // namespace rtc |