The following tests are in this commit:
ReadSingleLine() - Read a single valid line with a non-root controller
ReadSingleLine2() - Read a single valid line with a root controller
ReadEmptyController() - Some systems list a controller with no name.
This test simulates that scenario
ReadExampleFile() - Read several lines that are similar to a typical
/proc/{pid}/cgroups file
The results from googletest are reported below:
[----------] 4 tests from GetCgroupsFromProcCgroupsTest
[ RUN ] GetCgroupsFromProcCgroupsTest.ReadSingleLine
[ OK ] GetCgroupsFromProcCgroupsTest.ReadSingleLine (0 ms)
[ RUN ] GetCgroupsFromProcCgroupsTest.ReadSingleLine2
[ OK ] GetCgroupsFromProcCgroupsTest.ReadSingleLine2 (1 ms)
[ RUN ] GetCgroupsFromProcCgroupsTest.ReadEmptyController
[ OK ] GetCgroupsFromProcCgroupsTest.ReadEmptyController (0 ms)
[ RUN ] GetCgroupsFromProcCgroupsTest.ReadExampleFile
[ OK ] GetCgroupsFromProcCgroupsTest.ReadExampleFile (0 ms)
[----------] 4 tests from GetCgroupsFromProcCgroupsTest (1 ms total)
Signed-off-by: Tom Hromatka <[email protected]>
---
src/api.c | 6 +-
src/libcgroup-internal.h | 6 +
.../gunit/003-cg_get_cgroups_from_proc_cgroups.cpp | 175 +++++++++++++++++++++
tests/gunit/Makefile.am | 3 +-
4 files changed, 188 insertions(+), 2 deletions(-)
create mode 100644 tests/gunit/003-cg_get_cgroups_from_proc_cgroups.cpp
diff --git a/src/api.c b/src/api.c
index 105816a3ff51..be70fe05e890 100644
--- a/src/api.c
+++ b/src/api.c
@@ -4201,7 +4201,7 @@ int cgroup_get_uid_gid_from_procfs(pid_t pid, uid_t
*euid, gid_t *egid)
* of controllers
* @param list_len The size of the arrays
*/
-static int cg_get_cgroups_from_proc_cgroups(pid_t pid, char *cgroup_list[],
+STATIC int cg_get_cgroups_from_proc_cgroups(pid_t pid, char *cgroup_list[],
char *controller_list[],
int list_len)
{
@@ -4213,7 +4213,11 @@ static int cg_get_cgroups_from_proc_cgroups(pid_t pid,
char *cgroup_list[],
int idx = 0;
FILE *f;
+#ifdef UNIT_TEST
+ sprintf(path, "%s", TEST_PROC_PID_CGROUP_FILE);
+#else
sprintf(path, "/proc/%d/cgroup", pid);
+#endif
f = fopen(path, "re");
if (!f)
return ECGROUPNOTEXIST;
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
index b52c82c3f042..efe9b36fe052 100644
--- a/src/libcgroup-internal.h
+++ b/src/libcgroup-internal.h
@@ -294,9 +294,15 @@ int cg_chmod_path(const char *path, mode_t mode, int
owner_is_umask);
*/
#ifdef UNIT_TEST
+#define TEST_PROC_PID_CGROUP_FILE "test-procpidcgroup"
+
int cgroup_parse_rules_options(char *options,
struct cgroup_rule * const rule);
+int cg_get_cgroups_from_proc_cgroups(pid_t pid, char *cgroup_list[],
+ char *controller_list[],
+ int list_len);
+
#endif /* UNIT_TEST */
__END_DECLS
diff --git a/tests/gunit/003-cg_get_cgroups_from_proc_cgroups.cpp
b/tests/gunit/003-cg_get_cgroups_from_proc_cgroups.cpp
new file mode 100644
index 000000000000..0b4d28919b40
--- /dev/null
+++ b/tests/gunit/003-cg_get_cgroups_from_proc_cgroups.cpp
@@ -0,0 +1,175 @@
+/**
+ * libcgroup googletest for cg_get_cgroups_from_proc_cgroups()
+ *
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * Author: Tom Hromatka <[email protected]>
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include "gtest/gtest.h"
+
+#include "libcgroup-internal.h"
+
+class GetCgroupsFromProcCgroupsTest : public ::testing::Test {
+};
+
+static void CreateCgroupProcFile(const char * const contents)
+{
+ FILE *f;
+
+ f = fopen(TEST_PROC_PID_CGROUP_FILE, "w");
+ ASSERT_NE(f, nullptr);
+
+ fprintf(f, "%s", contents);
+ fclose(f);
+}
+
+
+TEST_F(GetCgroupsFromProcCgroupsTest, ReadSingleLine)
+{
+#undef LIST_LEN
+#define LIST_LEN 3
+ char contents[] =
+ "5:pids:/user.slice/user-1000.slice/session-1.scope\n";
+ char *controller_list[LIST_LEN];
+ char *cgroup_list[LIST_LEN];
+ pid_t pid = 1234;
+ int ret, i;
+
+ for (i = 0; i < LIST_LEN; i++) {
+ controller_list[i] = NULL;
+ cgroup_list[i] = NULL;
+ }
+
+ CreateCgroupProcFile(contents);
+
+ ret = cg_get_cgroups_from_proc_cgroups(pid, cgroup_list,
+ controller_list, LIST_LEN);
+ ASSERT_EQ(ret, 0);
+ ASSERT_STREQ(controller_list[0], "pids");
+ ASSERT_STREQ(cgroup_list[0],
+ "user.slice/user-1000.slice/session-1.scope");
+}
+
+TEST_F(GetCgroupsFromProcCgroupsTest, ReadSingleLine2)
+{
+#undef LIST_LEN
+#define LIST_LEN 1
+ char contents[] =
+ "5:cpu,cpuacct:/\n";
+ char *controller_list[LIST_LEN];
+ char *cgroup_list[LIST_LEN];
+ pid_t pid = 1234;
+ int ret, i;
+
+ for (i = 0; i < LIST_LEN; i++) {
+ controller_list[i] = NULL;
+ cgroup_list[i] = NULL;
+ }
+
+ CreateCgroupProcFile(contents);
+
+ ret = cg_get_cgroups_from_proc_cgroups(pid, cgroup_list,
+ controller_list, LIST_LEN);
+ ASSERT_EQ(ret, 0);
+ ASSERT_STREQ(controller_list[0], "cpu,cpuacct");
+ ASSERT_STREQ(cgroup_list[0], "/");
+}
+
+TEST_F(GetCgroupsFromProcCgroupsTest, ReadEmptyController)
+{
+#undef LIST_LEN
+#define LIST_LEN 1
+ char contents[] =
+ "0::/user.slice/user-1000.slice/session-1.scope\n";
+ char *controller_list[LIST_LEN];
+ char *cgroup_list[LIST_LEN];
+ pid_t pid = 1234;
+ int ret, i;
+
+ for (i = 0; i < LIST_LEN; i++) {
+ controller_list[i] = NULL;
+ cgroup_list[i] = NULL;
+ }
+
+ CreateCgroupProcFile(contents);
+
+ ret = cg_get_cgroups_from_proc_cgroups(pid, cgroup_list,
+ controller_list, LIST_LEN);
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(controller_list[0], nullptr);
+ ASSERT_EQ(cgroup_list[0], nullptr);
+}
+
+TEST_F(GetCgroupsFromProcCgroupsTest, ReadExampleFile)
+{
+ char contents[] =
+ "12:memory:/user/johndoe/0\n"
+ "11:perf_event:/\n"
+ "10:rdma:/\n"
+ "9:blkio:/user.slice\n"
+ "8:cpu,cpuacct:/myCgroup\n"
+ "7:freezer:/user/johndoe/0\n"
+ "6:net_cls,net_prio:/\n"
+ "5:pids:/user.slice/user-1000.slice/session-1.scope\n"
+ "4:devices:/user.slice\n"
+ "3:cpuset:/\n"
+ "2:hugetlb:/\n"
+ "1:name=systemd:/user.slice/user-1000.slice/session-1.scope\n"
+ "0::/user.slice/user-1000.slice/session-1.scope\n";
+ char *controller_list[MAX_MNT_ELEMENTS];
+ char *cgroup_list[MAX_MNT_ELEMENTS];
+ pid_t pid = 5678;
+ int ret, i;
+
+ for (i = 0; i < MAX_MNT_ELEMENTS; i++) {
+ controller_list[i] = NULL;
+ cgroup_list[i] = NULL;
+ }
+
+ CreateCgroupProcFile(contents);
+
+ ret = cg_get_cgroups_from_proc_cgroups(pid, cgroup_list,
+ controller_list, MAX_MNT_ELEMENTS);
+ ASSERT_EQ(ret, 0);
+ ASSERT_STREQ(controller_list[0], "memory");
+ ASSERT_STREQ(cgroup_list[0], "user/johndoe/0");
+ ASSERT_STREQ(controller_list[1], "perf_event");
+ ASSERT_STREQ(cgroup_list[1], "/");
+ ASSERT_STREQ(controller_list[2], "rdma");
+ ASSERT_STREQ(cgroup_list[2], "/");
+ ASSERT_STREQ(controller_list[3], "blkio");
+ ASSERT_STREQ(cgroup_list[3], "user.slice");
+ ASSERT_STREQ(controller_list[4], "cpu,cpuacct");
+ ASSERT_STREQ(cgroup_list[4], "myCgroup");
+ ASSERT_STREQ(controller_list[5], "freezer");
+ ASSERT_STREQ(cgroup_list[5], "user/johndoe/0");
+ ASSERT_STREQ(controller_list[6], "net_cls,net_prio");
+ ASSERT_STREQ(cgroup_list[6], "/");
+ ASSERT_STREQ(controller_list[7], "pids");
+ ASSERT_STREQ(cgroup_list[7],
"user.slice/user-1000.slice/session-1.scope");
+ ASSERT_STREQ(controller_list[8], "devices");
+ ASSERT_STREQ(cgroup_list[8], "user.slice");
+ ASSERT_STREQ(controller_list[9], "cpuset");
+ ASSERT_STREQ(cgroup_list[9], "/");
+ ASSERT_STREQ(controller_list[10], "hugetlb");
+ ASSERT_STREQ(cgroup_list[10], "/");
+ ASSERT_STREQ(controller_list[11], "name=systemd");
+ ASSERT_STREQ(cgroup_list[11],
"user.slice/user-1000.slice/session-1.scope");
+
+ ASSERT_EQ(controller_list[12], nullptr);
+ ASSERT_EQ(cgroup_list[12], nullptr);
+}
diff --git a/tests/gunit/Makefile.am b/tests/gunit/Makefile.am
index f3fe400b3218..85050d2b7cff 100644
--- a/tests/gunit/Makefile.am
+++ b/tests/gunit/Makefile.am
@@ -40,4 +40,5 @@ TESTS = gtest
gtest_SOURCES = gtest.cpp \
001-path.cpp \
- 002-cgroup_parse_rules_options.cpp
+ 002-cgroup_parse_rules_options.cpp \
+ 003-cg_get_cgroups_from_proc_cgroups.cpp
--
1.8.3.1
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel