Fix copyright lines
[folly.git] / folly / futures / test / CollectTest.cpp
index 2b7ca5bba635453c318b6e3e8d11ec0c59cce8f6..dbe94dbb11816f975e1b63827208715ae5a0cbce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2015-present Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
+#include <numeric>
 
 #include <boost/thread/barrier.hpp>
 
-#include <folly/futures/Future.h>
 #include <folly/Random.h>
+#include <folly/futures/Future.h>
+#include <folly/portability/GTest.h>
 #include <folly/small_vector.h>
 
 using namespace folly;
@@ -35,8 +36,9 @@ TEST(Collect, collectAll) {
     std::vector<Promise<int>> promises(10);
     std::vector<Future<int>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     auto allf = collectAll(futures);
 
@@ -58,8 +60,9 @@ TEST(Collect, collectAll) {
     std::vector<Promise<int>> promises(4);
     std::vector<Future<int>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     auto allf = collectAll(futures);
 
@@ -90,18 +93,20 @@ TEST(Collect, collectAll) {
     std::vector<Promise<Unit>> promises(10);
     std::vector<Future<Unit>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
-    auto allf = collectAll(futures)
-      .then([](Try<std::vector<Try<Unit>>>&& ts) {
-        for (auto& f : ts.value())
-          f.value();
-      });
+    auto allf = collectAll(futures).then([](Try<std::vector<Try<Unit>>>&& ts) {
+      for (auto& f : ts.value()) {
+        f.value();
+      }
+    });
 
     std::shuffle(promises.begin(), promises.end(), rng);
-    for (auto& p : promises)
+    for (auto& p : promises) {
       p.setValue();
+    }
     EXPECT_TRUE(allf.isReady());
   }
 }
@@ -112,8 +117,9 @@ TEST(Collect, collect) {
     std::vector<Promise<int>> promises(10);
     std::vector<Future<int>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     auto allf = collect(futures);
 
@@ -134,8 +140,9 @@ TEST(Collect, collect) {
     std::vector<Promise<int>> promises(10);
     std::vector<Future<int>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     auto allf = collect(futures);
 
@@ -169,8 +176,9 @@ TEST(Collect, collect) {
     std::vector<Promise<Unit>> promises(10);
     std::vector<Future<Unit>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     auto allf = collect(futures);
 
@@ -188,8 +196,9 @@ TEST(Collect, collect) {
     std::vector<Promise<Unit>> promises(10);
     std::vector<Future<Unit>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     auto allf = collect(futures);
 
@@ -223,8 +232,9 @@ TEST(Collect, collect) {
     std::vector<Promise<std::unique_ptr<int>>> promises(10);
     std::vector<Future<std::unique_ptr<int>>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     collect(futures);
   }
@@ -246,8 +256,9 @@ TEST(Collect, collectNotDefaultConstructible) {
   std::iota(indices.begin(), indices.end(), 0);
   std::shuffle(indices.begin(), indices.end(), rng);
 
-  for (auto& p : promises)
+  for (auto& p : promises) {
     futures.push_back(p.getFuture());
+  }
 
   auto allf = collect(futures);
 
@@ -269,8 +280,9 @@ TEST(Collect, collectAny) {
     std::vector<Promise<int>> promises(10);
     std::vector<Future<int>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     for (auto& f : futures) {
       EXPECT_FALSE(f.isReady());
@@ -297,8 +309,9 @@ TEST(Collect, collectAny) {
     std::vector<Promise<Unit>> promises(10);
     std::vector<Future<Unit>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     for (auto& f : futures) {
       EXPECT_FALSE(f.isReady());
@@ -318,8 +331,9 @@ TEST(Collect, collectAny) {
     std::vector<Promise<int>> promises(10);
     std::vector<Future<int>> futures;
 
-    for (auto& p : promises)
+    for (auto& p : promises) {
       futures.push_back(p.getFuture());
+    }
 
     auto anyf = collectAny(futures)
       .then([](std::pair<size_t, Try<int>> p) {
@@ -331,12 +345,80 @@ TEST(Collect, collectAny) {
   }
 }
 
+TEST(Collect, collectAnyWithoutException) {
+  {
+    std::vector<Promise<int>> promises(10);
+    std::vector<Future<int>> futures;
+
+    for (auto& p : promises) {
+      futures.push_back(p.getFuture());
+    }
+
+    auto onef = collectAnyWithoutException(futures);
+
+    /* futures were moved in, so these are invalid now */
+    EXPECT_FALSE(onef.isReady());
+
+    promises[7].setValue(42);
+    EXPECT_TRUE(onef.isReady());
+    auto& idx_fut = onef.value();
+    EXPECT_EQ(7, idx_fut.first);
+    EXPECT_EQ(42, idx_fut.second);
+  }
+
+  // some exception before ready
+  {
+    std::vector<Promise<int>> promises(10);
+    std::vector<Future<int>> futures;
+
+    for (auto& p : promises) {
+      futures.push_back(p.getFuture());
+    }
+
+    auto onef = collectAnyWithoutException(futures);
+
+    EXPECT_FALSE(onef.isReady());
+
+    promises[3].setException(eggs);
+    EXPECT_FALSE(onef.isReady());
+    promises[4].setException(eggs);
+    EXPECT_FALSE(onef.isReady());
+    promises[0].setValue(99);
+    EXPECT_TRUE(onef.isReady());
+    auto& idx_fut = onef.value();
+    EXPECT_EQ(0, idx_fut.first);
+    EXPECT_EQ(99, idx_fut.second);
+  }
+
+  // all exceptions
+  {
+    std::vector<Promise<int>> promises(10);
+    std::vector<Future<int>> futures;
+
+    for (auto& p : promises) {
+      futures.push_back(p.getFuture());
+    }
+
+    auto onef = collectAnyWithoutException(futures);
+
+    EXPECT_FALSE(onef.isReady());
+    for (int i = 0; i < 9; ++i) {
+      promises[i].setException(eggs);
+    }
+    EXPECT_FALSE(onef.isReady());
+
+    promises[9].setException(eggs);
+    EXPECT_TRUE(onef.isReady());
+    EXPECT_TRUE(onef.hasException());
+  }
+}
 
 TEST(Collect, alreadyCompleted) {
   {
     std::vector<Future<Unit>> fs;
-    for (int i = 0; i < 10; i++)
+    for (int i = 0; i < 10; i++) {
       fs.push_back(makeFuture());
+    }
 
     collectAll(fs)
       .then([&](std::vector<Try<Unit>> ts) {
@@ -345,8 +427,9 @@ TEST(Collect, alreadyCompleted) {
   }
   {
     std::vector<Future<int>> fs;
-    for (int i = 0; i < 10; i++)
+    for (int i = 0; i < 10; i++) {
       fs.push_back(makeFuture(i));
+    }
 
     collectAny(fs)
       .then([&](std::pair<size_t, Try<int>> p) {
@@ -487,8 +570,9 @@ TEST(Collect, collectN) {
   std::vector<Promise<Unit>> promises(10);
   std::vector<Future<Unit>> futures;
 
-  for (auto& p : promises)
+  for (auto& p : promises) {
     futures.push_back(p.getFuture());
+  }
 
   bool flag = false;
   size_t n = 3;
@@ -496,8 +580,9 @@ TEST(Collect, collectN) {
     .then([&](std::vector<std::pair<size_t, Try<Unit>>> v) {
       flag = true;
       EXPECT_EQ(n, v.size());
-      for (auto& tt : v)
+      for (auto& tt : v) {
         EXPECT_TRUE(tt.second.hasValue());
+      }
     });
 
   promises[0].setValue();
@@ -518,16 +603,18 @@ TEST(Collect, smallVector) {
   {
     folly::small_vector<Future<Unit>> futures;
 
-    for (int i = 0; i < 10; i++)
+    for (int i = 0; i < 10; i++) {
       futures.push_back(makeFuture());
+    }
 
     auto anyf = collectAny(futures);
   }
   {
     folly::small_vector<Future<Unit>> futures;
 
-    for (int i = 0; i < 10; i++)
+    for (int i = 0; i < 10; i++) {
       futures.push_back(makeFuture());
+    }
 
     auto allf = collectAll(futures);
   }