From: Haijun Zhu Date: Tue, 20 Jan 2015 18:54:59 +0000 (-0800) Subject: Try to fix IdleTime unit test X-Git-Tag: v0.23.0~38 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e26db8a2221698b9ba7319db9f54bd3a1eef74bb;p=folly.git Try to fix IdleTime unit test Summary: IdleTime unit test has been failing randomly (#5996886). The event base loop calculates an exponentially moving average of loop busy time in each loop. In the test, the busy time is initialized to 5900 and each loop runs more than 8000 us. In normal case decaying of the previous loop busy time will take 6 loops to move this average to >6000. But if the test is running on a heavily loaded machine the busy+idle time a loop is longer than it should be, causing the decaying happen faster. This diff skips this test if this happens. Test Plan: It won't affect anything if running on my devserver. It only helps on a heavily loaded contbuild host. Reviewed By: alandau@fb.com Subscribers: folly-diffs@ FB internal diff: D1788450 Tasks: 5996886 Signature: t1:1788450:1421460774:1ec575c50f881e10b5a0208717fe68164f0d0f57 --- diff --git a/folly/io/async/EventBase.cpp b/folly/io/async/EventBase.cpp index 7bfc2213..e956ca18 100644 --- a/folly/io/async/EventBase.cpp +++ b/folly/io/async/EventBase.cpp @@ -646,6 +646,8 @@ void EventBase::SmoothLoopTime::addSample(int64_t idle, int64_t busy) { LEFT = 2, // busy sample placed at the beginning of the iteration }; + // See http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average + // and D676020 for more info on this calculation. VLOG(11) << "idle " << idle << " oldBusyLeftover_ " << oldBusyLeftover_ << " idle + oldBusyLeftover_ " << idle + oldBusyLeftover_ << " busy " << busy << " " << __PRETTY_FUNCTION__; diff --git a/folly/io/async/test/EventBaseTest.cpp b/folly/io/async/test/EventBaseTest.cpp index c9887169..cacf18fe 100644 --- a/folly/io/async/test/EventBaseTest.cpp +++ b/folly/io/async/test/EventBaseTest.cpp @@ -34,6 +34,8 @@ using std::make_pair; using std::cerr; using std::endl; using std::chrono::milliseconds; +using std::chrono::microseconds; +using std::chrono::duration_cast; using namespace folly; @@ -1456,6 +1458,9 @@ TEST(EventBaseTest, IdleTime) { IdleTimeTimeoutSeries tos0(&eventBase, timeouts0); std::deque timeouts(20, 20); std::unique_ptr tos; + int64_t testStart = duration_cast( + std::chrono::steady_clock::now().time_since_epoch()).count(); + bool hostOverloaded = false; int latencyCallbacks = 0; eventBase.setMaxLatency(6000, [&]() { @@ -1463,6 +1468,15 @@ TEST(EventBaseTest, IdleTime) { switch (latencyCallbacks) { case 1: + if (tos0.getTimeouts() < 6) { + // This could only happen if the host this test is running + // on is heavily loaded. + int64_t maxLatencyReached = duration_cast( + std::chrono::steady_clock::now().time_since_epoch()).count(); + ASSERT_LE(43800, maxLatencyReached - testStart); + hostOverloaded = true; + break; + } ASSERT_EQ(6, tos0.getTimeouts()); ASSERT_GE(6100, eventBase.getAvgLoopTime() - 1200); ASSERT_LE(6100, eventBase.getAvgLoopTime() + 1200); @@ -1480,6 +1494,10 @@ TEST(EventBaseTest, IdleTime) { eventBase.loop(); + if (hostOverloaded) { + return; + } + ASSERT_EQ(1, latencyCallbacks); ASSERT_EQ(7, tos0.getTimeouts()); ASSERT_GE(5900, eventBase.getAvgLoopTime() - 1200);