blob: 6af99ba49e30a1f75484825d740de8a8dcb71460 [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <utility>
#include <vector>
#include <base/bind.h>
#include <base/callback.h>
#include <base/run_loop.h>
#include <base/test/task_environment.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <mojo/public/cpp/bindings/binding.h>
#include "diagnostics/wilco_dtc_supportd/probe_service_impl.h"
#include "mojo/cros_healthd.mojom.h"
#include "mojo/cros_healthd_probe.mojom.h"
using testing::_;
using testing::Invoke;
using testing::Return;
using testing::StrictMock;
namespace diagnostics {
namespace mojo_ipc = ::chromeos::cros_healthd::mojom;
namespace {
class MockCallback {
public:
MOCK_METHOD(void, OnTelemetryInfo, (mojo_ipc::TelemetryInfoPtr));
};
class MockProbeService : public mojo_ipc::CrosHealthdProbeService {
public:
MOCK_METHOD(void,
ProbeProcessInfo,
(uint32_t, ProbeProcessInfoCallback),
(override));
MOCK_METHOD(void,
ProbeTelemetryInfo,
(const std::vector<mojo_ipc::ProbeCategoryEnum>&,
ProbeTelemetryInfoCallback),
(override));
};
class MockProbeServiceDelegate : public ProbeService::Delegate {
public:
MOCK_METHOD(bool,
BindCrosHealthdProbeService,
(mojo_ipc::CrosHealthdProbeServiceRequest),
(override));
};
} // namespace
// Tests for the ProbeServiceImpl class.
class ProbeServiceImplTest : public testing::Test {
public:
ProbeServiceImplTest() = default;
MockCallback* mock_callback() { return &mock_callback_; }
MockProbeService* mock_probe_service() { return &mock_probe_service_; }
mojo::Binding<mojo_ipc::CrosHealthdProbeService>* service_binding() {
return &service_binding_;
}
MockProbeServiceDelegate* mock_delegate() { return &mock_delegate_; }
ProbeService* service() { return &service_; }
private:
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
StrictMock<MockCallback> mock_callback_;
StrictMock<MockProbeService> mock_probe_service_;
mojo::Binding<mojo_ipc::CrosHealthdProbeService> service_binding_{
&mock_probe_service_ /* impl */};
StrictMock<MockProbeServiceDelegate> mock_delegate_;
ProbeServiceImpl service_{&mock_delegate_};
};
TEST_F(ProbeServiceImplTest, ProbeServiceNotAvailable) {
EXPECT_CALL(*mock_callback(), OnTelemetryInfo(_))
.WillOnce(
Invoke([](mojo_ipc::TelemetryInfoPtr ptr) { EXPECT_FALSE(ptr); }));
EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_));
service()->ProbeTelemetryInfo(
{}, base::BindOnce(&MockCallback::OnTelemetryInfo,
base::Unretained(mock_callback())));
}
TEST_F(ProbeServiceImplTest, ProbeServiceNotResponsive) {
EXPECT_CALL(*mock_callback(), OnTelemetryInfo(_))
.WillOnce(
Invoke([](mojo_ipc::TelemetryInfoPtr ptr) { EXPECT_FALSE(ptr); }));
EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
.WillOnce(Return(true));
service()->ProbeTelemetryInfo(
{}, base::BindOnce(&MockCallback::OnTelemetryInfo,
base::Unretained(mock_callback())));
}
TEST_F(ProbeServiceImplTest, DroppedConnection) {
EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
.WillOnce(Return(true));
base::RunLoop run_loop;
service()->ProbeTelemetryInfo(
{}, base::BindOnce(
[](base::Closure callback, mojo_ipc::TelemetryInfoPtr ptr) {
EXPECT_FALSE(ptr);
callback.Run();
},
run_loop.QuitClosure()));
run_loop.Run();
}
TEST_F(ProbeServiceImplTest, RecoverAfterDroppedConnection) {
EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
.WillOnce(Return(true));
base::RunLoop run_loop1;
service()->ProbeTelemetryInfo(
{}, base::BindOnce(
[](base::Closure callback, mojo_ipc::TelemetryInfoPtr ptr) {
EXPECT_FALSE(ptr);
callback.Run();
},
run_loop1.QuitClosure()));
run_loop1.Run();
EXPECT_CALL(*mock_probe_service(), ProbeTelemetryInfo(_, _))
.WillOnce(Invoke(
[](const std::vector<mojo_ipc::ProbeCategoryEnum>& categories,
mojo_ipc::CrosHealthdProbeService::ProbeTelemetryInfoCallback
callback) {
mojo_ipc::TelemetryInfo telemetry_info;
std::move(callback).Run(telemetry_info.Clone());
}));
EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
.WillOnce(
Invoke([service_binding = service_binding()](
mojo_ipc::CrosHealthdProbeServiceRequest request) -> bool {
service_binding->Bind(std::move(request));
return true;
}));
base::RunLoop run_loop2;
service()->ProbeTelemetryInfo(
{}, base::BindOnce(
[](base::Closure callback, mojo_ipc::TelemetryInfoPtr ptr) {
EXPECT_TRUE(ptr);
callback.Run();
},
run_loop2.QuitClosure()));
run_loop2.Run();
}
TEST_F(ProbeServiceImplTest, ProbeTelemetryInfo) {
const std::vector<mojo_ipc::ProbeCategoryEnum> kCategories{
mojo_ipc::ProbeCategoryEnum::kBattery};
EXPECT_CALL(*mock_probe_service(), ProbeTelemetryInfo(kCategories, _))
.WillOnce(Invoke(
[](const std::vector<mojo_ipc::ProbeCategoryEnum>& categories,
mojo_ipc::CrosHealthdProbeService::ProbeTelemetryInfoCallback
callback) {
mojo_ipc::TelemetryInfo telemetry_info;
telemetry_info.battery_result =
mojo_ipc::BatteryResult::NewBatteryInfo(
mojo_ipc::BatteryInfoPtr());
std::move(callback).Run(telemetry_info.Clone());
}));
EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
.WillOnce(
Invoke([service_binding = service_binding()](
mojo_ipc::CrosHealthdProbeServiceRequest request) -> bool {
service_binding->Bind(std::move(request));
return true;
}));
base::RunLoop run_loop;
service()->ProbeTelemetryInfo(
kCategories,
base::BindOnce(
[](base::Closure callback, mojo_ipc::TelemetryInfoPtr ptr) {
ASSERT_TRUE(ptr);
EXPECT_TRUE(ptr->battery_result->is_battery_info());
callback.Run();
},
run_loop.QuitClosure()));
run_loop.Run();
}
} // namespace diagnostics