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

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

Reply via email to