Ejemplo n.º 1
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);

  Singleton<Watchdog> named_watchdog_singleton(
      "a_name", nullptr, nullptr, &vault);
  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);

  {
    auto named_weak_s1 = Singleton<Watchdog>::get_weak("a_name", &vault);
    auto locked = named_weak_s1.lock();
    EXPECT_NE(locked.get(), shared_s1.get());
  }

  LOG(ERROR) << "The following log message regarding ref counts is expected";
  vault.destroyInstances();
  EXPECT_EQ(vault.registeredSingletonCount(), 3);
  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());

  auto empty_s1 = Singleton<Watchdog>::get_weak(&vault);
  EXPECT_FALSE(empty_s1.lock());

  vault.reenableInstances();

  // Singleton should be re-created only after reenableInstances() was called.
  Watchdog* new_s1 = Singleton<Watchdog>::get(&vault);
  EXPECT_NE(new_s1->serial_number, old_serial);
}