summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authord0u9 <d0u9.su@outlook.com>2018-03-23 21:21:11 +0800
committerThomas Haller <thaller@redhat.com>2018-06-25 14:39:41 +0200
commitddfc36f46e2d1581e2b08bbe167644bd8b1f1571 (patch)
treeed21ede97a53822c1086701c3d79b59adc7018a6 /tests
parent3ebb0ea66b165d061c287164ca4514c13f8b2772 (diff)
downloadlibnl-ddfc36f46e2d1581e2b08bbe167644bd8b1f1571.tar.gz
Add support for cloning cgroup filter object.
In this commit, we implement ematch_tree_clone(), which is basis of cgroup_clone() interface. The whole ematch tree is deep-copied except the e_ops filed. Also, a new unit test is added for testing the interface, which named as check-ematch-tree-clone.c located in tests directory. https://github.com/thom311/libnl/pull/176
Diffstat (limited to 'tests')
-rw-r--r--tests/check-all.c1
-rw-r--r--tests/check-ematch-tree-clone.c143
-rw-r--r--tests/util.h1
3 files changed, 145 insertions, 0 deletions
diff --git a/tests/check-all.c b/tests/check-all.c
index 042452dd..7b738daa 100644
--- a/tests/check-all.c
+++ b/tests/check-all.c
@@ -31,6 +31,7 @@ int main(int argc, char *argv[])
srunner_add_suite(runner, make_nl_addr_suite());
srunner_add_suite(runner, make_nl_attr_suite());
+ srunner_add_suite(runner, make_nl_ematch_tree_clone_suite());
/* Do not add testsuites below this line */
diff --git a/tests/check-ematch-tree-clone.c b/tests/check-ematch-tree-clone.c
new file mode 100644
index 00000000..9c35c52e
--- /dev/null
+++ b/tests/check-ematch-tree-clone.c
@@ -0,0 +1,143 @@
+#include <netlink-private/types.h>
+#include <netlink/route/cls/ematch.h>
+
+#include <linux/netlink.h>
+
+#include <stdio.h>
+#include <time.h>
+
+#include <check.h>
+#include "util.h"
+
+#define MAX_DEPTH 6
+#define MAX_CHILDREN 5
+
+static int current_depth = 0;
+static int id = 1;
+static long long array_size = 0;
+
+static int *src_result = NULL, *dst_result = NULL;
+
+static long long my_pow(long long x, long long y)
+{
+ int ret = x;
+
+ if (y == 0)
+ return 1;
+
+ if (y < 0 || x == 0)
+ return 0;
+
+ while(--y) {
+ ret *= x;
+ }
+
+ return ret;
+}
+
+static long int generate_random(long int max)
+{
+ srandom(time(NULL) + id);
+ return (random() % max);
+}
+
+static int build_children(struct nl_list_head *parent)
+{
+ int i, num = 0;
+ struct rtnl_ematch *child = NULL;
+
+ if (!parent)
+ return 0;
+
+ if (++current_depth > MAX_DEPTH) {
+ --current_depth;
+ return 0;
+ }
+
+ num = generate_random(MAX_CHILDREN + 1);
+ for (i = 0; i < num; ++i) {
+ child = rtnl_ematch_alloc();
+ if (!child) {
+ printf("Mem alloc error\n");
+ exit(1);
+ }
+ build_children(&child->e_childs);
+ child->e_id = id++;
+ nl_list_add_tail(&child->e_list, parent);
+ }
+
+ --current_depth;
+ return 0;
+}
+
+static void build_src_cgroup(struct rtnl_ematch_tree *tree)
+{
+ build_children(&tree->et_list);
+}
+
+static void dump_ematch_list(struct nl_list_head *head, int *result, int *index)
+{
+ struct rtnl_ematch *pos = NULL;
+
+ nl_list_for_each_entry(pos, head, e_list) {
+ if (!nl_list_empty(&pos->e_childs))
+ dump_ematch_list(&pos->e_childs, result, index);
+ result[*index] = pos->e_id;
+ (*index)++;
+ }
+}
+
+static void dump_ematch_tree(struct rtnl_ematch_tree *tree, int *result, int *index)
+{
+ if (!tree)
+ return;
+
+ dump_ematch_list(&tree->et_list, result, index);
+}
+
+static int compare(int *r1, int *r2, int len)
+{
+ int i = 0;
+ for (i = 0; i < len; ++i) {
+ if (r1[i] != r2[i])
+ return -1;
+ }
+ return 0;
+}
+
+START_TEST(ematch_tree_clone)
+{
+ struct rtnl_ematch_tree *src = NULL, *dst = NULL;
+ int i = 0, j = 0;
+
+ array_size = (MAX_DEPTH * my_pow(MAX_CHILDREN, MAX_DEPTH)) / 2;
+ src_result = calloc(4, array_size);
+ dst_result = calloc(4, array_size);
+
+ src = rtnl_ematch_tree_alloc(2);
+
+ build_src_cgroup(src);
+ dump_ematch_tree(src, src_result, &i);
+
+ dst = rtnl_ematch_tree_clone(src);
+ dump_ematch_tree(dst, dst_result, &j);
+
+ fail_if(!dst);
+ fail_if(i != j);
+ fail_if(compare(src_result, dst_result, i));
+
+ free(src_result);
+ free(dst_result);
+}
+END_TEST
+
+Suite *make_nl_ematch_tree_clone_suite(void)
+{
+ Suite *suite = suite_create("Clone ematch tree");
+
+ TCase *ematch_tree = tcase_create("Core");
+ tcase_add_test(ematch_tree, ematch_tree_clone);
+ suite_add_tcase(suite, ematch_tree);
+
+ return suite;
+}
diff --git a/tests/util.h b/tests/util.h
index cd383ef8..8c9acf12 100644
--- a/tests/util.h
+++ b/tests/util.h
@@ -6,4 +6,5 @@
Suite *make_nl_attr_suite(void);
Suite *make_nl_addr_suite(void);
+Suite *make_nl_ematch_tree_clone_suite(void);