blob: c591d19ced4534f556cb05c9dbcbf72260746d63 [file] [log] [blame]
// Copyright 2019 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 "vm_tools/concierge/vm_util.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace vm_tools {
namespace concierge {
TEST(VMUtilTest, LoadCustomParametersSupportsEmptyInput) {
base::StringPairs args;
LoadCustomParameters("", &args);
base::StringPairs expected;
EXPECT_THAT(args, testing::ContainerEq(expected));
}
TEST(VMUtilTest, LoadCustomParametersParsesManyPairs) {
base::StringPairs args;
LoadCustomParameters("Key1=Value1\nKey2=Value2\nKey3=Value3", &args);
base::StringPairs expected = {
{"Key1", "Value1"}, {"Key2", "Value2"}, {"Key3", "Value3"}};
EXPECT_THAT(args, testing::ContainerEq(expected));
}
TEST(VMUtilTest, LoadCustomParametersSkipsComments) {
base::StringPairs args;
LoadCustomParameters("Key1=Value1\n#Key2=Value2\nKey3=Value3", &args);
base::StringPairs expected{{"Key1", "Value1"}, {"Key3", "Value3"}};
EXPECT_THAT(args, testing::ContainerEq(expected));
}
TEST(VMUtilTest, LoadCustomParametersSkipsEmptyLines) {
base::StringPairs args;
LoadCustomParameters("Key1=Value1\n\n\n\n\n\n\nKey2=Value2\n\n\n\n", &args);
base::StringPairs expected{{"Key1", "Value1"}, {"Key2", "Value2"}};
EXPECT_THAT(args, testing::ContainerEq(expected));
}
TEST(VMUtilTest, LoadCustomParametersSupportsKeyWithoutValue) {
base::StringPairs args;
LoadCustomParameters("Key1=Value1\nKey2\n\n\n\nKey3", &args);
base::StringPairs expected{{"Key1", "Value1"}, {"Key2", ""}, {"Key3", ""}};
EXPECT_THAT(args, testing::ContainerEq(expected));
}
TEST(VMUtilTest, LoadCustomParametersSupportsRemoving) {
base::StringPairs args = {{"KeyToBeReplaced", "OldValue"},
{"KeyToBeKept", "ValueToBeKept"}};
LoadCustomParameters(
"Key1=Value1\nKey2=Value2\n!KeyToBeReplaced\nKeyToBeReplaced=NewValue",
&args);
base::StringPairs expected{{"KeyToBeKept", "ValueToBeKept"},
{"Key1", "Value1"},
{"Key2", "Value2"},
{"KeyToBeReplaced", "NewValue"}};
EXPECT_THAT(args, testing::ContainerEq(expected));
}
TEST(VMUtilTest, LoadCustomParametersSupportsRemovingByPrefix) {
base::StringPairs args = {{"foo", ""},
{"foo", "bar"},
{"foobar", ""},
{"foobar", "baz"},
{"barfoo", ""}};
LoadCustomParameters("!foo", &args);
base::StringPairs expected{{"barfoo", ""}};
EXPECT_THAT(args, testing::ContainerEq(expected));
}
TEST(VMUtilTest, RemoveParametersWithKeyReturnsFoundValue) {
base::StringPairs args = {{"KERNEL_PATH", "/a/b/c"}, {"Key1", "Value1"}};
LoadCustomParameters("Key2=Value2\nKey3=Value3", &args);
const std::string resolved_kernel_path =
RemoveParametersWithKey("KERNEL_PATH", "default_path", &args);
base::StringPairs expected{
{"Key1", "Value1"}, {"Key2", "Value2"}, {"Key3", "Value3"}};
EXPECT_THAT(args, testing::ContainerEq(expected));
EXPECT_THAT(resolved_kernel_path, "/a/b/c");
}
TEST(VMUtilTest, RemoveParametersWithKeyReturnsDefaultValue) {
base::StringPairs args = {{"SOME_OTHER_PATH", "/a/b/c"}, {"Key1", "Value1"}};
LoadCustomParameters("Key2=Value2\nKey3=Value3", &args);
const std::string resolved_kernel_path =
RemoveParametersWithKey("KERNEL_PATH", "default_path", &args);
base::StringPairs expected{{"SOME_OTHER_PATH", "/a/b/c"},
{"Key1", "Value1"},
{"Key2", "Value2"},
{"Key3", "Value3"}};
EXPECT_THAT(args, testing::ContainerEq(expected));
EXPECT_THAT(resolved_kernel_path, "default_path");
}
TEST(VMUtilTest, GetCpuAffinityFromClustersNoGroups) {
std::vector<std::vector<std::string>> cpu_clusters;
std::map<int32_t, std::vector<std::string>> cpu_capacity_groups;
auto cpu_affinity =
GetCpuAffinityFromClusters(cpu_clusters, cpu_capacity_groups);
EXPECT_EQ(cpu_affinity, base::nullopt);
}
TEST(VMUtilTest, GetCpuAffinityFromClustersGroupSizesOne) {
std::vector<std::vector<std::string>> cpu_clusters;
std::map<int32_t, std::vector<std::string>> cpu_capacity_groups;
cpu_clusters.push_back({"0", "1", "2", "3"});
cpu_capacity_groups.insert({1024, {"0", "1", "2", "3"}});
auto cpu_affinity =
GetCpuAffinityFromClusters(cpu_clusters, cpu_capacity_groups);
EXPECT_EQ(cpu_affinity, base::nullopt);
}
TEST(VMUtilTest, GetCpuAffinityFromClustersTwoClusters) {
std::vector<std::vector<std::string>> cpu_clusters;
std::map<int32_t, std::vector<std::string>> cpu_capacity_groups;
cpu_clusters.push_back({"0", "1"});
cpu_clusters.push_back({"2", "3"});
cpu_capacity_groups.insert({1024, {"0", "1", "2", "3"}});
auto cpu_affinity =
GetCpuAffinityFromClusters(cpu_clusters, cpu_capacity_groups);
ASSERT_TRUE(cpu_affinity);
EXPECT_EQ(*cpu_affinity, "0=0,1:1=0,1:2=2,3:3=2,3");
}
TEST(VMUtilTest, GetCpuAffinityFromClustersTwoCapacityGroups) {
std::vector<std::vector<std::string>> cpu_clusters;
std::map<int32_t, std::vector<std::string>> cpu_capacity_groups;
cpu_clusters.push_back({"0", "1", "2", "3"});
cpu_capacity_groups.insert({100, {"0", "2"}});
cpu_capacity_groups.insert({200, {"1", "3"}});
auto cpu_affinity =
GetCpuAffinityFromClusters(cpu_clusters, cpu_capacity_groups);
ASSERT_TRUE(cpu_affinity);
EXPECT_EQ(*cpu_affinity, "0=0,2:2=0,2:1=1,3:3=1,3");
}
TEST(VMUtilTest, GetCpuAffinityFromClustersBothPresent) {
std::vector<std::vector<std::string>> cpu_clusters;
std::map<int32_t, std::vector<std::string>> cpu_capacity_groups;
cpu_clusters.push_back({"0", "1"});
cpu_clusters.push_back({"2", "3"});
cpu_capacity_groups.insert({100, {"0", "2"}});
cpu_capacity_groups.insert({200, {"1", "3"}});
auto cpu_affinity =
GetCpuAffinityFromClusters(cpu_clusters, cpu_capacity_groups);
ASSERT_TRUE(cpu_affinity);
// Clusters take precedence over capacity groups, so this matches the
// TwoClusters result.
EXPECT_EQ(*cpu_affinity, "0=0,1:1=0,1:2=2,3:3=2,3");
}
/*
// CPU0-CPU1 LITTLE cores, CPU2-CPU3 big cores
TEST(VMUtilTest, CreateArcVMAffinityTwoCapacityClusters) {
ArcVmCPUTopology topology(4, 1);
topology.AddCpuToCapacityGroupForTesting(0, 42);
topology.AddCpuToCapacityGroupForTesting(1, 42);
topology.AddCpuToCapacityGroupForTesting(2, 128);
topology.AddCpuToCapacityGroupForTesting(3, 128);
topology.CreateCPUAffinityForTesting();
EXPECT_EQ(topology.NumCPUs(), 4);
EXPECT_EQ(topology.NumRTCPUs(), 1);
EXPECT_EQ(topology.RTCPUMask(), "1");
EXPECT_EQ(topology.AffinityMask(), "0=0:1=1:2=2,3:3=2,3");
EXPECT_EQ(topology.CapacityMask(), "0=42,1=42,2=128,3=128");
}
TEST(VMUtilTest, CreateArcVMAffinityTwoGroups) {
ArcVmCPUTopology topology(4, 1);
topology.AddCpuToCapacityGroupForTesting(0, 42);
topology.AddCpuToCapacityGroupForTesting(1, 42);
topology.AddCpuToCapacityGroupForTesting(2, 128);
topology.AddCpuToCapacityGroupForTesting(3, 128);
topology.AddCpuToPackageGroupForTesting(0, 0);
topology.AddCpuToPackageGroupForTesting(1, 0);
topology.AddCpuToPackageGroupForTesting(2, 1);
topology.AddCpuToPackageGroupForTesting(3, 1);
topology.CreateCPUAffinityForTesting();
EXPECT_EQ(topology.NumCPUs(), 4);
EXPECT_EQ(topology.NumRTCPUs(), 1);
EXPECT_EQ(topology.RTCPUMask(), "1");
EXPECT_EQ(topology.AffinityMask(), "0=0:1=1:2=2,3:3=2,3");
EXPECT_EQ(topology.CapacityMask(), "0=42,1=42,2=128,3=128");
}
TEST(VMUtilTest, CreateArcVMAffinityOnePackage) {
ArcVmCPUTopology topology(4, 1);
topology.AddCpuToCapacityGroupForTesting(0, 42);
topology.AddCpuToCapacityGroupForTesting(1, 42);
topology.AddCpuToCapacityGroupForTesting(2, 128);
topology.AddCpuToCapacityGroupForTesting(3, 128);
topology.AddCpuToPackageGroupForTesting(0, 0);
topology.AddCpuToPackageGroupForTesting(1, 0);
topology.AddCpuToPackageGroupForTesting(2, 0);
topology.AddCpuToPackageGroupForTesting(3, 0);
topology.CreateCPUAffinityForTesting();
EXPECT_EQ(topology.NumCPUs(), 4);
EXPECT_EQ(topology.NumRTCPUs(), 1);
EXPECT_EQ(topology.RTCPUMask(), "1");
EXPECT_EQ(topology.AffinityMask(), "0=0:1=1:2=2,3:3=2,3");
EXPECT_EQ(topology.CapacityMask(), "0=42,1=42,2=128,3=128");
}
TEST(VMUtilTest, CreateArcVMAffinityOnePackageOneCapacity) {
ArcVmCPUTopology topology(4, 1);
topology.AddCpuToCapacityGroupForTesting(0, 42);
topology.AddCpuToCapacityGroupForTesting(1, 42);
topology.AddCpuToCapacityGroupForTesting(2, 42);
topology.AddCpuToCapacityGroupForTesting(3, 42);
topology.AddCpuToPackageGroupForTesting(0, 0);
topology.AddCpuToPackageGroupForTesting(1, 0);
topology.AddCpuToPackageGroupForTesting(2, 0);
topology.AddCpuToPackageGroupForTesting(3, 0);
topology.CreateCPUAffinityForTesting();
EXPECT_EQ(topology.NumCPUs(), 4);
EXPECT_EQ(topology.NumRTCPUs(), 1);
EXPECT_EQ(topology.RTCPUMask(), "1");
EXPECT_EQ(topology.AffinityMask(), "0=0,2,3:1=1:2=0,2,3:3=0,2,3");
EXPECT_EQ(topology.CapacityMask(), "0=42,1=42,2=42,3=42");
}
// CPU2-CPU3 LITTLE cores, CPU0-CPU1 big cores
TEST(VMUtilTest, CreateArcVMAffinityTwoCapacityClustersReverse) {
ArcVmCPUTopology topology(4, 1);
topology.AddCpuToCapacityGroupForTesting(2, 42);
topology.AddCpuToCapacityGroupForTesting(3, 42);
topology.AddCpuToCapacityGroupForTesting(0, 128);
topology.AddCpuToCapacityGroupForTesting(1, 128);
topology.CreateCPUAffinityForTesting();
EXPECT_EQ(topology.NumCPUs(), 4);
EXPECT_EQ(topology.NumRTCPUs(), 1);
EXPECT_EQ(topology.RTCPUMask(), "2");
EXPECT_EQ(topology.AffinityMask(), "2=2:3=3:0=0,1:1=0,1");
EXPECT_EQ(topology.CapacityMask(), "2=42,3=42,0=128,1=128");
}
// All cores are in the same capacity group
TEST(VMUtilTest, CreateArcVMAffinityOneCapacityCluster) {
ArcVmCPUTopology topology(4, 0);
topology.AddCpuToCapacityGroupForTesting(0, 42);
topology.AddCpuToCapacityGroupForTesting(1, 42);
topology.AddCpuToCapacityGroupForTesting(2, 42);
topology.AddCpuToCapacityGroupForTesting(3, 42);
topology.SetNumRTCPUs(1);
topology.CreateCPUAffinityForTesting();
EXPECT_EQ(topology.NumCPUs(), 4);
EXPECT_EQ(topology.NumRTCPUs(), 1);
EXPECT_EQ(topology.RTCPUMask(), "1");
EXPECT_EQ(topology.AffinityMask(), "0=0,2,3:1=1:2=0,2,3:3=0,2,3");
EXPECT_EQ(topology.CapacityMask(), "0=42,1=42,2=42,3=42");
}
// No RT CPU requested
TEST(VMUtilTest, CreateArcVMAffinityOneCapacityClusterNoRT) {
ArcVmCPUTopology topology(4, 0);
topology.AddCpuToCapacityGroupForTesting(0, 42);
topology.AddCpuToCapacityGroupForTesting(1, 42);
topology.AddCpuToCapacityGroupForTesting(2, 42);
topology.AddCpuToCapacityGroupForTesting(3, 42);
topology.CreateCPUAffinityForTesting();
ASSERT_EQ(topology.RTCPUMask().size(), 0);
EXPECT_EQ(topology.NumCPUs(), 4);
EXPECT_EQ(topology.NumRTCPUs(), 0);
EXPECT_EQ(topology.AffinityMask(), "0=0,1,2,3:1=0,1,2,3:2=0,1,2,3:3=0,1,2,3");
EXPECT_EQ(topology.CapacityMask(), "0=42,1=42,2=42,3=42");
}
// Static ARCVM CPU topologu
TEST(VMUtilTest, CreateStaticArcVMAffinity) {
ArcVmCPUTopology topology(2, 1);
topology.CreateCPUAffinityForTesting();
EXPECT_EQ(topology.NumCPUs(), 3);
EXPECT_EQ(topology.NumRTCPUs(), 1);
ASSERT_EQ(topology.AffinityMask().size(), 0);
ASSERT_EQ(topology.RTCPUMask(), "2");
ASSERT_EQ(topology.CapacityMask().size(), 0);
}
*/
} // namespace concierge
} // namespace vm_tools