summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux
diff options
context:
space:
mode:
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r--test/syscalls/linux/cgroup.cc81
1 files changed, 81 insertions, 0 deletions
diff --git a/test/syscalls/linux/cgroup.cc b/test/syscalls/linux/cgroup.cc
index ca23dfeee..50705a86e 100644
--- a/test/syscalls/linux/cgroup.cc
+++ b/test/syscalls/linux/cgroup.cc
@@ -37,6 +37,8 @@ namespace {
using ::testing::_;
using ::testing::Contains;
+using ::testing::Each;
+using ::testing::Eq;
using ::testing::Ge;
using ::testing::Gt;
using ::testing::Key;
@@ -383,6 +385,32 @@ PosixError WriteAndVerifyControlValue(const Cgroup& c, std::string_view path,
return NoError();
}
+PosixErrorOr<std::vector<bool>> ParseBitmap(std::string s) {
+ std::vector<bool> bitmap;
+ bitmap.reserve(64);
+ for (const std::string_view& t : absl::StrSplit(s, ',')) {
+ std::vector<std::string> parts = absl::StrSplit(t, absl::MaxSplits('-', 2));
+ if (parts.size() == 2) {
+ ASSIGN_OR_RETURN_ERRNO(int64_t start, Atoi<int64_t>(parts[0]));
+ ASSIGN_OR_RETURN_ERRNO(int64_t end, Atoi<int64_t>(parts[1]));
+ // Note: start and end are indices into bitmap.
+ if (end >= bitmap.size()) {
+ bitmap.resize(end + 1, false);
+ }
+ for (int i = start; i <= end; ++i) {
+ bitmap[i] = true;
+ }
+ } else { // parts.size() == 1, 0 not possible.
+ ASSIGN_OR_RETURN_ERRNO(int64_t i, Atoi<int64_t>(parts[0]));
+ if (i >= bitmap.size()) {
+ bitmap.resize(i + 1, false);
+ }
+ bitmap[i] = true;
+ }
+ }
+ return bitmap;
+}
+
TEST(JobCgroup, ReadWriteRead) {
SKIP_IF(!CgroupsAvailable());
@@ -396,6 +424,59 @@ TEST(JobCgroup, ReadWriteRead) {
EXPECT_NO_ERRNO(WriteAndVerifyControlValue(c, "job.id", LLONG_MAX));
}
+TEST(CpusetCgroup, Defaults) {
+ SKIP_IF(!CgroupsAvailable());
+ Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()));
+ Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpuset"));
+
+ std::string cpus =
+ ASSERT_NO_ERRNO_AND_VALUE(c.ReadControlFile("cpuset.cpus"));
+ std::vector<bool> cpus_bitmap = ASSERT_NO_ERRNO_AND_VALUE(ParseBitmap(cpus));
+ EXPECT_GT(cpus_bitmap.size(), 0);
+ EXPECT_THAT(cpus_bitmap, Each(Eq(true)));
+
+ std::string mems =
+ ASSERT_NO_ERRNO_AND_VALUE(c.ReadControlFile("cpuset.mems"));
+ std::vector<bool> mems_bitmap = ASSERT_NO_ERRNO_AND_VALUE(ParseBitmap(mems));
+ EXPECT_GT(mems_bitmap.size(), 0);
+ EXPECT_THAT(mems_bitmap, Each(Eq(true)));
+}
+
+TEST(CpusetCgroup, SetMask) {
+ SKIP_IF(!CgroupsAvailable());
+ Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()));
+ Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpuset"));
+
+ std::string cpus =
+ ASSERT_NO_ERRNO_AND_VALUE(c.ReadControlFile("cpuset.cpus"));
+ std::vector<bool> cpus_bitmap = ASSERT_NO_ERRNO_AND_VALUE(ParseBitmap(cpus));
+
+ SKIP_IF(cpus_bitmap.size() <= 1); // "Not enough CPUs"
+
+ int max_cpu = cpus_bitmap.size() - 1;
+ ASSERT_NO_ERRNO(
+ c.WriteControlFile("cpuset.cpus", absl::StrCat("1-", max_cpu)));
+ cpus_bitmap[0] = false;
+ cpus = ASSERT_NO_ERRNO_AND_VALUE(c.ReadControlFile("cpuset.cpus"));
+ std::vector<bool> cpus_bitmap_after =
+ ASSERT_NO_ERRNO_AND_VALUE(ParseBitmap(cpus));
+ EXPECT_EQ(cpus_bitmap_after, cpus_bitmap);
+}
+
+TEST(CpusetCgroup, SetEmptyMask) {
+ SKIP_IF(!CgroupsAvailable());
+ Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()));
+ Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("cpuset"));
+ ASSERT_NO_ERRNO(c.WriteControlFile("cpuset.cpus", ""));
+ std::string_view cpus = absl::StripAsciiWhitespace(
+ ASSERT_NO_ERRNO_AND_VALUE(c.ReadControlFile("cpuset.cpus")));
+ EXPECT_EQ(cpus, "");
+ ASSERT_NO_ERRNO(c.WriteControlFile("cpuset.mems", ""));
+ std::string_view mems = absl::StripAsciiWhitespace(
+ ASSERT_NO_ERRNO_AND_VALUE(c.ReadControlFile("cpuset.mems")));
+ EXPECT_EQ(mems, "");
+}
+
TEST(ProcCgroups, Empty) {
SKIP_IF(!CgroupsAvailable());