Use the GTest portability headers
[folly.git] / folly / futures / test / TimekeeperTest.cpp
index 0fdac19a638eb326f7d556990e574fb4971d955e..676d635124b73920fb16d9693b7e1b07e5a72d3b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <gtest/gtest.h>
 
 #include <folly/futures/Timekeeper.h>
-#include <unistd.h>
+#include <folly/portability/GTest.h>
+#include <folly/portability/Unistd.h>
 
 using namespace folly;
-using namespace std::chrono;
-using folly::Timekeeper;
-using Duration = folly::Duration;
+using std::chrono::milliseconds;
 
+std::chrono::milliseconds const zero_ms(0);
 std::chrono::milliseconds const one_ms(1);
 std::chrono::milliseconds const awhile(10);
 std::chrono::seconds const too_long(10);
@@ -36,12 +35,10 @@ struct TimekeeperFixture : public testing::Test {
     timeLord_(folly::detail::getTimekeeperSingleton())
   {}
 
-  Timekeeper* timeLord_;
+  std::shared_ptr<Timekeeper> timeLord_;
 };
 
 TEST_F(TimekeeperFixture, after) {
-  Duration waited(0);
-
   auto t1 = now();
   auto f = timeLord_->after(awhile);
   EXPECT_FALSE(f.isReady());
@@ -53,8 +50,9 @@ TEST_F(TimekeeperFixture, after) {
 
 TEST(Timekeeper, futureGet) {
   Promise<int> p;
-  std::thread([&]{ p.setValue(42); }).detach();
+  auto t = std::thread([&]{ p.setValue(42); });
   EXPECT_EQ(42, p.getFuture().get());
+  t.join();
 }
 
 TEST(Timekeeper, futureGetBeforeTimeout) {
@@ -66,13 +64,13 @@ TEST(Timekeeper, futureGetBeforeTimeout) {
   // runs it by hand they're not sitting there forever wondering why it's
   // blocked, and get a useful error message instead. If it does get flaky,
   // empirically increase the timeout to the point where it's very improbable.
-  EXPECT_EQ(42, p.getFuture().get(seconds(2)));
+  EXPECT_EQ(42, p.getFuture().get(std::chrono::seconds(2)));
   t.join();
 }
 
 TEST(Timekeeper, futureGetTimeout) {
   Promise<int> p;
-  EXPECT_THROW(p.getFuture().get(Duration(1)), folly::TimedOut);
+  EXPECT_THROW(p.getFuture().get(one_ms), folly::TimedOut);
 }
 
 TEST(Timekeeper, futureSleep) {
@@ -123,7 +121,7 @@ TEST(Timekeeper, futureWithinVoidSpecialization) {
 }
 
 TEST(Timekeeper, futureWithinException) {
-  Promise<void> p;
+  Promise<Unit> p;
   auto f = p.getFuture().within(awhile, std::runtime_error("expected"));
   EXPECT_THROW(f.get(), std::runtime_error);
 }
@@ -131,7 +129,7 @@ TEST(Timekeeper, futureWithinException) {
 TEST(Timekeeper, onTimeout) {
   bool flag = false;
   makeFuture(42).delayed(one_ms)
-    .onTimeout(Duration(0), [&]{ flag = true; return -1; })
+    .onTimeout(zero_ms, [&]{ flag = true; return -1; })
     .get();
   EXPECT_TRUE(flag);
 }
@@ -139,18 +137,18 @@ TEST(Timekeeper, onTimeout) {
 TEST(Timekeeper, onTimeoutReturnsFuture) {
   bool flag = false;
   makeFuture(42).delayed(one_ms)
-    .onTimeout(Duration(0), [&]{ flag = true; return makeFuture(-1); })
+    .onTimeout(zero_ms, [&]{ flag = true; return makeFuture(-1); })
     .get();
   EXPECT_TRUE(flag);
 }
 
 TEST(Timekeeper, onTimeoutVoid) {
   makeFuture().delayed(one_ms)
-    .onTimeout(Duration(0), [&]{
+    .onTimeout(zero_ms, [&]{
      });
   makeFuture().delayed(one_ms)
-    .onTimeout(Duration(0), [&]{
-       return makeFuture<void>(std::runtime_error("expected"));
+    .onTimeout(zero_ms, [&]{
+       return makeFuture<Unit>(std::runtime_error("expected"));
      });
   // just testing compilation here
 }
@@ -160,15 +158,54 @@ TEST(Timekeeper, interruptDoesntCrash) {
   f.cancel();
 }
 
+TEST(Timekeeper, chainedInterruptTest) {
+  bool test = false;
+  auto f = futures::sleep(milliseconds(100)).then([&](){
+    test = true;
+  });
+  f.cancel();
+  f.wait();
+  EXPECT_FALSE(test);
+}
+
+TEST(Timekeeper, executor) {
+  class ExecutorTester : public Executor {
+   public:
+    void add(Func f) override {
+      count++;
+      f();
+    }
+    std::atomic<int> count{0};
+  };
+
+  auto f = makeFuture();
+  ExecutorTester tester;
+  f.via(&tester).within(one_ms).then([&](){}).wait();
+  EXPECT_EQ(2, tester.count);
+}
+
 // TODO(5921764)
 /*
 TEST(Timekeeper, onTimeoutPropagates) {
   bool flag = false;
   EXPECT_THROW(
     makeFuture(42).delayed(one_ms)
-      .onTimeout(Duration(0), [&]{ flag = true; })
+      .onTimeout(zero_ms, [&]{ flag = true; })
       .get(),
     TimedOut);
   EXPECT_TRUE(flag);
 }
 */
+
+TEST_F(TimekeeperFixture, atBeforeNow) {
+  auto f = timeLord_->at(now() - too_long);
+  EXPECT_TRUE(f.isReady());
+  EXPECT_FALSE(f.hasException());
+}
+
+TEST_F(TimekeeperFixture, howToCastDuration) {
+  // I'm not sure whether this rounds up or down but it's irrelevant for the
+  // purpose of this example.
+  auto f = timeLord_->after(std::chrono::duration_cast<Duration>(
+      std::chrono::nanoseconds(1)));
+}