Ejemplo n.º 1
0
// Exercise some basic codepaths ensuring registration order and
// destruction order happen as expected, that instances are created
// when expected, etc etc.
TEST(Singleton, BasicUsage) {
  SingletonVault vault;

  EXPECT_EQ(vault.registeredSingletonCount(), 0);
  Singleton<Watchdog> watchdog_singleton(nullptr, nullptr, &vault);
  EXPECT_EQ(vault.registeredSingletonCount(), 1);

  Singleton<ChildWatchdog> child_watchdog_singleton(nullptr, nullptr, &vault);
  EXPECT_EQ(vault.registeredSingletonCount(), 2);

  vault.registrationComplete();

  Watchdog* s1 = Singleton<Watchdog>::get(&vault);
  EXPECT_NE(s1, nullptr);

  Watchdog* s2 = Singleton<Watchdog>::get(&vault);
  EXPECT_NE(s2, nullptr);

  EXPECT_EQ(s1, s2);

  auto s3 = Singleton<ChildWatchdog>::get(&vault);
  EXPECT_NE(s3, nullptr);
  EXPECT_NE(s2, s3);

  EXPECT_EQ(vault.registeredSingletonCount(), 2);
  EXPECT_EQ(vault.livingSingletonCount(), 2);

  vault.destroyInstances();
  EXPECT_EQ(vault.registeredSingletonCount(), 2);
  EXPECT_EQ(vault.livingSingletonCount(), 0);
}
Ejemplo n.º 2
0
TEST(Singleton, NamedUsage) {
  SingletonVault vault;

  EXPECT_EQ(vault.registeredSingletonCount(), 0);

  // Define two named Watchdog singletons and one unnamed singleton.
  Singleton<Watchdog> watchdog1_singleton(
      "watchdog1", nullptr, nullptr, &vault);
  EXPECT_EQ(vault.registeredSingletonCount(), 1);
  Singleton<Watchdog> watchdog2_singleton(
      "watchdog2", nullptr, nullptr, &vault);
  EXPECT_EQ(vault.registeredSingletonCount(), 2);
  Singleton<Watchdog> watchdog3_singleton(nullptr, nullptr, &vault);
  EXPECT_EQ(vault.registeredSingletonCount(), 3);

  vault.registrationComplete();

  // Verify our three singletons are distinct and non-nullptr.
  Watchdog* s1 = Singleton<Watchdog>::get("watchdog1", &vault);
  EXPECT_EQ(s1, watchdog1_singleton.ptr());
  Watchdog* s2 = Singleton<Watchdog>::get("watchdog2", &vault);
  EXPECT_EQ(s2, watchdog2_singleton.ptr());
  EXPECT_NE(s1, s2);
  Watchdog* s3 = Singleton<Watchdog>::get(&vault);
  EXPECT_EQ(s3, watchdog3_singleton.ptr());
  EXPECT_NE(s3, s1);
  EXPECT_NE(s3, s2);

  // Verify the "default" singleton is the same as the empty string
  // singleton.
  Watchdog* s4 = Singleton<Watchdog>::get("", &vault);
  EXPECT_EQ(s4, watchdog3_singleton.ptr());
}
Ejemplo n.º 3
0
TEST(Singleton, SharedPtrUsage) {
  SingletonVault vault;

  EXPECT_EQ(vault.registeredSingletonCount(), 0);
  Singleton<Watchdog> watchdog_singleton(nullptr, nullptr, &vault);
  EXPECT_EQ(vault.registeredSingletonCount(), 1);

  Singleton<ChildWatchdog> child_watchdog_singleton(nullptr, nullptr, &vault);
  EXPECT_EQ(vault.registeredSingletonCount(), 2);

  vault.registrationComplete();

  Watchdog* s1 = Singleton<Watchdog>::get(&vault);
  EXPECT_NE(s1, nullptr);

  Watchdog* s2 = Singleton<Watchdog>::get(&vault);
  EXPECT_NE(s2, nullptr);

  EXPECT_EQ(s1, s2);

  auto weak_s1 = Singleton<Watchdog>::get_weak(&vault);
  auto shared_s1 = weak_s1.lock();
  EXPECT_EQ(shared_s1.get(), s1);
  EXPECT_EQ(shared_s1.use_count(), 2);

  LOG(ERROR) << "The following log message regarding ref counts is expected";
  vault.destroyInstances();
  EXPECT_EQ(vault.registeredSingletonCount(), 2);
  EXPECT_EQ(vault.livingSingletonCount(), 0);

  EXPECT_EQ(shared_s1.use_count(), 1);
  EXPECT_EQ(shared_s1.get(), s1);

  auto locked_s1 = weak_s1.lock();
  EXPECT_EQ(locked_s1.get(), s1);
  EXPECT_EQ(shared_s1.use_count(), 2);
  locked_s1.reset();
  EXPECT_EQ(shared_s1.use_count(), 1);

  // Track serial number rather than pointer since the memory could be
  // re-used when we create new_s1.
  auto old_serial = shared_s1->serial_number;
  shared_s1.reset();
  locked_s1 = weak_s1.lock();
  EXPECT_TRUE(weak_s1.expired());

  Watchdog* new_s1 = Singleton<Watchdog>::get(&vault);
  EXPECT_NE(new_s1->serial_number, old_serial);
}
Ejemplo n.º 4
0
TEST(Singleton, DirectUsage) {
  SingletonVault vault;

  EXPECT_EQ(vault.registeredSingletonCount(), 0);

  // Verify we can get to the underlying singletons via directly using
  // the singleton definition.
  Singleton<Watchdog> watchdog(nullptr, nullptr, &vault);
  Singleton<Watchdog> named_watchdog("named", nullptr, nullptr, &vault);
  EXPECT_EQ(vault.registeredSingletonCount(), 2);
  vault.registrationComplete();

  EXPECT_NE(watchdog.ptr(), nullptr);
  EXPECT_EQ(watchdog.ptr(), Singleton<Watchdog>::get(&vault));
  EXPECT_NE(watchdog.ptr(), named_watchdog.ptr());
  EXPECT_EQ(watchdog->livingWatchdogCount(), 2);
  EXPECT_EQ((*watchdog).livingWatchdogCount(), 2);
}
Ejemplo n.º 5
0
TEST(Singleton, SingletonDependencies) {
  Singleton<NeededSingleton> needed_singleton(nullptr, nullptr, &needy_vault);
  Singleton<NeedySingleton> needy_singleton(nullptr, nullptr, &needy_vault);
  needy_vault.registrationComplete();

  EXPECT_EQ(needy_vault.registeredSingletonCount(), 2);
  EXPECT_EQ(needy_vault.livingSingletonCount(), 0);

  auto needy = Singleton<NeedySingleton>::get(&needy_vault);
  EXPECT_EQ(needy_vault.livingSingletonCount(), 2);

  Singleton<SelfNeedySingleton> self_needy_singleton(
      nullptr, nullptr, &self_needy_vault);
  self_needy_vault.registrationComplete();
  EXPECT_THROW([]() {
                 Singleton<SelfNeedySingleton>::get(&self_needy_vault);
               }(),
               std::out_of_range);
}