move wangle/futures to futures
[folly.git] / folly / futures / test / ExecutorTest.cpp
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <gtest/gtest.h>
18 #include <folly/futures/InlineExecutor.h>
19 #include <folly/futures/ManualExecutor.h>
20 #include <folly/futures/QueuedImmediateExecutor.h>
21 #include <folly/futures/Future.h>
22 #include <folly/Baton.h>
23
24 using namespace folly::wangle;
25 using namespace std::chrono;
26 using namespace testing;
27
28 TEST(ManualExecutor, runIsStable) {
29   ManualExecutor x;
30   size_t count = 0;
31   auto f1 = [&]() { count++; };
32   auto f2 = [&]() { x.add(f1); x.add(f1); };
33   x.add(f2);
34   x.run();
35 }
36
37 TEST(ManualExecutor, scheduleDur) {
38   ManualExecutor x;
39   size_t count = 0;
40   milliseconds dur {10};
41   x.schedule([&]{ count++; }, dur);
42   EXPECT_EQ(count, 0);
43   x.run();
44   EXPECT_EQ(count, 0);
45   x.advance(dur/2);
46   EXPECT_EQ(count, 0);
47   x.advance(dur/2);
48   EXPECT_EQ(count, 1);
49 }
50
51 TEST(ManualExecutor, clockStartsAt0) {
52   ManualExecutor x;
53   EXPECT_EQ(x.now(), x.now().min());
54 }
55
56 TEST(ManualExecutor, scheduleAbs) {
57   ManualExecutor x;
58   size_t count = 0;
59   x.scheduleAt([&]{ count++; }, x.now() + milliseconds(10));
60   EXPECT_EQ(count, 0);
61   x.advance(milliseconds(10));
62   EXPECT_EQ(count, 1);
63 }
64
65 TEST(ManualExecutor, advanceTo) {
66   ManualExecutor x;
67   size_t count = 0;
68   x.scheduleAt([&]{ count++; }, steady_clock::now());
69   EXPECT_EQ(count, 0);
70   x.advanceTo(steady_clock::now());
71   EXPECT_EQ(count, 1);
72 }
73
74 TEST(ManualExecutor, advanceBack) {
75   ManualExecutor x;
76   size_t count = 0;
77   x.advance(microseconds(5));
78   x.schedule([&]{ count++; }, microseconds(6));
79   EXPECT_EQ(count, 0);
80   x.advanceTo(x.now() - microseconds(1));
81   EXPECT_EQ(count, 0);
82 }
83
84 TEST(ManualExecutor, advanceNeg) {
85   ManualExecutor x;
86   size_t count = 0;
87   x.advance(microseconds(5));
88   x.schedule([&]{ count++; }, microseconds(6));
89   EXPECT_EQ(count, 0);
90   x.advance(microseconds(-1));
91   EXPECT_EQ(count, 0);
92 }
93
94 TEST(ManualExecutor, waitForDoesNotDeadlock) {
95   ManualExecutor east, west;
96   folly::Baton<> baton;
97   auto f = makeFuture()
98     .via(&east)
99     .then([](Try<void>){ return makeFuture(); })
100     .via(&west);
101   std::thread t([&]{
102     baton.post();
103     west.waitFor(f);
104   });
105   baton.wait();
106   east.run();
107   t.join();
108 }
109
110 TEST(Executor, InlineExecutor) {
111   InlineExecutor x;
112   size_t counter = 0;
113   x.add([&]{
114     x.add([&]{
115       EXPECT_EQ(counter++, 0);
116     });
117     EXPECT_EQ(counter++, 1);
118   });
119   EXPECT_EQ(counter, 2);
120 }
121
122 TEST(Executor, QueuedImmediateExecutor) {
123   QueuedImmediateExecutor x;
124   size_t counter = 0;
125   x.add([&]{
126     x.add([&]{
127       EXPECT_EQ(1, counter++);
128     });
129     EXPECT_EQ(0, counter++);
130   });
131   EXPECT_EQ(2, counter);
132 }
133
134 TEST(Executor, Runnable) {
135   InlineExecutor x;
136   size_t counter = 0;
137   struct Runnable {
138     std::function<void()> fn;
139     void operator()() { fn(); }
140   };
141   Runnable f;
142   f.fn = [&]{ counter++; };
143   x.add(f);
144   EXPECT_EQ(counter, 1);
145 }
146
147 TEST(Executor, RunnablePtr) {
148   InlineExecutor x;
149   struct Runnable {
150     std::function<void()> fn;
151     void operator()() { fn(); }
152   };
153   size_t counter = 0;
154   auto fnp = std::make_shared<Runnable>();
155   fnp->fn = [&]{ counter++; };
156   x.addPtr(fnp);
157   EXPECT_EQ(counter, 1);
158 }