Using fake clock for TURN port tests and un-disabling some tests.

The fake clock has a few advantages:
1. It lets use verify that operations take the expected number of
   round trips.
2. It makes the tests faster by letting us remove the equivalent
   of "Sleep(500)" all over the tests.
3. It makes the tests less flaky, because sometimes sleeping for
   500ms or waiting for 1s is not enough.

R=honghaiz@webrtc.org, pthatcher@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#13304}
This commit is contained in:
Taylor Brandstetter 2016-06-27 14:07:41 -07:00
parent 1caff88945
commit 716d07a241
4 changed files with 299 additions and 221 deletions

View File

@ -21,25 +21,25 @@
#endif
// Wait until "ex" is true, or "timeout" expires.
#define WAIT(ex, timeout) \
for (int64_t start = rtc::SystemTimeMillis(); \
!(ex) && rtc::SystemTimeMillis() < start + timeout;) { \
rtc::Thread::Current()->ProcessMessages(0); \
rtc::Thread::Current()->SleepMs(1); \
#define WAIT(ex, timeout) \
for (int64_t start = rtc::SystemTimeMillis(); \
!(ex) && rtc::SystemTimeMillis() < start + (timeout);) { \
rtc::Thread::Current()->ProcessMessages(0); \
rtc::Thread::Current()->SleepMs(1); \
}
// This returns the result of the test in res, so that we don't re-evaluate
// the expression in the XXXX_WAIT macros below, since that causes problems
// when the expression is only true the first time you check it.
#define WAIT_(ex, timeout, res) \
do { \
int64_t start = rtc::SystemTimeMillis(); \
res = (ex); \
while (!res && rtc::SystemTimeMillis() < start + timeout) { \
rtc::Thread::Current()->ProcessMessages(0); \
rtc::Thread::Current()->SleepMs(1); \
res = (ex); \
} \
#define WAIT_(ex, timeout, res) \
do { \
int64_t start = rtc::SystemTimeMillis(); \
res = (ex); \
while (!res && rtc::SystemTimeMillis() < start + (timeout)) { \
rtc::Thread::Current()->ProcessMessages(0); \
rtc::Thread::Current()->SleepMs(1); \
res = (ex); \
} \
} while (0)
// The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout.
@ -74,26 +74,27 @@
// Version with a "soft" timeout and a margin. This logs if the timeout is
// exceeded, but it only fails if the expression still isn't true after the
// margin time passes.
#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \
do { \
bool res; \
WAIT_(ex, timeout, res); \
if (res) { \
break; \
} \
LOG(LS_WARNING) << "Expression " << #ex << " still not true after " << \
timeout << "ms; waiting an additional " << margin << "ms"; \
WAIT_(ex, margin, res); \
if (!res) { \
EXPECT_TRUE(ex); \
} \
#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \
do { \
bool res; \
WAIT_(ex, timeout, res); \
if (res) { \
break; \
} \
LOG(LS_WARNING) << "Expression " << #ex << " still not true after " \
<< (timeout) << "ms; waiting an additional " << margin \
<< "ms"; \
WAIT_(ex, margin, res); \
if (!res) { \
EXPECT_TRUE(ex); \
} \
} while (0)
// Wait until "ex" is true, or "timeout" expires, using fake clock where
// messages are processed every millisecond.
#define SIMULATED_WAIT(ex, timeout, clock) \
for (int64_t start = rtc::TimeMillis(); \
!(ex) && rtc::TimeMillis() < start + timeout;) { \
!(ex) && rtc::TimeMillis() < start + (timeout);) { \
clock.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); \
}
@ -104,7 +105,7 @@
do { \
int64_t start = rtc::TimeMillis(); \
res = (ex); \
while (!res && rtc::TimeMillis() < start + timeout) { \
while (!res && rtc::TimeMillis() < start + (timeout)) { \
clock.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); \
res = (ex); \
} \
@ -129,4 +130,20 @@
} \
} while (0)
#define ASSERT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
do { \
bool res; \
SIMULATED_WAIT_(ex, timeout, res, clock); \
if (!res) \
ASSERT_TRUE(ex); \
} while (0)
#define ASSERT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
do { \
bool res; \
SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
if (!res) \
ASSERT_EQ(v1, v2); \
} while (0)
#endif // WEBRTC_BASE_GUNIT_H_

View File

@ -771,8 +771,11 @@ int VirtualSocketServer::Connect(VirtualSocket* socket,
bool VirtualSocketServer::Disconnect(VirtualSocket* socket) {
if (socket) {
// If we simulate packets being delayed, we should simulate the
// equivalent of a FIN being delayed as well.
uint32_t delay = GetRandomTransitDelay();
// Remove the mapping.
msg_queue_->Post(RTC_FROM_HERE, socket, MSG_ID_DISCONNECT);
msg_queue_->PostDelayed(RTC_FROM_HERE, delay, socket, MSG_ID_DISCONNECT);
return true;
}
return false;

File diff suppressed because it is too large Load Diff

View File

@ -509,10 +509,11 @@ void TurnServer::OnAllocationDestroyed(TurnServerAllocation* allocation) {
// Removing the internal socket if the connection is not udp.
rtc::AsyncPacketSocket* socket = allocation->conn()->socket();
InternalSocketMap::iterator iter = server_sockets_.find(socket);
ASSERT(iter != server_sockets_.end());
// Skip if the socket serving this allocation is UDP, as this will be shared
// by all allocations.
if (iter->second != cricket::PROTO_UDP) {
// Note: We may not find a socket if it's a TCP socket that was closed, and
// the allocation is only now timing out.
if (iter != server_sockets_.end() && iter->second != cricket::PROTO_UDP) {
DestroyInternalSocket(socket);
}