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

MatchChildFolder() - Compares a rule with a single-level hierarchy
    with a rule that matches that hierarchy

MatchGrandchildFolder() - Compares a rule with a multi-level hierarchy
    with a process that matches that hierachy

MatchSimilarChildFolder() - Compares a child folder that is similar
    to the rule.  This mimics a misconfiguration that a user could
    make

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

SimilarFolderNoMatch() - Compares a rule with a folder name that
   is similar to the process' cgroup, but not a match

RootDestinationMatch() - Compares a rule with the root as the
   destination and a process also running in the root cgroup

RootDestinationNoMatch() - Compares a rule with the root as the
   destination and a process in another cgroup folder

The results from googletest are reported below:

[----------] 13 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 (0 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.CombinedControllers
[       OK ] CgroupCompareIgnoreRuleTest.CombinedControllers (0 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.MatchChildFolder
[       OK ] CgroupCompareIgnoreRuleTest.MatchChildFolder (0 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.MatchGrandchildFolder
[       OK ] CgroupCompareIgnoreRuleTest.MatchGrandchildFolder (0 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.MatchSimilarChildFolder
[       OK ] CgroupCompareIgnoreRuleTest.MatchSimilarChildFolder (0 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.RealWorldMatch
[       OK ] CgroupCompareIgnoreRuleTest.RealWorldMatch (0 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.RealWorldNoMatch
[       OK ] CgroupCompareIgnoreRuleTest.RealWorldNoMatch (1 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.SimilarFolderNoMatch
[       OK ] CgroupCompareIgnoreRuleTest.SimilarFolderNoMatch (0 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.RootDestinationMatch
[       OK ] CgroupCompareIgnoreRuleTest.RootDestinationMatch (0 ms)
[ RUN      ] CgroupCompareIgnoreRuleTest.RootDestinationNoMatch
[       OK ] CgroupCompareIgnoreRuleTest.RootDestinationNoMatch (0 ms)
[----------] 13 tests from CgroupCompareIgnoreRuleTest (3 ms total)

Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
---
 src/api.c                                      |   2 +-
 src/libcgroup-internal.h                       |   3 +
 tests/gunit/004-cgroup_compare_ignore_rule.cpp | 340 +++++++++++++++++++++++++
 tests/gunit/Makefile.am                        |   3 +-
 4 files changed, 346 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 0cdd2a8c316f..3fbe1ed28e2f 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2879,7 +2879,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..f50f523d18d8
--- /dev/null
+++ b/tests/gunit/004-cgroup_compare_ignore_rule.cpp
@@ -0,0 +1,340 @@
+/**
+ * libcgroup googletest for cgroup_compare_ignore_rule()
+ *
+ * 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 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, MatchChildFolder)
+{
+       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, MatchGrandchildFolder)
+{
+       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);
+}
+
+/**
+ * This test is designed to highlight the case where the user has not put a
+ * trailing slash at the end of the rule's destination.  By design, this will
+ * cause the rule to match a wide variety of cases.
+ *
+ * For example, given the rule destination of "Folder".  The following
+ * behavior would be observed:
+ *     Process Location        Matches the rule?
+ *     Folder                  Yes
+ *     Folders                 Yes
+ *     Folder/AnotherFolder    Yes
+ *     Folder2                 Yes
+ *     Folder3/ChildFolder     Yes
+ *     Folde                   No
+ */
+TEST_F(CgroupCompareIgnoreRuleTest, MatchSimilarChildFolder)
+{
+       char proc_file_contents[] =
+               "1:hugetlb:/parentcg/childcg2";
+       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, SimilarFolderNoMatch)
+{
+       char proc_file_contents[] =
+               "4:memory:/folder1";
+       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, "folder/");
+
+       ret = cgroup_compare_ignore_rule(&rule, pid, procname);
+       ASSERT_EQ(ret, false);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, RootDestinationMatch)
+{
+       char proc_file_contents[] =
+               "2:freezer:/";
+       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, true);
+}
+
+TEST_F(CgroupCompareIgnoreRuleTest, RootDestinationNoMatch)
+{
+       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
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to