The following tests are in this commit:
NotAnIgnore() - Test that non-ignore rules are not processed
SimpleMatch() - Test that an ignore rule with a matching cgroup
and controller match
CgroupsDontMatch() - Test that cgroups with similar but not matching
names do not match
ControllersDontMatch() - Test that controllers with non-matching
names do not match
CombinedControllers() - Test that controllers that have been mounted
on the same path, e.g. cpu,cpuacct, can be matched by a rule
WildcardMatch() - Test that rules with a wildcarded destination, e.g.
parentcg/*, can match a process in a nested cgroup
WildcardMatch2() - Another test that a wildcarded destination can
match a process in a nested cgroup
RealWorldMatch() - Test that a realistic cgroup proc file matches
a new process
RealWorldNoMatch() - Test that a realistic cgroup proc file will
not match a new process
WildcardDestinationWithSlash - Test that a destination specified
as SomeCgroup/* matches
RootDestinationWithWildcard - Test that the erroneous configuration
"/*" does not match
The results from googletest are reported below:
[----------] 11 tests from CgroupCompareIgnoreRuleTest
[ RUN ] CgroupCompareIgnoreRuleTest.NotAnIgnore
[ OK ] CgroupCompareIgnoreRuleTest.NotAnIgnore (0 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.SimpleMatch
[ OK ] CgroupCompareIgnoreRuleTest.SimpleMatch (0 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.CgroupsDontMatch
[ OK ] CgroupCompareIgnoreRuleTest.CgroupsDontMatch (0 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.ControllersDontMatch
[ OK ] CgroupCompareIgnoreRuleTest.ControllersDontMatch (1 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.CombinedControllers
[ OK ] CgroupCompareIgnoreRuleTest.CombinedControllers (0 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.WildcardMatch
[ OK ] CgroupCompareIgnoreRuleTest.WildcardMatch (0 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.WildcardMatch2
[ OK ] CgroupCompareIgnoreRuleTest.WildcardMatch2 (0 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.RealWorldMatch
[ OK ] CgroupCompareIgnoreRuleTest.RealWorldMatch (0 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.RealWorldNoMatch
[ OK ] CgroupCompareIgnoreRuleTest.RealWorldNoMatch (1 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.WildcardDestinationWithSlash
[ OK ] CgroupCompareIgnoreRuleTest.WildcardDestinationWithSlash (0 ms)
[ RUN ] CgroupCompareIgnoreRuleTest.RootDestinationWithWildcard
[ OK ] CgroupCompareIgnoreRuleTest.RootDestinationWithWildcard (0 ms)
[----------] 11 tests from CgroupCompareIgnoreRuleTest (2 ms total)
Signed-off-by: Tom Hromatka <[email protected]>
---
src/api.c | 2 +-
src/libcgroup-internal.h | 3 +
tests/gunit/004-cgroup_compare_ignore_rule.cpp | 292 +++++++++++++++++++++++++
tests/gunit/Makefile.am | 3 +-
4 files changed, 298 insertions(+), 2 deletions(-)
create mode 100644 tests/gunit/004-cgroup_compare_ignore_rule.cpp
diff --git a/src/api.c b/src/api.c
index b8749c887e44..a1cd035827fa 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2889,7 +2889,7 @@ static int cgroup_find_matching_controller(char * const
*rule_controllers,
* @return True if the rule is an ignore rule and this pid/procname
* match the rule. False otherwise
*/
-static bool cgroup_compare_ignore_rule(const struct cgroup_rule * const rule,
+STATIC bool cgroup_compare_ignore_rule(const struct cgroup_rule * const rule,
pid_t pid, const char * const procname)
{
char *controller_list[MAX_MNT_ELEMENTS] = { '\0' };
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
index efe9b36fe052..c827fea28d35 100644
--- a/src/libcgroup-internal.h
+++ b/src/libcgroup-internal.h
@@ -303,6 +303,9 @@ int cg_get_cgroups_from_proc_cgroups(pid_t pid, char
*cgroup_list[],
char *controller_list[],
int list_len);
+bool cgroup_compare_ignore_rule(const struct cgroup_rule * const rule,
+ pid_t pid, const char * const procname);
+
#endif /* UNIT_TEST */
__END_DECLS
diff --git a/tests/gunit/004-cgroup_compare_ignore_rule.cpp
b/tests/gunit/004-cgroup_compare_ignore_rule.cpp
new file mode 100644
index 000000000000..61d28085bee4
--- /dev/null
+++ b/tests/gunit/004-cgroup_compare_ignore_rule.cpp
@@ -0,0 +1,292 @@
+/**
+ * libcgroup googletest for cgroup_compare_ignore_rule()
+ *
+ * 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 CgroupCompareIgnoreRuleTest : 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(CgroupCompareIgnoreRuleTest, NotAnIgnore)
+{
+ char procname[] = "myprocess";
+ struct cgroup_rule rule;
+ pid_t pid = 1234;
+ bool ret;
+
+ rule.is_ignore = false;
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, false);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, SimpleMatch)
+{
+ char proc_file_contents[] =
+ "7:cpuacct:/SimpleMatchCgroup";
+ char rule_controller[] = "cpuacct";
+ char procname[] = "procfoo";
+ struct cgroup_rule rule;
+ pid_t pid = 2345;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.procname = NULL;
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "SimpleMatchCgroup");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, true);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, CgroupsDontMatch)
+{
+ char proc_file_contents[] =
+ "2:cpuacct:CloseButNotQuite";
+ char rule_controller[] = "cpuacct";
+ char procname[] = "procfoo2";
+ struct cgroup_rule rule;
+ pid_t pid = 4567;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "CloseButNotQuit");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, false);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, ControllersDontMatch)
+{
+ char proc_file_contents[] =
+ "5:memory:MyCgroup";
+ char rule_controller[] = "cpuacct";
+ char procname[] = "procfoo3";
+ struct cgroup_rule rule;
+ pid_t pid = 5678;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "MyCgroup");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, false);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, CombinedControllers)
+{
+ char proc_file_contents[] =
+ "13:cpu,cpuacct:/containercg";
+ char rule_controller[] = "cpuacct";
+ char procname[] = "docker";
+ struct cgroup_rule rule;
+ pid_t pid = 6789;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ rule.controllers[1] = NULL;
+ sprintf(rule.destination, "containercg");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, true);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, WildcardMatch)
+{
+ char proc_file_contents[] =
+ "7:cpuset:/parentcg/childcg/grandchildcg";
+ char rule_controller[] = "cpuset";
+ char procname[] = "childprocess";
+ struct cgroup_rule rule;
+ pid_t pid = 7890;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.procname = procname;
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "parentcg/*");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, true);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, WildcardMatch2)
+{
+ char proc_file_contents[] =
+ "1:hugetlb:/parentcg/childcg/grandchildcg";
+ char rule_controller[] = "hugetlb";
+ char procname[] = "granchildprocess";
+ struct cgroup_rule rule;
+ pid_t pid = 8901;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.procname = NULL;
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "parentcg/childcg*");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, true);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, RealWorldMatch)
+{
+ char proc_file_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 rule_controller[] = "cpu";
+ char procname[] = "granchildprocess";
+ struct cgroup_rule rule;
+ pid_t pid = 8901;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.procname = NULL;
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "myCgroup*");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, true);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, RealWorldNoMatch)
+{
+ char proc_file_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:/NetCgroup\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 rule_controller[] = "net_cls";
+ char procname[] = "NotMatching";
+ struct cgroup_rule rule;
+ pid_t pid = 9012;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.procname = NULL;
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "NetCgroup2");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, false);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, WildcardDestinationWithSlash)
+{
+ char proc_file_contents[] =
+ "4:memory:/parentcg";
+ char rule_controller[] = "memory";
+ char procname[] = "childprocess";
+ struct cgroup_rule rule;
+ pid_t pid = 2345;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.procname = procname;
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "parentcg/*");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, true);
+}
+
+/*
+ * This tests an invalid configuration that could be an easy user mistake
+ *
+ * <user> <controllers> <destination> <options>
+ * * cpuset /* ignore
+ *
+ * In reality, the user really wanted:
+ * * cpuset * ignore
+ */
+TEST_F(CgroupCompareIgnoreRuleTest, RootDestinationWithWildcard)
+{
+ char proc_file_contents[] =
+ "2:freezer:/somerandomcg";
+ char rule_controller[] = "freezer";
+ char procname[] = "ANewProcess";
+ struct cgroup_rule rule;
+ pid_t pid = 3456;
+ bool ret;
+
+ CreateCgroupProcFile(proc_file_contents);
+
+ rule.procname = procname;
+ rule.is_ignore = true;
+ rule.controllers[0] = rule_controller;
+ sprintf(rule.destination, "/*");
+
+ ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+ ASSERT_EQ(ret, false);
+}
diff --git a/tests/gunit/Makefile.am b/tests/gunit/Makefile.am
index 85050d2b7cff..ff2630644044 100644
--- a/tests/gunit/Makefile.am
+++ b/tests/gunit/Makefile.am
@@ -41,4 +41,5 @@ TESTS = gtest
gtest_SOURCES = gtest.cpp \
001-path.cpp \
002-cgroup_parse_rules_options.cpp \
- 003-cg_get_cgroups_from_proc_cgroups.cpp
+ 003-cg_get_cgroups_from_proc_cgroups.cpp \
+ 004-cgroup_compare_ignore_rule.cpp
--
1.8.3.1
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel