blob: 6f6bc7218d373cef9bdd7e306efb100b08cb4621 [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 <base/files/file_path.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>
#include "diagnostics/common/file_test_utils.h"
#include "diagnostics/cros_healthd/fetchers/memory_fetcher.h"
namespace diagnostics {
namespace {
constexpr char kRelativeMeminfoPath[] = "proc/meminfo";
constexpr char kRelativeVmStatPath[] = "proc/vmstat";
constexpr char kFakeMeminfoContents[] =
"MemTotal: 3906320 kB\nMemFree: 873180 kB\nMemAvailable: "
"87980 kB\n";
constexpr char kFakeMeminfoContentsIncorrectlyFormattedFile[] =
"Incorrectly formatted meminfo contents.\n";
constexpr char kFakeMeminfoContentsMissingMemtotal[] =
"MemFree: 873180 kB\nMemAvailable: 87980 kB\n";
constexpr char kFakeMeminfoContentsMissingMemfree[] =
"MemTotal: 3906320 kB\nMemAvailable: 87980 kB\n";
constexpr char kFakeMeminfoContentsMissingMemavailable[] =
"MemTotal: 3906320 kB\nMemFree: 873180 kB\n";
constexpr char kFakeMeminfoContentsIncorrectlyFormattedMemtotal[] =
"MemTotal: 3906320kB\nMemFree: 873180 kB\nMemAvailable: "
"87980 kB\n";
constexpr char kFakeMeminfoContentsIncorrectlyFormattedMemfree[] =
"MemTotal: 3906320 kB\nMemFree: 873180 WrongUnits\nMemAvailable: "
" 87980 kB\n";
constexpr char kFakeMeminfoContentsIncorrectlyFormattedMemavailable[] =
"MemTotal: 3906320 kB\nMemFree: 873180 kB\nMemAvailable: "
"NotAnInteger kB\n";
constexpr char kFakeVmStatContents[] = "foo 98\npgfault 654654\n";
constexpr char kFakeVmStatContentsIncorrectlyFormattedFile[] =
"NoKey\npgfault 71023\n";
constexpr char kFakeVmStatContentsMissingPgfault[] = "foo 9908\n";
constexpr char kFakeVmStatContentsIncorrectlyFormattedPgfault[] =
"pgfault NotAnInteger\n";
} // namespace
// Test that memory info can be read when it exists.
TEST(MemoryUtils, TestFetchMemoryInfo) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath), kFakeMeminfoContents));
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_memory_info());
const auto& memory_info = memory_result->get_memory_info();
EXPECT_EQ(memory_info->total_memory_kib, 3906320);
EXPECT_EQ(memory_info->free_memory_kib, 873180);
EXPECT_EQ(memory_info->available_memory_kib, 87980);
EXPECT_EQ(memory_info->page_faults_since_last_boot, 654654);
}
// Test that fetching memory info returns an error when /proc/meminfo doesn't
// exist.
TEST(MemoryUtils, TestFetchMemoryInfoNoProcMeminfo) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kFileReadError);
}
// Test that fetching memory info returns an error when /proc/meminfo is
// formatted incorrectly.
TEST(MemoryUtils, TestFetchMemoryInfoProcMeminfoFormattedIncorrectly) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath),
kFakeMeminfoContentsIncorrectlyFormattedFile));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/meminfo doesn't
// contain the MemTotal key.
TEST(MemoryUtils, TestFetchMemoryInfoProcMeminfoNoMemTotal) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(
WriteFileAndCreateParentDirs(root_dir.Append(kRelativeMeminfoPath),
kFakeMeminfoContentsMissingMemtotal));
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/meminfo doesn't
// contain the MemFree key.
TEST(MemoryUtils, TestFetchMemoryInfoProcMeminfoNoMemFree) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(
WriteFileAndCreateParentDirs(root_dir.Append(kRelativeMeminfoPath),
kFakeMeminfoContentsMissingMemfree));
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/meminfo doesn't
// contain the MemAvailable key.
TEST(MemoryUtils, TestFetchMemoryInfoProcMeminfoNoMemAvailable) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(
WriteFileAndCreateParentDirs(root_dir.Append(kRelativeMeminfoPath),
kFakeMeminfoContentsMissingMemavailable));
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/meminfo contains
// an incorrectly formatted MemTotal key.
TEST(MemoryUtils, TestFetchMemoryInfoProcMeminfoIncorrectlyFormattedMemTotal) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath),
kFakeMeminfoContentsIncorrectlyFormattedMemtotal));
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/meminfo contains
// an incorrectly formatted MemFree key.
TEST(MemoryUtils, TestFetchMemoryInfoProcMeminfoIncorrectlyFormattedMemFree) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath),
kFakeMeminfoContentsIncorrectlyFormattedMemfree));
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/meminfo contains
// an incorrectly formatted MemAvailable key.
TEST(MemoryUtils,
TestFetchMemoryInfoProcMeminfoIncorrectlyFormattedMemAvailable) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath),
kFakeMeminfoContentsIncorrectlyFormattedMemavailable));
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/vmstat doesn't
// exist.
TEST(MemoryUtils, TestFetchMemoryInfoNoProcVmStat) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath), kFakeMeminfoContents));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kFileReadError);
}
// Test that fetching memory info returns an error when /proc/vmstat is
// formatted incorrectly.
TEST(MemoryUtils, TestFetchMemoryInfoProcVmStatFormattedIncorrectly) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath), kFakeMeminfoContents));
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContentsIncorrectlyFormattedFile));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/vmstat doesn't
// contain the pgfault key.
TEST(MemoryUtils, TestFetchMemoryInfoProcVmStatNoPgfault) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath), kFakeMeminfoContents));
ASSERT_TRUE(WriteFileAndCreateParentDirs(root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContentsMissingPgfault));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
// Test that fetching memory info returns an error when /proc/vmstat contains
// an incorrectly formatted pgfault key.
TEST(MemoryUtils, TestFetchMemoryInfoProcVmStatIncorrectlyFormattedPgfault) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath root_dir = temp_dir.GetPath();
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeMeminfoPath), kFakeMeminfoContents));
ASSERT_TRUE(WriteFileAndCreateParentDirs(
root_dir.Append(kRelativeVmStatPath),
kFakeVmStatContentsIncorrectlyFormattedPgfault));
auto memory_result = FetchMemoryInfo(root_dir);
ASSERT_TRUE(memory_result->is_error());
EXPECT_EQ(memory_result->get_error()->type,
chromeos::cros_healthd::mojom::ErrorType::kParseError);
}
} // namespace diagnostics