#include "base/win/com_init_balancer.h"
#include <shlobj.h>
#include <wrl/client.h>
#include "base/test/gtest_util.h"
#include "base/win/com_init_util.h"
#include "base/win/scoped_com_initializer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace win {
using Microsoft::WRL::ComPtr;
TEST(TestComInitBalancer, BalancedPairsWithComBalancerEnabled) {
{
ScopedCOMInitializer com_initializer(
ScopedCOMInitializer::Uninitialization::kBlockPremature);
ASSERT_TRUE(com_initializer.Succeeded());
ComPtr<IUnknown> shell_link;
HRESULT hr = ::CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_ALL,
IID_PPV_ARGS(&shell_link));
EXPECT_TRUE(SUCCEEDED(hr));
}
EXPECT_DCHECK_DEATH(AssertComInitialized());
}
TEST(TestComInitBalancer, UnbalancedPairsWithComBalancerEnabled) {
{
ScopedCOMInitializer com_initializer(
ScopedCOMInitializer::Uninitialization::kBlockPremature);
ASSERT_TRUE(com_initializer.Succeeded());
::CoUninitialize();
::CoUninitialize();
AssertComInitialized();
ComPtr<IUnknown> shell_link;
HRESULT hr = ::CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_ALL,
IID_PPV_ARGS(&shell_link));
EXPECT_TRUE(SUCCEEDED(hr));
}
EXPECT_DCHECK_DEATH(AssertComInitialized());
}
TEST(TestComInitBalancer, BalancedPairsWithComBalancerDisabled) {
{
ScopedCOMInitializer com_initializer(
ScopedCOMInitializer::Uninitialization::kAllow);
ASSERT_TRUE(com_initializer.Succeeded());
ComPtr<IUnknown> shell_link;
HRESULT hr = ::CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_ALL,
IID_PPV_ARGS(&shell_link));
EXPECT_TRUE(SUCCEEDED(hr));
}
EXPECT_DCHECK_DEATH(AssertComInitialized());
}
TEST(TestComInitBalancer, UnbalancedPairsWithComBalancerDisabled) {
ScopedCOMInitializer com_initializer(
ScopedCOMInitializer::Uninitialization::kAllow);
ASSERT_TRUE(com_initializer.Succeeded());
::CoUninitialize();
::CoUninitialize();
EXPECT_DCHECK_DEATH(AssertComInitialized());
ComPtr<IUnknown> shell_link;
HRESULT hr = ::CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_ALL,
IID_PPV_ARGS(&shell_link));
EXPECT_TRUE(FAILED(hr));
EXPECT_EQ(CO_E_NOTINITIALIZED, hr);
}
TEST(TestComInitBalancer, OneRegisteredSpyRefCount) {
ScopedCOMInitializer com_initializer(
ScopedCOMInitializer::Uninitialization::kBlockPremature);
ASSERT_TRUE(com_initializer.Succeeded());
EXPECT_EQ(DWORD(1), com_initializer.GetCOMBalancerReferenceCountForTesting());
::CoUninitialize();
EXPECT_EQ(DWORD(1), com_initializer.GetCOMBalancerReferenceCountForTesting());
}
TEST(TestComInitBalancer, ThreeRegisteredSpiesRefCount) {
ScopedCOMInitializer com_initializer_1(
ScopedCOMInitializer::Uninitialization::kBlockPremature);
ScopedCOMInitializer com_initializer_2(
ScopedCOMInitializer::Uninitialization::kBlockPremature);
ScopedCOMInitializer com_initializer_3(
ScopedCOMInitializer::Uninitialization::kBlockPremature);
ASSERT_TRUE(com_initializer_1.Succeeded());
ASSERT_TRUE(com_initializer_2.Succeeded());
ASSERT_TRUE(com_initializer_3.Succeeded());
EXPECT_EQ(DWORD(3),
com_initializer_1.GetCOMBalancerReferenceCountForTesting());
EXPECT_EQ(DWORD(3),
com_initializer_2.GetCOMBalancerReferenceCountForTesting());
EXPECT_EQ(DWORD(3),
com_initializer_3.GetCOMBalancerReferenceCountForTesting());
::CoUninitialize();
::CoUninitialize();
::CoUninitialize();
EXPECT_EQ(DWORD(1),
com_initializer_1.GetCOMBalancerReferenceCountForTesting());
EXPECT_EQ(DWORD(1),
com_initializer_2.GetCOMBalancerReferenceCountForTesting());
EXPECT_EQ(DWORD(1),
com_initializer_3.GetCOMBalancerReferenceCountForTesting());
}
}
}