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 <tom.hroma...@oracle.com> --- 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 <tom.hroma...@oracle.com> + */ + +/* + * 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 Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel