Bug 1355746 - Part 3. Test cases for IdleTaskRunner. draft
authorHenry Chang <hchang@mozilla.com>
Wed, 12 Jul 2017 14:13:44 +0800
changeset 642451 1644732b27bb31097b678cab22e50b2d982847db
parent 642450 89a3a01fb3f5d41d712c4b798890ecf06cec3a4c
child 642452 342547edfada26c8dad97b537db2505f55ffd3b0
push id72752
push userhchang@mozilla.com
push dateTue, 08 Aug 2017 08:47:58 +0000
bugs1355746
milestone57.0a1
Bug 1355746 - Part 3. Test cases for IdleTaskRunner. MozReview-Commit-ID: 3RsC1pT9Fzc
xpcom/tests/gtest/TestThreadUtils.cpp
--- a/xpcom/tests/gtest/TestThreadUtils.cpp
+++ b/xpcom/tests/gtest/TestThreadUtils.cpp
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http:mozilla.org/MPL/2.0/. */
 
 #include "nsThreadUtils.h"
+#include "mozilla/IdleTaskRunner.h"
 #include "mozilla/UniquePtr.h"
 
 #include "gtest/gtest.h"
 
 using namespace mozilla;
 
 enum {
   TEST_CALL_VOID_ARG_VOID_RETURN,
@@ -670,16 +671,89 @@ TEST(ThreadUtils, IdleRunnableMethod)
     NS_ProcessPendingEvents(nullptr);
 
     ASSERT_TRUE(idleNoSetDeadline->mRunnableExecuted);
     ASSERT_TRUE(idleInheritedSetDeadline->mRunnableExecuted);
     ASSERT_TRUE(idleInheritedSetDeadline->mSetDeadlineCalled);
   }
 }
 
+TEST(ThreadUtils, IdleTaskRunner)
+{
+  using namespace mozilla;
+
+  // Repeating.
+  int cnt1 = 0;
+  RefPtr<IdleTaskRunner> runner1 =
+    IdleTaskRunner::Create([&cnt1](TimeStamp) { cnt1++; return true; },
+                           10,
+                           3,
+                           true,
+                           nullptr);
+
+  // Non-repeating but callback always return false so it's still repeating.
+  int cnt2 = 0;
+  RefPtr<IdleTaskRunner> runner2 =
+    IdleTaskRunner::Create([&cnt2](TimeStamp) { cnt2++; return false; },
+                           10,
+                           3,
+                           false,
+                           nullptr);
+
+  // Repeating until cnt3 >= 2 by returning 'true' in MayStopProcessing callback.
+  // The strategy is to stop repeating as early as possible so that
+  // we are more probable to catch the bug if it didn't stop as expected.
+  int cnt3 = 0;
+  RefPtr<IdleTaskRunner> runner3 =
+    IdleTaskRunner::Create([&cnt3](TimeStamp) { cnt3++; return true; },
+                           10,
+                           3,
+                           true,
+                           [&cnt3]{ return cnt3 >= 2; });
+
+  // Non-repeating can callback return true so the callback will
+  // be only run once.
+  int cnt4 = 0;
+  RefPtr<IdleTaskRunner> runner4 =
+    IdleTaskRunner::Create([&cnt4](TimeStamp) { cnt4++; return true; },
+                           10,
+                           3,
+                           false,
+                           nullptr);
+
+  // Firstly we wait until the two repeating tasks reach their limits.
+  MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return cnt1 >= 100; }));
+  MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return cnt2 >= 100; }));
+
+  // At any point ==> 0 <= cnt3 <= 2 since MayStopProcessing() would return
+  // true when cnt3 >= 2.
+  MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() {
+    if (cnt3 > 2) {
+      EXPECT_TRUE(false) << "MaybeContinueProcess() doesn't work.";
+      return true; // Stop on failure.
+    }
+    return cnt3 == 2; // Stop finish if we have reached its max value.
+  }));
+
+  // At any point ==> 0 <= cnt4 <= 1 since this is a non-repeating
+  // idle runner.
+  MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() {
+    // At any point: 0 <= cnt4 <= 1
+    if (cnt4 > 1) {
+      EXPECT_TRUE(false) << "The 'mRepeating' flag doesn't work.";
+      return true; // Stop on failure.
+    }
+    return cnt4 == 1;
+  }));
+
+  // The repeating timer with no "exit" condition requires an explicit
+  // Cancel() call.
+  runner1->Cancel();
+}
+
 // {9e70a320-be02-11d1-8031-006008159b5a}
 #define NS_IFOO_IID \
   {0x9e70a320, 0xbe02, 0x11d1,    \
     {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
 
 TEST(ThreadUtils, TypeTraits)
 {
   static_assert(!mozilla::IsRefcountedSmartPointer<int>::value,