Codemod folly::make_unique to std::make_unique
[folly.git] / folly / experimental / test / FutureDAGTest.cpp
index 95dad8bae4a8551de4adc6160f0d8fecf37956d9..98329c9035e0cb7ca07afb813e2813690fe79b9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,9 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <folly/experimental/FutureDAG.h>
-#include <gtest/gtest.h>
 #include <boost/thread/barrier.hpp>
+#include <folly/experimental/FutureDAG.h>
+#include <folly/portability/GTest.h>
 
 using namespace folly;
 
@@ -23,14 +23,45 @@ struct FutureDAGTest : public testing::Test {
   typedef FutureDAG::Handle Handle;
 
   Handle add() {
-    auto node = folly::make_unique<TestNode>(this);
+    auto node = std::make_unique<TestNode>(this);
     auto handle = node->handle;
     nodes.emplace(handle, std::move(node));
     return handle;
   }
 
+  void reset() {
+    Handle source_node;
+    std::unordered_set<Handle> memo;
+    for (auto& node : nodes) {
+      for (Handle handle : node.second->dependencies) {
+        memo.insert(handle);
+      }
+    }
+    for (auto& node : nodes) {
+      if (memo.find(node.first) == memo.end()) {
+        source_node = node.first;
+      }
+    }
+    for (auto it = nodes.cbegin(); it != nodes.cend();) {
+      if (it->first != source_node) {
+        it = nodes.erase(it);
+      } else {
+        ++it;
+      }
+    }
+    dag->reset();
+  }
+
+  void remove(Handle a) {
+    for (auto& node : nodes) {
+      node.second->dependencies.erase(a);
+    }
+    nodes.erase(a);
+    dag->remove(a);
+  }
+
   void dependency(Handle a, Handle b) {
-    nodes.at(b)->dependencies.push_back(a);
+    nodes.at(b)->dependencies.insert(a);
     dag->dependency(a, b);
   }
 
@@ -50,31 +81,62 @@ struct FutureDAGTest : public testing::Test {
   }
 
   struct TestNode {
-    explicit TestNode(FutureDAGTest* test) {
-      func = [this, test] {
-        test->order.push_back(handle);
-        return Future<void>();
-      };
-      handle = test->dag->add(func);
-    }
+    explicit TestNode(FutureDAGTest* test)
+        : func([this, test] {
+            test->order.push_back(handle);
+            return Future<Unit>();
+          }),
+          handle(test->dag->add(func)) {}
 
-    FutureDAG::FutureFunc func;
-    Handle handle;
-    std::vector<Handle> dependencies;
+    const FutureDAG::FutureFunc func;
+    const Handle handle;
+    std::set<Handle> dependencies;
   };
 
-  std::shared_ptr<FutureDAG> dag = FutureDAG::create();
+  const std::shared_ptr<FutureDAG> dag = FutureDAG::create();
   std::map<Handle, std::unique_ptr<TestNode>> nodes;
   std::vector<Handle> order;
 };
 
-
 TEST_F(FutureDAGTest, SingleNode) {
   add();
   ASSERT_NO_THROW(dag->go().get());
   checkOrder();
 }
 
+TEST_F(FutureDAGTest, RemoveSingleNode) {
+  auto h1 = add();
+  auto h2 = add();
+  remove(h2);
+  ASSERT_NO_THROW(dag->go().get());
+  checkOrder();
+}
+
+TEST_F(FutureDAGTest, RemoveNodeComplex) {
+  auto h1 = add();
+  auto h2 = add();
+  auto h3 = add();
+  dependency(h1, h3);
+  dependency(h2, h1);
+  remove(h3);
+  remove(h2);
+  remove(h1);
+  ASSERT_NO_THROW(dag->go().get());
+  checkOrder();
+}
+
+TEST_F(FutureDAGTest, ResetDAG) {
+  auto h1 = add();
+  auto h2 = add();
+  auto h3 = add();
+  dependency(h3, h1);
+  dependency(h2, h3);
+
+  reset();
+  ASSERT_NO_THROW(dag->go().get());
+  checkOrder();
+}
+
 TEST_F(FutureDAGTest, FanOut) {
   auto h1 = add();
   auto h2 = add();
@@ -145,12 +207,10 @@ TEST_F(FutureDAGTest, Complex) {
   checkOrder();
 }
 
-FutureDAG::FutureFunc makeFutureFunc = []{
-  return makeFuture();
-};
+FutureDAG::FutureFunc makeFutureFunc = [] { return makeFuture(); };
 
-FutureDAG::FutureFunc throwFunc = []{
-  return makeFuture<void>(std::runtime_error("oops"));
+FutureDAG::FutureFunc throwFunc = [] {
+  return makeFuture<Unit>(std::runtime_error("oops"));
 };
 
 TEST_F(FutureDAGTest, ThrowBegin) {
@@ -193,21 +253,21 @@ TEST_F(FutureDAGTest, Cycle3) {
 
 TEST_F(FutureDAGTest, DestroyBeforeComplete) {
   auto barrier = std::make_shared<boost::barrier>(2);
-  Future<void> f;
+  Future<Unit> f;
   {
-    auto dag = FutureDAG::create();
-    auto h1 = dag->add([barrier] {
-      auto p = std::make_shared<Promise<void>>();
-      std::thread t([p, barrier]{
+    auto localDag = FutureDAG::create();
+    auto h1 = localDag->add([barrier] {
+      auto p = std::make_shared<Promise<Unit>>();
+      std::thread t([p, barrier] {
         barrier->wait();
         p->setValue();
       });
       t.detach();
       return p->getFuture();
     });
-    auto h2 = dag->add(makeFutureFunc);
-    dag->dependency(h1, h2);
-    f = dag->go();
+    auto h2 = localDag->add(makeFutureFunc);
+    localDag->dependency(h1, h2);
+    f = localDag->go();
   }
   barrier->wait();
   ASSERT_NO_THROW(f.get());