#include "chrome/common/conflicts/module_watcher_win.h"
#include <windows.h>
#include <memory>
#include "base/functional/bind.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
class ModuleWatcherTest : public testing::Test {
public:
ModuleWatcherTest(const ModuleWatcherTest&) = delete;
ModuleWatcherTest& operator=(const ModuleWatcherTest&) = delete;
protected:
ModuleWatcherTest()
: module_(nullptr),
module_event_count_(0),
module_already_loaded_event_count_(0),
module_loaded_event_count_(0) {}
void OnModuleEvent(const ModuleWatcher::ModuleEvent& event) {
++module_event_count_;
switch (event.event_type) {
case ModuleWatcher::ModuleEventType::kModuleAlreadyLoaded:
++module_already_loaded_event_count_;
break;
case ModuleWatcher::ModuleEventType::kModuleLoaded:
++module_loaded_event_count_;
break;
}
}
void TearDown() override { UnloadModule(); }
void LoadModule() {
if (module_)
return;
static constexpr wchar_t kModuleName[] = L"conflicts_dll.dll";
ASSERT_FALSE(::GetModuleHandle(kModuleName));
module_ = ::LoadLibrary(kModuleName);
ASSERT_TRUE(module_);
}
void UnloadModule() {
if (!module_)
return;
::FreeLibrary(module_);
module_ = nullptr;
}
void RunUntilIdle() { task_environment_.RunUntilIdle(); }
std::unique_ptr<ModuleWatcher> Create() {
return ModuleWatcher::Create(base::BindRepeating(
&ModuleWatcherTest::OnModuleEvent, base::Unretained(this)));
}
base::test::TaskEnvironment task_environment_;
HMODULE module_;
int module_event_count_;
int module_already_loaded_event_count_;
int module_loaded_event_count_;
};
TEST_F(ModuleWatcherTest, SingleModuleWatcherOnly) {
std::unique_ptr<ModuleWatcher> mw1(Create());
EXPECT_TRUE(mw1.get());
std::unique_ptr<ModuleWatcher> mw2(Create());
EXPECT_FALSE(mw2.get());
}
#if BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER)
#define MAYBE_ModuleEvents DISABLED_ModuleEvents
#else
#define MAYBE_ModuleEvents ModuleEvents
#endif
TEST_F(ModuleWatcherTest, MAYBE_ModuleEvents) {
std::unique_ptr<ModuleWatcher> mw(Create());
RunUntilIdle();
EXPECT_LT(0, module_event_count_);
EXPECT_LT(0, module_already_loaded_event_count_);
EXPECT_EQ(0, module_loaded_event_count_);
int previous_module_loaded_event_count = module_loaded_event_count_;
LoadModule();
EXPECT_LT(previous_module_loaded_event_count, module_loaded_event_count_);
UnloadModule();
previous_module_loaded_event_count = module_loaded_event_count_;
LoadModule();
EXPECT_LT(previous_module_loaded_event_count, module_loaded_event_count_);
UnloadModule();
mw.reset();
previous_module_loaded_event_count = module_loaded_event_count_;
LoadModule();
EXPECT_EQ(previous_module_loaded_event_count, module_loaded_event_count_);
}