blob: 32e483734519619c8a086af246f862fc23940ae3 [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gmock/gmock.h"
#include "swap_management/mock_metrics.h"
#include "swap_management/mock_utils.h"
#include "swap_management/swap_tool.h"
#include <memory>
#include <absl/status/status.h>
#include <absl/strings/str_cat.h>
#include <chromeos/dbus/swap_management/dbus-constants.h>
#include <gtest/gtest.h>
using testing::_;
using testing::DoAll;
using testing::ElementsAre;
using testing::Return;
using testing::SetArgPointee;
using testing::StrictMock;
namespace swap_management {
namespace {
const char kSwapsNoZram[] =
"Filename "
" Type Size "
"Used Priority\n";
const char kZramDisksize8G[] = "16679780352";
const int kZramMemTotal8G = 8144424;
} // namespace
class SwapToolTest : public ::testing::Test {
public:
void SetUp() override {
swap_tool_ = std::make_unique<SwapTool>();
// Init Utils and then replace with mocked one.
Utils::OverrideForTesting(&mock_util_);
}
protected:
std::unique_ptr<SwapTool> swap_tool_;
MockUtils mock_util_;
};
TEST_F(SwapToolTest, SwapIsAlreadyOnOrOff) {
EXPECT_CALL(mock_util_, ReadFileToString(base::FilePath("/proc/swaps"), _))
.WillOnce(DoAll(SetArgPointee<1>(
absl::StrCat(kSwapsNoZram,
"/dev/zram0 "
" partition 16288844 "
"0 -2\n")),
Return(absl::OkStatus())));
EXPECT_THAT(swap_tool_->SwapStart(), absl::OkStatus());
EXPECT_CALL(mock_util_, ReadFileToString(base::FilePath("/proc/swaps"), _))
.WillOnce(DoAll(
SetArgPointee<1>(absl::StrCat(kSwapsNoZram,
"/zram0 "
"partition 16288844 "
"0 -2\n")),
Return(absl::OkStatus())));
EXPECT_THAT(swap_tool_->SwapStart(), absl::OkStatus());
EXPECT_CALL(mock_util_, ReadFileToString(base::FilePath("/proc/swaps"), _))
.WillOnce(
DoAll(SetArgPointee<1>(kSwapsNoZram), Return(absl::OkStatus())));
EXPECT_THAT(swap_tool_->SwapStop(), absl::OkStatus());
}
TEST_F(SwapToolTest, SwapStart) {
// IsZramSwapOn
EXPECT_CALL(mock_util_, ReadFileToString(base::FilePath("/proc/swaps"), _))
.WillOnce(
DoAll(SetArgPointee<1>(kSwapsNoZram), Return(absl::OkStatus())));
// GetZramSizeBytes
// GetUserConfigZramSizeBytes
EXPECT_CALL(mock_util_, ReadFileToStringWithMaxSize(
base::FilePath("/var/lib/swap/swap_size"), _, _))
.WillOnce(Return(
absl::NotFoundError("Failed to read /var/lib/swap/swap_size")));
base::SystemMemoryInfoKB mock_meminfo;
mock_meminfo.total = kZramMemTotal8G;
EXPECT_CALL(mock_util_, GetSystemMemoryInfo()).WillOnce(Return(mock_meminfo));
EXPECT_CALL(mock_util_,
RunProcessHelper(ElementsAre("/usr/bin/modprobe", "zram")))
.WillOnce(Return(absl::OkStatus()));
// EnableZramRecompression, we don't test it here.
EXPECT_CALL(mock_util_,
PathExists(base::FilePath("/sys/block/zram0/recomp_algorithm")))
.WillOnce(Return(absl::NotFoundError(
"/sys/block/zram0/recomp_algorithm does not exist.")));
EXPECT_CALL(mock_util_, WriteFile(base::FilePath("/sys/block/zram0/disksize"),
kZramDisksize8G))
.WillOnce(Return(absl::OkStatus()));
EXPECT_CALL(mock_util_,
RunProcessHelper(ElementsAre("/sbin/mkswap", "/dev/zram0")))
.WillOnce(Return(absl::OkStatus()));
// EnableZramSwapping
EXPECT_CALL(mock_util_,
RunProcessHelper(ElementsAre("/sbin/swapon", "/dev/zram0")))
.WillOnce(Return(absl::OkStatus()));
// Metrics::Get()->Start()
// We don't test metrics in swap_tool_test, just simply return.
MockMetrics mock_metrics_;
Metrics::OverrideForTesting(&mock_metrics_);
EXPECT_CALL(mock_metrics_, Start()).WillOnce(Return());
EXPECT_THAT(swap_tool_->SwapStart(), absl::OkStatus());
}
TEST_F(SwapToolTest, SwapStartButSwapIsDisabled) {
// IsZramSwapOn
EXPECT_CALL(mock_util_, ReadFileToString(base::FilePath("/proc/swaps"), _))
.WillOnce(
DoAll(SetArgPointee<1>(kSwapsNoZram), Return(absl::OkStatus())));
// GetZramSizeBytes
// GetUserConfigZramSizeBytes
EXPECT_CALL(mock_util_, ReadFileToStringWithMaxSize(
base::FilePath("/var/lib/swap/swap_size"), _, _))
.WillOnce(DoAll(SetArgPointee<1>("0"), Return(absl::OkStatus())));
EXPECT_THAT(swap_tool_->SwapStart(), absl::OkStatus());
}
TEST_F(SwapToolTest, SwapStop) {
// IsZramSwapOn
EXPECT_CALL(mock_util_, ReadFileToString(base::FilePath("/proc/swaps"), _))
.WillOnce(DoAll(
SetArgPointee<1>(absl::StrCat(std::string(kSwapsNoZram),
"/zram0 "
"partition 16288844 "
"0 -2\n")),
Return(absl::OkStatus())));
EXPECT_CALL(mock_util_, RunProcessHelper(
ElementsAre("/sbin/swapoff", "-v", "/dev/zram0")))
.WillOnce(Return(absl::OkStatus()));
EXPECT_CALL(mock_util_, WriteFile(base::FilePath("/sys/block/zram0/reset"),
std::to_string(1)))
.WillOnce(Return(absl::OkStatus()));
EXPECT_THAT(swap_tool_->SwapStop(), absl::OkStatus());
}
TEST_F(SwapToolTest, SwapSetSize) {
// If size is negative.
EXPECT_CALL(mock_util_, WriteFile(base::FilePath("/var/lib/swap/swap_size"),
absl::StrCat(0)))
.WillOnce(Return(absl::OkStatus()));
EXPECT_THAT(swap_tool_->SwapSetSize(-1), absl::OkStatus());
// If size is 0.
EXPECT_CALL(mock_util_, DeleteFile(base::FilePath("/var/lib/swap/swap_size")))
.WillOnce(Return(absl::OkStatus()));
EXPECT_THAT(swap_tool_->SwapSetSize(0), absl::OkStatus());
// If size is larger than 65000.
absl::Status status = swap_tool_->SwapSetSize(128000);
EXPECT_TRUE(absl::IsInvalidArgument(status));
EXPECT_EQ(status.ToString(),
"INVALID_ARGUMENT: Size is not between 128 and 65000 MiB.");
// If size is smaller than 128, but not 0.
status = swap_tool_->SwapSetSize(64);
EXPECT_TRUE(absl::IsInvalidArgument(status));
EXPECT_EQ(status.ToString(),
"INVALID_ARGUMENT: Size is not between 128 and 65000 MiB.");
// If size is between 128 and 65000.
EXPECT_CALL(mock_util_, WriteFile(base::FilePath("/var/lib/swap/swap_size"),
absl::StrCat(1024)))
.WillOnce(Return(absl::OkStatus()));
EXPECT_THAT(swap_tool_->SwapSetSize(1024), absl::OkStatus());
}
} // namespace swap_management