Files
platform-external-webrtc/webrtc/base/physicalsocketserver_unittest.cc
Peter Boström e2976c87f7 Remove DISABLED_ON_ macros.
Macro incorrectly displays DISABLED_ON_ANDROID in test names for
parameterized tests under --gtest_list_tests, causing tests to be
disabled on all platforms since they contain the DISABLED_ prefix rather
than their expanded variants.

This expands the macro variants to inline if they're disabled or not,
and removes building some tests under configurations where they should
fail, instead of building them but disabling them by default.

The change also removes gtest_disable.h as an unused include from many
other files.

BUG=webrtc:5387, webrtc:5400
R=kjellander@webrtc.org, phoglund@webrtc.org
TBR=henrik.lundin@webrtc.org

Review URL: https://codereview.webrtc.org/1547343002 .

Cr-Commit-Position: refs/heads/master@{#11150}
2016-01-04 21:44:16 +00:00

527 lines
16 KiB
C++

/*
* 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 <signal.h>
#include <stdarg.h>
#include "webrtc/base/gunit.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/physicalsocketserver.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/socket_unittest.h"
#include "webrtc/base/testutils.h"
#include "webrtc/base/thread.h"
namespace rtc {
class PhysicalSocketTest;
class FakeSocketDispatcher : public SocketDispatcher {
public:
explicit FakeSocketDispatcher(PhysicalSocketServer* ss)
: SocketDispatcher(ss) {
}
protected:
SOCKET DoAccept(SOCKET socket, sockaddr* 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)) {
return dispatcher;
} else {
delete dispatcher;
return nullptr;
}
}
AsyncSocket* CreateAsyncSocket(int family, int type) override {
SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
if (dispatcher->Create(family, type)) {
return dispatcher;
} else {
delete dispatcher;
return nullptr;
}
}
PhysicalSocketTest* GetTest() const { return test_; }
private:
PhysicalSocketTest* test_;
};
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_; }
protected:
PhysicalSocketTest()
: server_(new FakePhysicalSocketServer(this)),
scope_(server_.get()),
fail_accept_(false) {
}
void ConnectInternalAcceptError(const IPAddress& loopback);
rtc::scoped_ptr<FakePhysicalSocketServer> server_;
SocketServerScope scope_;
bool fail_accept_;
};
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);
}
TEST_F(PhysicalSocketTest, TestConnectIPv4) {
SocketTest::TestConnectIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectIPv6 DISABLED_TestConnectIPv6
#else
#define MAYBE_TestConnectIPv6 TestConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectIPv6) {
SocketTest::TestConnectIPv6();
}
TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
SocketTest::TestConnectWithDnsLookupIPv4();
}
TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
SocketTest::TestConnectWithDnsLookupIPv6();
}
TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
SocketTest::TestConnectFailIPv4();
}
void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) {
testing::StreamSink sink;
SocketAddress accept_addr;
// Create two clients.
scoped_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());
scoped_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.
scoped_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(), 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(), testing::SSE_OPEN));
EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_CLOSE));
// Server has pending connection, try to accept it (will fail).
EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
// Simulate "::accept" returning an error.
SetFailAccept(true);
scoped_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(), 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(), testing::SSE_OPEN));
EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_CLOSE));
// Server has pending connection, try to accept it (will succeed).
EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
SetFailAccept(false);
scoped_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) {
ConnectInternalAcceptError(kIPv4Loopback);
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectAcceptErrorIPv6 DISABLED_TestConnectAcceptErrorIPv6
#else
#define MAYBE_TestConnectAcceptErrorIPv6 TestConnectAcceptErrorIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectAcceptErrorIPv6) {
ConnectInternalAcceptError(kIPv6Loopback);
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectFailIPv6 DISABLED_TestConnectFailIPv6
#else
#define MAYBE_TestConnectFailIPv6 TestConnectFailIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectFailIPv6) {
SocketTest::TestConnectFailIPv6();
}
TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
SocketTest::TestConnectWithDnsLookupFailIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
DISABLED_TestConnectWithDnsLookupFailIPv6
#else
#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
TestConnectWithDnsLookupFailIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithDnsLookupFailIPv6) {
SocketTest::TestConnectWithDnsLookupFailIPv6();
}
TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
SocketTest::TestConnectWithClosedSocketIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWithClosedSocketIPv6 \
DISABLED_TestConnectWithClosedSocketIPv6
#else
#define MAYBE_TestConnectWithClosedSocketIPv6 TestConnectWithClosedSocketIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithClosedSocketIPv6) {
SocketTest::TestConnectWithClosedSocketIPv6();
}
TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
SocketTest::TestConnectWhileNotClosedIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWhileNotClosedIPv6 \
DISABLED_TestConnectWhileNotClosedIPv6
#else
#define MAYBE_TestConnectWhileNotClosedIPv6 TestConnectWhileNotClosedIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWhileNotClosedIPv6) {
SocketTest::TestConnectWhileNotClosedIPv6();
}
TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
SocketTest::TestServerCloseDuringConnectIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestServerCloseDuringConnectIPv6 \
DISABLED_TestServerCloseDuringConnectIPv6
#else
#define MAYBE_TestServerCloseDuringConnectIPv6 TestServerCloseDuringConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseDuringConnectIPv6) {
SocketTest::TestServerCloseDuringConnectIPv6();
}
TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
SocketTest::TestClientCloseDuringConnectIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestClientCloseDuringConnectIPv6 \
DISABLED_TestClientCloseDuringConnectIPv6
#else
#define MAYBE_TestClientCloseDuringConnectIPv6 TestClientCloseDuringConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestClientCloseDuringConnectIPv6) {
SocketTest::TestClientCloseDuringConnectIPv6();
}
TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
SocketTest::TestServerCloseIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestServerCloseIPv6 DISABLED_TestServerCloseIPv6
#else
#define MAYBE_TestServerCloseIPv6 TestServerCloseIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseIPv6) {
SocketTest::TestServerCloseIPv6();
}
TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
SocketTest::TestCloseInClosedCallbackIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestCloseInClosedCallbackIPv6 \
DISABLED_TestCloseInClosedCallbackIPv6
#else
#define MAYBE_TestCloseInClosedCallbackIPv6 TestCloseInClosedCallbackIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestCloseInClosedCallbackIPv6) {
SocketTest::TestCloseInClosedCallbackIPv6();
}
TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
SocketTest::TestSocketServerWaitIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestSocketServerWaitIPv6 DISABLED_TestSocketServerWaitIPv6
#else
#define MAYBE_TestSocketServerWaitIPv6 TestSocketServerWaitIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestSocketServerWaitIPv6) {
SocketTest::TestSocketServerWaitIPv6();
}
TEST_F(PhysicalSocketTest, TestTcpIPv4) {
SocketTest::TestTcpIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestTcpIPv6 DISABLED_TestTcpIPv6
#else
#define MAYBE_TestTcpIPv6 TestTcpIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestTcpIPv6) {
SocketTest::TestTcpIPv6();
}
TEST_F(PhysicalSocketTest, TestUdpIPv4) {
SocketTest::TestUdpIPv4();
}
// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestUdpIPv6 DISABLED_TestUdpIPv6
#else
#define MAYBE_TestUdpIPv6 TestUdpIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_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) {
SocketTest::TestUdpReadyToSendIPv4();
}
TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
SocketTest::TestUdpReadyToSendIPv6();
}
TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
SocketTest::TestGetSetOptionsIPv4();
}
TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
SocketTest::TestGetSetOptionsIPv6();
}
#if defined(WEBRTC_POSIX)
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(NULL);
signals_received_.clear();
signaled_thread_ = NULL;
}
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_;
scoped_ptr<PhysicalSocketServer> ss_;
};
std::vector<int> PosixSignalDeliveryTest::signals_received_;
Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
// 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, NULL);
// 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, NULL));
// 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.
scoped_ptr<Thread> thread(new Thread());
scoped_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