blob: 8f5fdff9fc52a12fa3aaf6762de163f10e6f5bea [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/reporting/health/health_module.h"
#include <utility>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/strings/strcat.h"
#include "base/task/thread_pool.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "components/reporting/util/test_support_callbacks.h"
#include "components/reporting/util/test_util.h"
using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::WithoutArgs;
namespace reporting {
namespace {
class MockHealthModuleDelegate : public HealthModuleDelegate {
public:
MOCK_METHOD(Status, DoInit, (), (override));
MOCK_METHOD(void, DoGetERPHealthData, (HealthCallback cb), (const override));
MOCK_METHOD(void,
DoPostHealthRecord,
(HealthDataHistory history),
(override));
};
HealthDataHistory AddEnqueueRecordCall() {
HealthDataHistory history;
EnqueueRecordCall call;
call.set_priority(Priority::IMMEDIATE);
*history.mutable_enqueue_record_call() = call;
history.set_timestamp_seconds(base::Time::Now().ToTimeT());
return history;
}
class HealthModuleTest : public ::testing::Test {
protected:
void SetUp() override {
delegate_ = std::make_unique<MockHealthModuleDelegate>();
mock_delegate_ = delegate_.get();
}
void TearDown() override {
mock_delegate_ = nullptr; // Prevent runaway pointer.
}
void CreateModule() {
// Next line will asynchronously invoke delegate_->Init.
module_ = HealthModule::Create(std::move(delegate_));
}
base::test::TaskEnvironment task_environment_;
std::unique_ptr<MockHealthModuleDelegate> delegate_;
raw_ptr<MockHealthModuleDelegate> mock_delegate_ = nullptr;
scoped_refptr<HealthModule> module_;
};
TEST_F(HealthModuleTest, Init) {
test::TestCallbackAutoWaiter init_waiter;
EXPECT_CALL(*mock_delegate_, DoInit())
.WillOnce(
DoAll(Invoke(&init_waiter, &test::TestCallbackAutoWaiter::Signal),
Return(Status::StatusOK())));
CreateModule();
}
TEST_F(HealthModuleTest, InitFails) {
test::TestCallbackAutoWaiter init_waiter;
EXPECT_CALL(*mock_delegate_, DoInit())
.WillOnce(
DoAll(Invoke(&init_waiter, &test::TestCallbackAutoWaiter::Signal),
Return(Status(error::UNKNOWN, "Test fails init"))));
CreateModule();
}
TEST_F(HealthModuleTest, WriteAndReadData) {
{
test::TestCallbackAutoWaiter init_waiter;
EXPECT_CALL(*mock_delegate_, DoInit())
.WillOnce(
DoAll(Invoke(&init_waiter, &test::TestCallbackAutoWaiter::Signal),
Return(Status::StatusOK())));
CreateModule();
}
ERPHealthData ref_data;
auto call = AddEnqueueRecordCall();
*ref_data.add_history() = call;
{
test::TestCallbackAutoWaiter post_waiter;
EXPECT_CALL(*mock_delegate_, DoPostHealthRecord(EqualsProto(call)))
.WillOnce(WithoutArgs(
Invoke(&post_waiter, &test::TestCallbackAutoWaiter::Signal)));
module_->PostHealthRecord(call);
}
test::TestEvent<const ERPHealthData> read_event;
EXPECT_CALL(*mock_delegate_, DoGetERPHealthData(_))
.WillOnce(Invoke(
[&ref_data](HealthCallback cb) { std::move(cb).Run(ref_data); }));
module_->GetHealthData(read_event.cb());
EXPECT_THAT(read_event.ref_result(), EqualsProto(ref_data));
}
TEST_F(HealthModuleTest, UseRecorder) {
{
test::TestCallbackAutoWaiter init_waiter;
EXPECT_CALL(*mock_delegate_, DoInit())
.WillOnce(
DoAll(Invoke(&init_waiter, &test::TestCallbackAutoWaiter::Signal),
Return(Status::StatusOK())));
CreateModule();
}
test::TestCallbackAutoWaiter post_waiter;
auto call = AddEnqueueRecordCall();
EXPECT_CALL(*mock_delegate_, DoPostHealthRecord(EqualsProto(call)))
.WillOnce(WithoutArgs(
Invoke(&post_waiter, &test::TestCallbackAutoWaiter::Signal)));
auto recorder = HealthModule::Recorder(module_);
// Hand recorder over for async processing.
// PostHealthRecord will be called by its destructor.
base::ThreadPool::PostTask(
FROM_HERE, {base::TaskPriority::BEST_EFFORT},
base::BindOnce([](HealthModule::Recorder recorder,
HealthDataHistory call) { *recorder = call; },
std::move(recorder), call));
}
} // namespace
} // namespace reporting