blob: 9fb3a6bd2681fc3b2431b82662a4b41e558a7830 [file] [log] [blame]
// Copyright 2019 The Chromium 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 "chrome/browser/chromeos/concierge_helper_service.h"
#include <memory>
#include "base/macros.h"
#include "base/run_loop.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/dbus/concierge/service.pb.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_concierge_client.h"
#include "chromeos/dbus/debug_daemon/fake_debug_daemon_client.h"
#include "content/public/test/browser_task_environment.h"
#include "dbus/bus.h"
#include "dbus/object_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
class TestDebugDaemonClient : public FakeDebugDaemonClient {
public:
TestDebugDaemonClient() = default;
~TestDebugDaemonClient() override = default;
void StartConcierge(ConciergeCallback callback) override {
++start_concierge_called_;
FakeDebugDaemonClient::StartConcierge(std::move(callback));
}
size_t start_concierge_called() const { return start_concierge_called_; }
private:
size_t start_concierge_called_{0};
DISALLOW_COPY_AND_ASSIGN(TestDebugDaemonClient);
};
class TestConciergeClient : public FakeConciergeClient {
public:
TestConciergeClient() = default;
~TestConciergeClient() override = default;
void SetVmCpuRestriction(
const vm_tools::concierge::SetVmCpuRestrictionRequest& request,
DBusMethodCallback<vm_tools::concierge::SetVmCpuRestrictionResponse>
callback) override {
requests_.push_back(request);
FakeConciergeClient::SetVmCpuRestriction(request, std::move(callback));
}
// Runs callback when service becomes available. If service is already
// available, runs callback immediately.
void WaitForServiceToBeAvailable(
dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback)
override {
if (!service_is_available_) {
callbacks_.push_back(std::move(callback));
} else {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), service_is_available_));
}
}
// Sets whether service is available or not. If service_is_available is
// true, all callbacks waiting for service to be available will be run.
void SetServiceIsAvailable(bool service_is_available) {
service_is_available_ = service_is_available;
if (service_is_available_ && !callbacks_.empty()) {
for (auto& callback : callbacks_)
WaitForServiceToBeAvailable(std::move(callback));
}
}
const std::vector<vm_tools::concierge::SetVmCpuRestrictionRequest>& requests()
const {
return requests_;
}
private:
std::vector<vm_tools::concierge::SetVmCpuRestrictionRequest> requests_;
std::vector<dbus::ObjectProxy::WaitForServiceToBeAvailableCallback>
callbacks_;
bool service_is_available_ = true;
DISALLOW_COPY_AND_ASSIGN(TestConciergeClient);
};
class ConciergeHelperServiceTest : public testing::Test {
public:
ConciergeHelperServiceTest() = default;
~ConciergeHelperServiceTest() override = default;
// testing::Test:
void SetUp() override {
auto setter = DBusThreadManager::GetSetterForTesting();
setter->SetDebugDaemonClient(std::make_unique<TestDebugDaemonClient>());
setter->SetConciergeClient(std::make_unique<TestConciergeClient>());
service_ = ConciergeHelperService::GetForBrowserContext(&profile_);
}
void TearDown() override { DBusThreadManager::Shutdown(); }
protected:
ConciergeHelperService* service() { return service_; }
TestConciergeClient* fake_concierge_client() {
return static_cast<TestConciergeClient*>(
DBusThreadManager::Get()->GetConciergeClient());
}
TestDebugDaemonClient* fake_debug_client() {
return static_cast<TestDebugDaemonClient*>(
DBusThreadManager::Get()->GetDebugDaemonClient());
}
content::BrowserTaskEnvironment* task_environment() {
return &task_environment_;
}
private:
content::BrowserTaskEnvironment task_environment_;
TestingProfile profile_;
ConciergeHelperService* service_;
DISALLOW_COPY_AND_ASSIGN(ConciergeHelperServiceTest);
};
// Tests that ConciergeHelperService can be constructed and destructed. Also,
// check that ConciergeHelperService starts Concierge on construction.
TEST_F(ConciergeHelperServiceTest, TestConstructDestruct) {
EXPECT_EQ(1U, fake_debug_client()->start_concierge_called());
}
// Tests that ConciergeHelperService makes cpu restriction requests correctly.
TEST_F(ConciergeHelperServiceTest, TestSetVmCpuRestriction) {
vm_tools::concierge::SetVmCpuRestrictionResponse response;
response.set_success(true);
fake_concierge_client()->set_set_vm_cpu_restriction_response(response);
service()->SetArcVmCpuRestriction(true);
service()->SetArcVmCpuRestriction(false);
service()->SetTerminaVmCpuRestriction(true);
service()->SetTerminaVmCpuRestriction(false);
service()->SetPluginVmCpuRestriction(true);
service()->SetPluginVmCpuRestriction(false);
task_environment()->RunUntilIdle();
std::vector<vm_tools::concierge::SetVmCpuRestrictionRequest> requests(
fake_concierge_client()->requests());
EXPECT_EQ(6U, requests.size());
EXPECT_EQ(vm_tools::concierge::CPU_CGROUP_ARCVM, requests[0].cpu_cgroup());
EXPECT_EQ(vm_tools::concierge::CPU_RESTRICTION_BACKGROUND,
requests[0].cpu_restriction_state());
EXPECT_EQ(vm_tools::concierge::CPU_CGROUP_ARCVM, requests[1].cpu_cgroup());
EXPECT_EQ(vm_tools::concierge::CPU_RESTRICTION_FOREGROUND,
requests[1].cpu_restriction_state());
EXPECT_EQ(vm_tools::concierge::CPU_CGROUP_TERMINA, requests[2].cpu_cgroup());
EXPECT_EQ(vm_tools::concierge::CPU_RESTRICTION_BACKGROUND,
requests[2].cpu_restriction_state());
EXPECT_EQ(vm_tools::concierge::CPU_CGROUP_TERMINA, requests[3].cpu_cgroup());
EXPECT_EQ(vm_tools::concierge::CPU_RESTRICTION_FOREGROUND,
requests[3].cpu_restriction_state());
EXPECT_EQ(vm_tools::concierge::CPU_CGROUP_PLUGINVM, requests[4].cpu_cgroup());
EXPECT_EQ(vm_tools::concierge::CPU_RESTRICTION_BACKGROUND,
requests[4].cpu_restriction_state());
EXPECT_EQ(vm_tools::concierge::CPU_CGROUP_PLUGINVM, requests[5].cpu_cgroup());
EXPECT_EQ(vm_tools::concierge::CPU_RESTRICTION_FOREGROUND,
requests[5].cpu_restriction_state());
}
// Tests that ConciergeHelperService requests cpu restriction immediately when
// dbus service is available, but waits until service is ready when it is not
// available.
TEST_F(ConciergeHelperServiceTest, TestWaitForServiceAvailable) {
// Service is available, so request is made immediately.
vm_tools::concierge::SetVmCpuRestrictionResponse response;
response.set_success(true);
fake_concierge_client()->set_set_vm_cpu_restriction_response(response);
fake_concierge_client()->SetServiceIsAvailable(true);
service()->SetArcVmCpuRestriction(true);
task_environment()->RunUntilIdle();
EXPECT_EQ(1U, fake_concierge_client()->requests().size());
// Service is unavailable, so request is queued until it is.
fake_concierge_client()->SetServiceIsAvailable(false);
service()->SetArcVmCpuRestriction(true);
task_environment()->RunUntilIdle();
EXPECT_EQ(1U, fake_concierge_client()->requests().size());
fake_concierge_client()->SetServiceIsAvailable(true);
task_environment()->RunUntilIdle();
EXPECT_EQ(2U, fake_concierge_client()->requests().size());
EXPECT_EQ(vm_tools::concierge::CPU_CGROUP_ARCVM,
fake_concierge_client()->requests()[0].cpu_cgroup());
EXPECT_EQ(vm_tools::concierge::CPU_CGROUP_ARCVM,
fake_concierge_client()->requests()[1].cpu_cgroup());
EXPECT_EQ(vm_tools::concierge::CPU_RESTRICTION_BACKGROUND,
fake_concierge_client()->requests()[0].cpu_restriction_state());
EXPECT_EQ(vm_tools::concierge::CPU_RESTRICTION_BACKGROUND,
fake_concierge_client()->requests()[1].cpu_restriction_state());
}
} // namespace chromeos