Move retrying method to separate header in folly/futures
[folly.git] / folly / futures / test / RetryingTest.cpp
index 2de5c8a441a4a6884181eb4699ca60717381b24a..c99f3fceb15ab0ac9c12fdc1b6cc130c2bf5cfc6 100644 (file)
@@ -18,7 +18,7 @@
 #include <atomic>
 #include <vector>
 
-#include <folly/futures/Future.h>
+#include <folly/futures/Retrying.h>
 #include <folly/portability/GTest.h>
 #include <folly/portability/SysResource.h>
 #include "TestExecutor.h"
@@ -75,6 +75,27 @@ TEST(RetryingTest, basic) {
   EXPECT_EQ(2, r.value());
 }
 
+TEST(RetryingTest, future_factory_throws) {
+  struct ReturnedException : exception {};
+  struct ThrownException : exception {};
+  auto result = futures::retrying(
+                    [](size_t n, const exception_wrapper&) { return n < 2; },
+                    [](size_t n) {
+                      switch (n) {
+                        case 0:
+                          return makeFuture<size_t>(
+                              make_exception_wrapper<ReturnedException>());
+                        case 1:
+                          throw ThrownException();
+                        default:
+                          return makeFuture(n);
+                      }
+                    })
+                    .wait()
+                    .getTry();
+  EXPECT_THROW(result.throwIfFailed(), ThrownException);
+}
+
 TEST(RetryingTest, policy_future) {
   atomic<size_t> sleeps {0};
   auto r = futures::retrying(
@@ -144,14 +165,17 @@ TEST(RetryingTest, large_retries) {
   PCHECK(getrlimit(RLIMIT_AS, &oldMemLimit) == 0);
 
   rlimit newMemLimit;
-  newMemLimit.rlim_cur = std::min(1UL << 30, oldMemLimit.rlim_max);
+  newMemLimit.rlim_cur =
+      std::min(static_cast<rlim_t>(1UL << 30), oldMemLimit.rlim_max);
   newMemLimit.rlim_max = oldMemLimit.rlim_max;
-  PCHECK(setrlimit(RLIMIT_AS, &newMemLimit) == 0);
+  if (!folly::kIsSanitizeAddress) { // ASAN reserves outside of the rlimit
+    PCHECK(setrlimit(RLIMIT_AS, &newMemLimit) == 0);
+  }
   SCOPE_EXIT {
     PCHECK(setrlimit(RLIMIT_AS, &oldMemLimit) == 0);
   };
 
-  TestExecutor executor;
+  TestExecutor executor(4);
   // size of implicit promise is at least the size of the return.
   using LargeReturn = array<uint64_t, 16000>;
   auto func = [&executor](size_t retryNum) -> Future<LargeReturn> {
@@ -172,6 +196,8 @@ TEST(RetryingTest, large_retries) {
         func));
   }
 
+  // 40 * 10,000 * 16,000B > 1GB; we should avoid OOM
+
   for (auto& f : futures) {
     f.wait();
     EXPECT_TRUE(f.hasValue());