futures::retrying.
[folly.git] / folly / test / SingletonTest.cpp
1 /*
2  * Copyright 2015 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 <thread>
18
19 #include <folly/Singleton.h>
20
21 #include <folly/Benchmark.h>
22
23 #include <glog/logging.h>
24 #include <gtest/gtest.h>
25
26 using namespace folly;
27
28 // A simple class that tracks how often instances of the class and
29 // subclasses are created, and the ordering.  Also tracks a global
30 // unique counter for each object.
31 std::atomic<size_t> global_counter(19770326);
32 struct Watchdog {
33   static std::vector<Watchdog*> creation_order;
34   Watchdog() : serial_number(++global_counter) {
35     creation_order.push_back(this);
36   }
37
38   ~Watchdog() {
39     if (creation_order.back() != this) {
40       throw std::out_of_range("Watchdog destruction order mismatch");
41     }
42     creation_order.pop_back();
43   }
44
45   const size_t serial_number;
46   size_t livingWatchdogCount() const { return creation_order.size(); }
47
48   Watchdog(const Watchdog&) = delete;
49   Watchdog& operator=(const Watchdog&) = delete;
50   Watchdog(Watchdog&&) noexcept = default;
51 };
52
53 std::vector<Watchdog*> Watchdog::creation_order;
54
55 // Some basic types we use for tracking.
56 struct ChildWatchdog : public Watchdog {};
57 struct GlobalWatchdog : public Watchdog {};
58 struct UnregisteredWatchdog : public Watchdog {};
59
60 namespace {
61 Singleton<GlobalWatchdog> global_watchdog;
62 }
63
64 // Test basic global usage (the default way singletons will generally
65 // be used).
66 TEST(Singleton, BasicGlobalUsage) {
67   EXPECT_EQ(Watchdog::creation_order.size(), 0);
68   EXPECT_EQ(SingletonVault::singleton()->registeredSingletonCount(), 1);
69   EXPECT_EQ(SingletonVault::singleton()->livingSingletonCount(), 0);
70   auto wd1 = Singleton<GlobalWatchdog>::get();
71   EXPECT_NE(wd1, nullptr);
72   EXPECT_EQ(Watchdog::creation_order.size(), 1);
73   auto wd2 = Singleton<GlobalWatchdog>::get();
74   EXPECT_NE(wd2, nullptr);
75   EXPECT_EQ(wd1, wd2);
76   EXPECT_EQ(Watchdog::creation_order.size(), 1);
77   SingletonVault::singleton()->destroyInstances();
78   EXPECT_EQ(Watchdog::creation_order.size(), 0);
79 }
80
81 TEST(Singleton, MissingSingleton) {
82   EXPECT_DEATH([]() { auto u = Singleton<UnregisteredWatchdog>::get(); }(), "");
83 }
84
85 struct BasicUsageTag {};
86 template <typename T, typename Tag = detail::DefaultTag>
87 using SingletonBasicUsage = Singleton <T, Tag, BasicUsageTag>;
88
89 // Exercise some basic codepaths ensuring registration order and
90 // destruction order happen as expected, that instances are created
91 // when expected, etc etc.
92 TEST(Singleton, BasicUsage) {
93   auto& vault = *SingletonVault::singleton<BasicUsageTag>();
94
95   EXPECT_EQ(vault.registeredSingletonCount(), 0);
96   SingletonBasicUsage<Watchdog> watchdog_singleton;
97   EXPECT_EQ(vault.registeredSingletonCount(), 1);
98
99   SingletonBasicUsage<ChildWatchdog> child_watchdog_singleton;
100   EXPECT_EQ(vault.registeredSingletonCount(), 2);
101
102   vault.registrationComplete();
103
104   Watchdog* s1 = SingletonBasicUsage<Watchdog>::get();
105   EXPECT_NE(s1, nullptr);
106
107   Watchdog* s2 = SingletonBasicUsage<Watchdog>::get();
108   EXPECT_NE(s2, nullptr);
109
110   EXPECT_EQ(s1, s2);
111
112   auto s3 = SingletonBasicUsage<ChildWatchdog>::get();
113   EXPECT_NE(s3, nullptr);
114   EXPECT_NE(s2, s3);
115
116   EXPECT_EQ(vault.registeredSingletonCount(), 2);
117   EXPECT_EQ(vault.livingSingletonCount(), 2);
118
119   vault.destroyInstances();
120   EXPECT_EQ(vault.registeredSingletonCount(), 2);
121   EXPECT_EQ(vault.livingSingletonCount(), 0);
122 }
123
124 struct DirectUsageTag {};
125 template <typename T, typename Tag = detail::DefaultTag>
126 using SingletonDirectUsage = Singleton <T, Tag, DirectUsageTag>;
127
128 TEST(Singleton, DirectUsage) {
129   auto& vault = *SingletonVault::singleton<DirectUsageTag>();
130
131   EXPECT_EQ(vault.registeredSingletonCount(), 0);
132
133   // Verify we can get to the underlying singletons via directly using
134   // the singleton definition.
135   SingletonDirectUsage<Watchdog> watchdog;
136   struct TestTag {};
137   SingletonDirectUsage<Watchdog, TestTag> named_watchdog;
138   EXPECT_EQ(vault.registeredSingletonCount(), 2);
139   vault.registrationComplete();
140
141   EXPECT_NE(watchdog.get(), nullptr);
142   EXPECT_EQ(watchdog.get(), SingletonDirectUsage<Watchdog>::get());
143   EXPECT_NE(watchdog.get(), named_watchdog.get());
144   EXPECT_EQ(watchdog->livingWatchdogCount(), 2);
145   EXPECT_EQ((*watchdog).livingWatchdogCount(), 2);
146
147   vault.destroyInstances();
148 }
149
150 struct NamedUsageTag {};
151 template <typename T, typename Tag = detail::DefaultTag>
152 using SingletonNamedUsage = Singleton <T, Tag, NamedUsageTag>;
153
154 TEST(Singleton, NamedUsage) {
155   auto& vault = *SingletonVault::singleton<NamedUsageTag>();
156
157   EXPECT_EQ(vault.registeredSingletonCount(), 0);
158
159   // Define two named Watchdog singletons and one unnamed singleton.
160   struct Watchdog1 {};
161   struct Watchdog2 {};
162   typedef detail::DefaultTag Watchdog3;
163   SingletonNamedUsage<Watchdog, Watchdog1> watchdog1_singleton;
164   EXPECT_EQ(vault.registeredSingletonCount(), 1);
165   SingletonNamedUsage<Watchdog, Watchdog2> watchdog2_singleton;
166   EXPECT_EQ(vault.registeredSingletonCount(), 2);
167   SingletonNamedUsage<Watchdog, Watchdog3> watchdog3_singleton;
168   EXPECT_EQ(vault.registeredSingletonCount(), 3);
169
170   vault.registrationComplete();
171
172   // Verify our three singletons are distinct and non-nullptr.
173   Watchdog* s1 = SingletonNamedUsage<Watchdog, Watchdog1>::get();
174   EXPECT_EQ(s1, watchdog1_singleton.get());
175   Watchdog* s2 = SingletonNamedUsage<Watchdog, Watchdog2>::get();
176   EXPECT_EQ(s2, watchdog2_singleton.get());
177   EXPECT_NE(s1, s2);
178   Watchdog* s3 = SingletonNamedUsage<Watchdog, Watchdog3>::get();
179   EXPECT_EQ(s3, watchdog3_singleton.get());
180   EXPECT_NE(s3, s1);
181   EXPECT_NE(s3, s2);
182
183   // Verify the "default" singleton is the same as the DefaultTag-tagged
184   // singleton.
185   Watchdog* s4 = SingletonNamedUsage<Watchdog>::get();
186   EXPECT_EQ(s4, watchdog3_singleton.get());
187
188   vault.destroyInstances();
189 }
190
191 struct NaughtyUsageTag {};
192 template <typename T, typename Tag = detail::DefaultTag>
193 using SingletonNaughtyUsage = Singleton <T, Tag, NaughtyUsageTag>;
194 struct NaughtyUsageTag2 {};
195 template <typename T, typename Tag = detail::DefaultTag>
196 using SingletonNaughtyUsage2 = Singleton <T, Tag, NaughtyUsageTag2>;
197
198 // Some pathological cases such as getting unregistered singletons,
199 // double registration, etc.
200 TEST(Singleton, NaughtyUsage) {
201   auto& vault = *SingletonVault::singleton<NaughtyUsageTag>();
202
203   vault.registrationComplete();
204
205   // Unregistered.
206   EXPECT_DEATH(Singleton<Watchdog>::get(), "");
207   EXPECT_DEATH(SingletonNaughtyUsage<Watchdog>::get(), "");
208
209   vault.destroyInstances();
210
211   auto& vault2 = *SingletonVault::singleton<NaughtyUsageTag2>();
212
213   EXPECT_DEATH(SingletonNaughtyUsage2<Watchdog>::get(), "");
214   SingletonNaughtyUsage2<Watchdog> watchdog_singleton;
215
216   // double registration
217   EXPECT_DEATH([]() { SingletonNaughtyUsage2<Watchdog> watchdog_singleton; }(),
218                "");
219   vault2.destroyInstances();
220
221   // double registration after destroy
222   EXPECT_DEATH([]() { SingletonNaughtyUsage2<Watchdog> watchdog_singleton; }(),
223                "");
224 }
225
226 struct SharedPtrUsageTag {};
227 template <typename T, typename Tag = detail::DefaultTag>
228 using SingletonSharedPtrUsage = Singleton <T, Tag, SharedPtrUsageTag>;
229
230 TEST(Singleton, SharedPtrUsage) {
231   struct WatchdogHolder {
232     ~WatchdogHolder() {
233       if (watchdog) {
234         LOG(ERROR) << "The following log message with stack trace is expected";
235       }
236     }
237
238     std::shared_ptr<Watchdog> watchdog;
239   };
240
241   auto& vault = *SingletonVault::singleton<SharedPtrUsageTag>();
242
243   EXPECT_EQ(vault.registeredSingletonCount(), 0);
244   SingletonSharedPtrUsage<Watchdog> watchdog_singleton;
245   EXPECT_EQ(vault.registeredSingletonCount(), 1);
246
247   SingletonSharedPtrUsage<ChildWatchdog> child_watchdog_singleton;
248   EXPECT_EQ(vault.registeredSingletonCount(), 2);
249
250   struct ATag {};
251   SingletonSharedPtrUsage<Watchdog, ATag> named_watchdog_singleton;
252
253   SingletonSharedPtrUsage<WatchdogHolder> watchdog_holder_singleton;
254
255   vault.registrationComplete();
256
257   // Initilize holder singleton first, so that it's the last one to be
258   // destroyed.
259   watchdog_holder_singleton.get();
260
261   Watchdog* s1 = SingletonSharedPtrUsage<Watchdog>::get();
262   EXPECT_NE(s1, nullptr);
263
264   Watchdog* s2 = SingletonSharedPtrUsage<Watchdog>::get();
265   EXPECT_NE(s2, nullptr);
266
267   EXPECT_EQ(s1, s2);
268
269   auto weak_s1 = SingletonSharedPtrUsage<Watchdog>::get_weak();
270
271   auto shared_s1 = weak_s1.lock();
272   EXPECT_EQ(shared_s1.get(), s1);
273   EXPECT_EQ(shared_s1.use_count(), 2);
274
275   auto old_serial = shared_s1->serial_number;
276
277   {
278     auto named_weak_s1 =
279       SingletonSharedPtrUsage<Watchdog, ATag>::get_weak();
280     auto locked = named_weak_s1.lock();
281     EXPECT_NE(locked.get(), shared_s1.get());
282   }
283
284   // We should release externally locked shared_ptr, otherwise it will be
285   // considered a leak
286   watchdog_holder_singleton->watchdog = std::move(shared_s1);
287
288   LOG(ERROR) << "The following log message regarding shared_ptr is expected";
289   {
290     auto start_time = std::chrono::steady_clock::now();
291     vault.destroyInstances();
292     auto duration = std::chrono::steady_clock::now() - start_time;
293     EXPECT_TRUE(duration > std::chrono::seconds{4} &&
294                 duration < std::chrono::seconds{6});
295   }
296   EXPECT_EQ(vault.registeredSingletonCount(), 4);
297   EXPECT_EQ(vault.livingSingletonCount(), 0);
298
299   EXPECT_TRUE(weak_s1.expired());
300
301   auto empty_s1 = SingletonSharedPtrUsage<Watchdog>::get_weak();
302   EXPECT_FALSE(empty_s1.lock());
303
304   vault.reenableInstances();
305
306   // Singleton should be re-created only after reenableInstances() was called.
307   Watchdog* new_s1 = SingletonSharedPtrUsage<Watchdog>::get();
308   // Track serial number rather than pointer since the memory could be
309   // re-used when we create new_s1.
310   EXPECT_NE(new_s1->serial_number, old_serial);
311
312   auto new_s1_weak = SingletonSharedPtrUsage<Watchdog>::get_weak();
313   auto new_s1_shared = new_s1_weak.lock();
314   std::thread t([new_s1_shared]() mutable {
315       std::this_thread::sleep_for(std::chrono::seconds{2});
316       new_s1_shared.reset();
317     });
318   new_s1_shared.reset();
319   {
320     auto start_time = std::chrono::steady_clock::now();
321     vault.destroyInstances();
322     auto duration = std::chrono::steady_clock::now() - start_time;
323     EXPECT_TRUE(duration > std::chrono::seconds{1} &&
324                 duration < std::chrono::seconds{3});
325   }
326   EXPECT_TRUE(new_s1_weak.expired());
327   t.join();
328 }
329
330 // Some classes to test singleton dependencies.  NeedySingleton has a
331 // dependency on NeededSingleton, which happens during its
332 // construction.
333 struct NeedyTag {};
334 template <typename T, typename Tag = detail::DefaultTag>
335 using SingletonNeedy = Singleton <T, Tag, NeedyTag>;
336
337 struct NeededSingleton {};
338 struct NeedySingleton {
339   NeedySingleton() {
340     auto unused = SingletonNeedy<NeededSingleton>::get();
341     EXPECT_NE(unused, nullptr);
342   }
343 };
344
345 // Ensure circular dependencies fail -- a singleton that needs itself, whoops.
346 struct SelfNeedyTag {};
347 template <typename T, typename Tag = detail::DefaultTag>
348 using SingletonSelfNeedy = Singleton <T, Tag, SelfNeedyTag>;
349
350 struct SelfNeedySingleton {
351   SelfNeedySingleton() {
352     auto unused = SingletonSelfNeedy<SelfNeedySingleton>::get();
353     EXPECT_NE(unused, nullptr);
354   }
355 };
356
357 TEST(Singleton, SingletonDependencies) {
358   SingletonNeedy<NeededSingleton> needed_singleton;
359   SingletonNeedy<NeedySingleton> needy_singleton;
360   auto& needy_vault = *SingletonVault::singleton<NeedyTag>();
361
362   needy_vault.registrationComplete();
363
364   EXPECT_EQ(needy_vault.registeredSingletonCount(), 2);
365   EXPECT_EQ(needy_vault.livingSingletonCount(), 0);
366
367   auto needy = SingletonNeedy<NeedySingleton>::get();
368   EXPECT_EQ(needy_vault.livingSingletonCount(), 2);
369
370   SingletonSelfNeedy<SelfNeedySingleton> self_needy_singleton;
371   auto& self_needy_vault = *SingletonVault::singleton<SelfNeedyTag>();
372
373   self_needy_vault.registrationComplete();
374   EXPECT_DEATH([]() { SingletonSelfNeedy<SelfNeedySingleton>::get(); }(), "");
375 }
376
377 // A test to ensure multiple threads contending on singleton creation
378 // properly wait for creation rather than thinking it is a circular
379 // dependency.
380 class Slowpoke : public Watchdog {
381  public:
382   Slowpoke() { std::this_thread::sleep_for(std::chrono::milliseconds(10)); }
383 };
384
385 struct ConcurrencyTag {};
386 template <typename T, typename Tag = detail::DefaultTag>
387 using SingletonConcurrency = Singleton <T, Tag, ConcurrencyTag>;
388
389 TEST(Singleton, SingletonConcurrency) {
390   auto& vault = *SingletonVault::singleton<ConcurrencyTag>();
391   SingletonConcurrency<Slowpoke> slowpoke_singleton;
392   vault.registrationComplete();
393
394   std::mutex gatekeeper;
395   gatekeeper.lock();
396   auto func = [&gatekeeper]() {
397     gatekeeper.lock();
398     gatekeeper.unlock();
399     auto unused = SingletonConcurrency<Slowpoke>::get();
400   };
401
402   EXPECT_EQ(vault.livingSingletonCount(), 0);
403   std::vector<std::thread> threads;
404   for (int i = 0; i < 100; ++i) {
405     threads.emplace_back(func);
406   }
407   // If circular dependency checks fail, the unlock would trigger a
408   // crash.  Instead, it succeeds, and we have exactly one living
409   // singleton.
410   gatekeeper.unlock();
411   for (auto& t : threads) {
412     t.join();
413   }
414   EXPECT_EQ(vault.livingSingletonCount(), 1);
415 }
416
417 struct ErrorConstructor {
418   static size_t constructCount_;
419   ErrorConstructor() {
420     if ((constructCount_++) == 0) {
421       throw std::runtime_error("first time fails");
422     }
423   }
424 };
425 size_t ErrorConstructor::constructCount_(0);
426
427 struct CreationErrorTag {};
428 template <typename T, typename Tag = detail::DefaultTag>
429 using SingletonCreationError = Singleton<T, Tag, CreationErrorTag>;
430
431 TEST(Singleton, SingletonCreationError) {
432   auto& vault = *SingletonVault::singleton<CreationErrorTag>();
433   SingletonCreationError<ErrorConstructor> error_once_singleton;
434
435   // first time should error out
436   EXPECT_THROW(error_once_singleton.get_weak().lock(), std::runtime_error);
437
438   // second time it'll work fine
439   error_once_singleton.get_weak().lock();
440   SUCCEED();
441 }
442
443 struct ConcurrencyStressTag {};
444 template <typename T, typename Tag = detail::DefaultTag>
445 using SingletonConcurrencyStress = Singleton <T, Tag, ConcurrencyStressTag>;
446
447 TEST(Singleton, SingletonConcurrencyStress) {
448   auto& vault = *SingletonVault::singleton<ConcurrencyStressTag>();
449   SingletonConcurrencyStress<Slowpoke> slowpoke_singleton;
450
451   std::vector<std::thread> ts;
452   for (size_t i = 0; i < 100; ++i) {
453     ts.emplace_back([&]() {
454         slowpoke_singleton.get_weak().lock();
455       });
456   }
457
458   for (size_t i = 0; i < 100; ++i) {
459     std::chrono::milliseconds d(20);
460
461     std::this_thread::sleep_for(d);
462     vault.destroyInstances();
463     std::this_thread::sleep_for(d);
464     vault.destroyInstances();
465   }
466
467   for (auto& t : ts) {
468     t.join();
469   }
470 }
471
472 // Benchmarking a normal singleton vs a Meyers singleton vs a Folly
473 // singleton.  Meyers are insanely fast, but (hopefully) Folly
474 // singletons are fast "enough."
475 int* getMeyersSingleton() {
476   static auto ret = new int(0);
477   return ret;
478 }
479
480 int normal_singleton_value = 0;
481 int* getNormalSingleton() {
482   doNotOptimizeAway(&normal_singleton_value);
483   return &normal_singleton_value;
484 }
485
486 struct MockTag {};
487 template <typename T, typename Tag = detail::DefaultTag>
488 using SingletonMock = Singleton <T, Tag, MockTag>;
489
490 // Verify that existing Singleton's can be overridden
491 // using the make_mock functionality.
492 TEST(Singleton, MockTest) {
493   auto& vault = *SingletonVault::singleton<MockTag>();
494
495   SingletonMock<Watchdog> watchdog_singleton;
496   vault.registrationComplete();
497
498   // Registring singletons after registrationComplete called works
499   // with make_mock (but not with Singleton ctor).
500   EXPECT_EQ(vault.registeredSingletonCount(), 1);
501   int serial_count_first = SingletonMock<Watchdog>::get()->serial_number;
502
503   // Override existing mock using make_mock.
504   SingletonMock<Watchdog>::make_mock();
505
506   EXPECT_EQ(vault.registeredSingletonCount(), 1);
507   int serial_count_mock = SingletonMock<Watchdog>::get()->serial_number;
508
509   // If serial_count value is the same, then singleton was not replaced.
510   EXPECT_NE(serial_count_first, serial_count_mock);
511 }
512
513 struct BenchmarkSingleton {
514   int val = 0;
515 };
516
517 BENCHMARK(NormalSingleton, n) {
518   for (size_t i = 0; i < n; ++i) {
519     doNotOptimizeAway(getNormalSingleton());
520   }
521 }
522
523 BENCHMARK_RELATIVE(MeyersSingleton, n) {
524   for (size_t i = 0; i < n; ++i) {
525     doNotOptimizeAway(getMeyersSingleton());
526   }
527 }
528
529 struct BenchmarkTag {};
530 template <typename T, typename Tag = detail::DefaultTag>
531 using SingletonBenchmark = Singleton <T, Tag, BenchmarkTag>;
532
533 struct GetTag{};
534 struct GetWeakTag{};
535
536 SingletonBenchmark<BenchmarkSingleton, GetTag> benchmark_singleton_get;
537 SingletonBenchmark<BenchmarkSingleton, GetWeakTag> benchmark_singleton_get_weak;
538
539 BENCHMARK_RELATIVE(FollySingleton, n) {
540   for (size_t i = 0; i < n; ++i) {
541     doNotOptimizeAway(SingletonBenchmark<BenchmarkSingleton, GetTag>::get());
542   }
543 }
544
545 BENCHMARK_RELATIVE(FollySingletonWeak, n) {
546   for (size_t i = 0; i < n; ++i) {
547     SingletonBenchmark<BenchmarkSingleton, GetWeakTag>::get_weak();
548   }
549 }
550
551 int main(int argc, char* argv[]) {
552   testing::InitGoogleTest(&argc, argv);
553   google::InitGoogleLogging(argv[0]);
554   gflags::ParseCommandLineFlags(&argc, &argv, true);
555
556   SingletonVault::singleton()->registrationComplete();
557
558   auto ret = RUN_ALL_TESTS();
559   if (!ret) {
560     folly::runBenchmarksOnFlag();
561   }
562   return ret;
563 }