diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/syscalls/linux/cgroup.cc | 35 | ||||
-rw-r--r-- | test/util/cgroup_util.cc | 13 | ||||
-rw-r--r-- | test/util/cgroup_util.h | 8 |
3 files changed, 54 insertions, 2 deletions
diff --git a/test/syscalls/linux/cgroup.cc b/test/syscalls/linux/cgroup.cc index a1006a978..862328f5b 100644 --- a/test/syscalls/linux/cgroup.cc +++ b/test/syscalls/linux/cgroup.cc @@ -15,6 +15,7 @@ // All tests in this file rely on being about to mount and unmount cgroupfs, // which isn't expected to work, or be safe on a general linux system. +#include <limits.h> #include <sys/mount.h> #include <unistd.h> @@ -35,8 +36,9 @@ using ::testing::_; using ::testing::Ge; using ::testing::Gt; -std::vector<std::string> known_controllers = {"cpu", "cpuset", "cpuacct", - "memory"}; +std::vector<std::string> known_controllers = { + "cpu", "cpuset", "cpuacct", "job", "memory", +}; bool CgroupsAvailable() { return IsRunningOnGvisor() && !IsRunningWithVFS1() && @@ -257,6 +259,35 @@ TEST(CPUAcctCgroup, CPUAcctStat) { EXPECT_THAT(Atoi<int64_t>(sys_tokens[1]), IsPosixErrorOkAndHolds(Ge(0))); } +// WriteAndVerifyControlValue attempts to write val to a cgroup file at path, +// and verify the value by reading it afterwards. +PosixError WriteAndVerifyControlValue(const Cgroup& c, std::string_view path, + int64_t val) { + RETURN_IF_ERRNO(c.WriteIntegerControlFile(path, val)); + ASSIGN_OR_RETURN_ERRNO(int64_t newval, c.ReadIntegerControlFile(path)); + if (newval != val) { + return PosixError( + EINVAL, + absl::StrFormat( + "Unexpected value for control file '%s': expected %d, got %d", path, + val, newval)); + } + return NoError(); +} + +TEST(JobCgroup, ReadWriteRead) { + SKIP_IF(!CgroupsAvailable()); + + Mounter m(ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir())); + Cgroup c = ASSERT_NO_ERRNO_AND_VALUE(m.MountCgroupfs("job")); + + EXPECT_THAT(c.ReadIntegerControlFile("job.id"), IsPosixErrorOkAndHolds(0)); + EXPECT_NO_ERRNO(WriteAndVerifyControlValue(c, "job.id", 1234)); + EXPECT_NO_ERRNO(WriteAndVerifyControlValue(c, "job.id", -1)); + EXPECT_NO_ERRNO(WriteAndVerifyControlValue(c, "job.id", LLONG_MIN)); + EXPECT_NO_ERRNO(WriteAndVerifyControlValue(c, "job.id", LLONG_MAX)); +} + TEST(ProcCgroups, Empty) { SKIP_IF(!CgroupsAvailable()); diff --git a/test/util/cgroup_util.cc b/test/util/cgroup_util.cc index 65d9c4986..d8d3fe471 100644 --- a/test/util/cgroup_util.cc +++ b/test/util/cgroup_util.cc @@ -17,6 +17,7 @@ #include <sys/syscall.h> #include <unistd.h> +#include "absl/strings/str_cat.h" #include "absl/strings/str_split.h" #include "test/util/fs_util.h" #include "test/util/mount_util.h" @@ -50,6 +51,18 @@ PosixErrorOr<int64_t> Cgroup::ReadIntegerControlFile( return val; } +PosixError Cgroup::WriteControlFile(absl::string_view name, + const std::string& value) const { + ASSIGN_OR_RETURN_ERRNO(FileDescriptor fd, Open(Relpath(name), O_WRONLY)); + RETURN_ERROR_IF_SYSCALL_FAIL(WriteFd(fd.get(), value.c_str(), value.size())); + return NoError(); +} + +PosixError Cgroup::WriteIntegerControlFile(absl::string_view name, + int64_t value) const { + return WriteControlFile(name, absl::StrCat(value)); +} + PosixErrorOr<absl::flat_hash_set<pid_t>> Cgroup::Procs() const { ASSIGN_OR_RETURN_ERRNO(std::string buf, ReadControlFile("cgroup.procs")); return ParsePIDList(buf); diff --git a/test/util/cgroup_util.h b/test/util/cgroup_util.h index b049559df..c6e4303e1 100644 --- a/test/util/cgroup_util.h +++ b/test/util/cgroup_util.h @@ -45,6 +45,14 @@ class Cgroup { // to parse it as an integer. PosixErrorOr<int64_t> ReadIntegerControlFile(absl::string_view name) const; + // Writes a string to a cgroup control file. + PosixError WriteControlFile(absl::string_view name, + const std::string& value) const; + + // Writes an integer value to a cgroup control file. + PosixError WriteIntegerControlFile(absl::string_view name, + int64_t value) const; + // Returns the thread ids of the leaders of thread groups managed by this // cgroup. PosixErrorOr<absl::flat_hash_set<pid_t>> Procs() const; |