summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test-dns-domain.c66
-rw-r--r--src/test/test-engine.c5
-rw-r--r--src/test/test-execute.c5
-rw-r--r--src/test/test-helper.h12
-rw-r--r--src/test/test-path.c5
-rw-r--r--src/test/test-rbtree.c362
-rw-r--r--src/test/test-rlimit-util.c69
-rw-r--r--src/test/test-sched-prio.c5
8 files changed, 512 insertions, 17 deletions
diff --git a/src/test/test-dns-domain.c b/src/test/test-dns-domain.c
index f010e4e19a..de003e251c 100644
--- a/src/test/test-dns-domain.c
+++ b/src/test/test-dns-domain.c
@@ -39,7 +39,7 @@ static void test_dns_label_unescape_one(const char *what, const char *expect, si
static void test_dns_label_unescape(void) {
test_dns_label_unescape_one("hallo", "hallo", 6, 5);
- test_dns_label_unescape_one("hallo", "hallo", 4, -ENOSPC);
+ test_dns_label_unescape_one("hallo", "hallo", 4, -ENOBUFS);
test_dns_label_unescape_one("", "", 10, 0);
test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12);
test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5);
@@ -56,7 +56,7 @@ static void test_dns_name_to_wire_format_one(const char *what, const char *expec
uint8_t buffer[buffer_sz];
int r;
- r = dns_name_to_wire_format(what, buffer, buffer_sz);
+ r = dns_name_to_wire_format(what, buffer, buffer_sz, false);
assert_se(r == ret);
if (r < 0)
@@ -66,11 +66,38 @@ static void test_dns_name_to_wire_format_one(const char *what, const char *expec
}
static void test_dns_name_to_wire_format(void) {
- const char out1[] = { 3, 'f', 'o', 'o', 0 };
- const char out2[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
- const char out3[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
-
- test_dns_name_to_wire_format_one("", NULL, 0, -EINVAL);
+ static const char out0[] = { 0 };
+ static const char out1[] = { 3, 'f', 'o', 'o', 0 };
+ static const char out2[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
+ static const char out3[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
+ static const char out4[] = { 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
+ 3, 'a', '1', '2', 0 };
+
+ test_dns_name_to_wire_format_one("", out0, sizeof(out0), sizeof(out0));
test_dns_name_to_wire_format_one("foo", out1, sizeof(out1), sizeof(out1));
test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) + 1, sizeof(out1));
@@ -80,6 +107,9 @@ static void test_dns_name_to_wire_format(void) {
test_dns_name_to_wire_format_one("hallo.foo..bar", NULL, 32, -EINVAL);
test_dns_name_to_wire_format_one("\\032foo.bar", out3, sizeof(out3), sizeof(out3));
+
+ test_dns_name_to_wire_format_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", NULL, 500, -EINVAL);
+ test_dns_name_to_wire_format_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", out4, sizeof(out4), sizeof(out4));
}
static void test_dns_label_unescape_suffix_one(const char *what, const char *expect1, const char *expect2, size_t buffer_sz, int ret1, int ret2) {
@@ -102,7 +132,7 @@ static void test_dns_label_unescape_suffix_one(const char *what, const char *exp
static void test_dns_label_unescape_suffix(void) {
test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
- test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOSPC, -ENOSPC);
+ test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOBUFS, -ENOBUFS);
test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
@@ -136,7 +166,7 @@ static void test_dns_label_escape_one(const char *what, size_t l, const char *ex
}
static void test_dns_label_escape(void) {
- test_dns_label_escape_one("", 0, "", 0);
+ test_dns_label_escape_one("", 0, NULL, -EINVAL);
test_dns_label_escape_one("hallo", 5, "hallo", 5);
test_dns_label_escape_one("hallo", 6, NULL, -EINVAL);
test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
@@ -314,6 +344,24 @@ static void test_dns_name_is_valid(void) {
test_dns_name_is_valid_one("\\zbar", 0);
test_dns_name_is_valid_one("รค", 1);
test_dns_name_is_valid_one("\n", 0);
+
+ /* 256 characters*/
+ test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345", 0);
+
+ /* 255 characters*/
+ test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a1234", 0);
+
+ /* 254 characters*/
+ test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", 0);
+
+ /* 253 characters*/
+ test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", 1);
+
+ /* label of 64 chars length */
+ test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a123", 0);
+
+ /* label of 63 chars length */
+ test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a12", 1);
}
static void test_dns_service_name_is_valid(void) {
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
index c98d01168c..e23eec7370 100644
--- a/src/test/test-engine.c
+++ b/src/test/test-engine.c
@@ -25,6 +25,7 @@
#include "bus-util.h"
#include "manager.h"
+#include "test-helper.h"
int main(int argc, char *argv[]) {
_cleanup_(sd_bus_error_free) sd_bus_error err = SD_BUS_ERROR_NULL;
@@ -38,8 +39,8 @@ int main(int argc, char *argv[]) {
/* prepare the test */
assert_se(set_unit_path(TEST_DIR) >= 0);
r = manager_new(MANAGER_USER, true, &m);
- if (IN_SET(r, -EPERM, -EACCES, -EADDRINUSE, -EHOSTDOWN, -ENOENT, -ENOEXEC)) {
- printf("Skipping test: manager_new: %s", strerror(-r));
+ if (MANAGER_SKIP_TEST(r)) {
+ printf("Skipping test: manager_new: %s\n", strerror(-r));
return EXIT_TEST_SKIP;
}
assert_se(r >= 0);
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index 03ec0fcfc7..753afadb0a 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -29,6 +29,7 @@
#include "mkdir.h"
#include "path-util.h"
#include "rm-rf.h"
+#include "test-helper.h"
#include "unit.h"
#include "util.h"
@@ -296,8 +297,8 @@ int main(int argc, char *argv[]) {
assert_se(unsetenv("VAR3") == 0);
r = manager_new(MANAGER_USER, true, &m);
- if (IN_SET(r, -EPERM, -EACCES, -EADDRINUSE, -EHOSTDOWN, -ENOENT)) {
- printf("Skipping test: manager_new: %s", strerror(-r));
+ if (MANAGER_SKIP_TEST(r)) {
+ printf("Skipping test: manager_new: %s\n", strerror(-r));
return EXIT_TEST_SKIP;
}
assert_se(r >= 0);
diff --git a/src/test/test-helper.h b/src/test/test-helper.h
index f75dd3374a..c0f6a91787 100644
--- a/src/test/test-helper.h
+++ b/src/test/test-helper.h
@@ -23,9 +23,21 @@
#include "sd-daemon.h"
+#include "macro.h"
+
#define TEST_REQ_RUNNING_SYSTEMD(x) \
if (sd_booted() > 0) { \
x; \
} else { \
printf("systemd not booted skipping '%s'\n", #x); \
}
+
+#define MANAGER_SKIP_TEST(r) \
+ IN_SET(r, \
+ -EPERM, \
+ -EACCES, \
+ -EADDRINUSE, \
+ -EHOSTDOWN, \
+ -ENOENT, \
+ -ENOMEDIUM /* cannot determine cgroup */ \
+ )
diff --git a/src/test/test-path.c b/src/test/test-path.c
index 8302bdd283..7a3b145414 100644
--- a/src/test/test-path.c
+++ b/src/test/test-path.c
@@ -29,6 +29,7 @@
#include "rm-rf.h"
#include "string-util.h"
#include "strv.h"
+#include "test-helper.h"
#include "unit.h"
#include "util.h"
@@ -44,8 +45,8 @@ static int setup_test(Manager **m) {
assert_se(m);
r = manager_new(MANAGER_USER, true, &tmp);
- if (IN_SET(r, -EPERM, -EACCES, -EADDRINUSE, -EHOSTDOWN, -ENOENT, -ENOEXEC)) {
- printf("Skipping test: manager_new: %s", strerror(-r));
+ if (MANAGER_SKIP_TEST(r)) {
+ printf("Skipping test: manager_new: %s\n", strerror(-r));
return -EXIT_TEST_SKIP;
}
assert_se(r >= 0);
diff --git a/src/test/test-rbtree.c b/src/test/test-rbtree.c
new file mode 100644
index 0000000000..8ae416c557
--- /dev/null
+++ b/src/test/test-rbtree.c
@@ -0,0 +1,362 @@
+/***
+ This file is part of systemd. See COPYING for details.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Tests for RB-Tree
+ */
+
+#undef NDEBUG
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include "c-rbtree.h"
+
+/* verify that all API calls are exported */
+static void test_api(void) {
+ CRBTree t = {};
+ CRBNode n = C_RBNODE_INIT(n);
+
+ assert(!c_rbnode_is_linked(&n));
+
+ /* init, is_linked, add, remove, remove_init */
+
+ c_rbtree_add(&t, NULL, &t.root, &n);
+ assert(c_rbnode_is_linked(&n));
+
+ c_rbtree_remove_init(&t, &n);
+ assert(!c_rbnode_is_linked(&n));
+
+ c_rbtree_add(&t, NULL, &t.root, &n);
+ assert(c_rbnode_is_linked(&n));
+
+ c_rbtree_remove(&t, &n);
+ assert(c_rbnode_is_linked(&n)); /* @n wasn't touched */
+
+ c_rbnode_init(&n);
+ assert(!c_rbnode_is_linked(&n));
+
+ /* first, last, leftmost, rightmost, next, prev */
+
+ assert(!c_rbtree_first(&t));
+ assert(!c_rbtree_last(&t));
+ assert(&n == c_rbnode_leftmost(&n));
+ assert(&n == c_rbnode_rightmost(&n));
+ assert(!c_rbnode_next(&n));
+ assert(!c_rbnode_prev(&n));
+}
+
+/* copied from c-rbtree.c, relies on internal representation */
+static inline _Bool c_rbnode_is_red(CRBNode *n) {
+ return !((unsigned long)n->__parent_and_color & 1UL);
+}
+
+/* copied from c-rbtree.c, relies on internal representation */
+static inline _Bool c_rbnode_is_black(CRBNode *n) {
+ return !!((unsigned long)n->__parent_and_color & 1UL);
+}
+
+static size_t validate(CRBTree *t) {
+ unsigned int i_black, n_black;
+ CRBNode *n, *p, *o;
+ size_t count = 0;
+
+ assert(t);
+ assert(!t->root || c_rbnode_is_black(t->root));
+
+ /* traverse to left-most child, count black nodes */
+ i_black = 0;
+ n = t->root;
+ while (n && n->left) {
+ if (c_rbnode_is_black(n))
+ ++i_black;
+ n = n->left;
+ }
+ n_black = i_black;
+
+ /*
+ * Traverse tree and verify correctness:
+ * 1) A node is either red or black
+ * 2) The root is black
+ * 3) All leaves are black
+ * 4) Every red node must have two black child nodes
+ * 5) Every path to a leaf contains the same number of black nodes
+ *
+ * Note that NULL nodes are considered black, which is why we don't
+ * check for 3).
+ */
+ o = NULL;
+ while (n) {
+ ++count;
+
+ /* verify natural order */
+ assert(n > o);
+ o = n;
+
+ /* verify consistency */
+ assert(!n->right || c_rbnode_parent(n->right) == n);
+ assert(!n->left || c_rbnode_parent(n->left) == n);
+
+ /* verify 2) */
+ if (!c_rbnode_parent(n))
+ assert(c_rbnode_is_black(n));
+
+ if (c_rbnode_is_red(n)) {
+ /* verify 4) */
+ assert(!n->left || c_rbnode_is_black(n->left));
+ assert(!n->right || c_rbnode_is_black(n->right));
+ } else {
+ /* verify 1) */
+ assert(c_rbnode_is_black(n));
+ }
+
+ /* verify 5) */
+ if (!n->left && !n->right)
+ assert(i_black == n_black);
+
+ /* get next node */
+ if (n->right) {
+ n = n->right;
+ if (c_rbnode_is_black(n))
+ ++i_black;
+
+ while (n->left) {
+ n = n->left;
+ if (c_rbnode_is_black(n))
+ ++i_black;
+ }
+ } else {
+ while ((p = c_rbnode_parent(n)) && n == p->right) {
+ n = p;
+ if (c_rbnode_is_black(p->right))
+ --i_black;
+ }
+
+ n = p;
+ if (p && c_rbnode_is_black(p->left))
+ --i_black;
+ }
+ }
+
+ return count;
+}
+
+static void insert(CRBTree *t, CRBNode *n) {
+ CRBNode **i, *p;
+
+ assert(t);
+ assert(n);
+ assert(!c_rbnode_is_linked(n));
+
+ i = &t->root;
+ p = NULL;
+ while (*i) {
+ p = *i;
+ if (n < *i) {
+ i = &(*i)->left;
+ } else {
+ assert(n > *i);
+ i = &(*i)->right;
+ }
+ }
+
+ c_rbtree_add(t, p, i, n);
+}
+
+static void shuffle(void **nodes, size_t n_memb) {
+ unsigned int i, j;
+ void *t;
+
+ for (i = 0; i < n_memb; ++i) {
+ j = rand() % n_memb;
+ t = nodes[j];
+ nodes[j] = nodes[i];
+ nodes[i] = t;
+ }
+}
+
+/* run some pseudo-random tests on the tree */
+static void test_shuffle(void) {
+ CRBNode *nodes[256];
+ CRBTree t = {};
+ unsigned int i, j;
+ size_t n;
+
+ /* allocate and initialize all nodes */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
+ nodes[i] = malloc(sizeof(*nodes[i]));
+ assert(nodes[i]);
+ c_rbnode_init(nodes[i]);
+ }
+
+ /* shuffle nodes and validate *empty* tree */
+ shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
+ n = validate(&t);
+ assert(n == 0);
+
+ /* add all nodes and validate after each insertion */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
+ insert(&t, nodes[i]);
+ n = validate(&t);
+ assert(n == i + 1);
+ }
+
+ /* shuffle nodes again */
+ shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
+
+ /* remove all nodes (in different order) and validate on each round */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
+ c_rbtree_remove(&t, nodes[i]);
+ n = validate(&t);
+ assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
+ c_rbnode_init(nodes[i]);
+ }
+
+ /* shuffle nodes and validate *empty* tree again */
+ shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
+ n = validate(&t);
+ assert(n == 0);
+
+ /* add all nodes again */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
+ insert(&t, nodes[i]);
+ n = validate(&t);
+ assert(n == i + 1);
+ }
+
+ /* 4 times, remove half of the nodes and add them again */
+ for (j = 0; j < 4; ++j) {
+ /* shuffle nodes again */
+ shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
+
+ /* remove half of the nodes */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes) / 2; ++i) {
+ c_rbtree_remove(&t, nodes[i]);
+ n = validate(&t);
+ assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
+ c_rbnode_init(nodes[i]);
+ }
+
+ /* shuffle the removed half */
+ shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes) / 2);
+
+ /* add the removed half again */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes) / 2; ++i) {
+ insert(&t, nodes[i]);
+ n = validate(&t);
+ assert(n == sizeof(nodes) / sizeof(*nodes) / 2 + i + 1);
+ }
+ }
+
+ /* shuffle nodes again */
+ shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
+
+ /* remove all */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
+ c_rbtree_remove(&t, nodes[i]);
+ n = validate(&t);
+ assert(n == sizeof(nodes) / sizeof(*nodes) - i - 1);
+ c_rbnode_init(nodes[i]);
+ }
+
+ /* free nodes again */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i)
+ free(nodes[i]);
+}
+
+typedef struct {
+ unsigned long key;
+ CRBNode rb;
+} Node;
+
+#define node_from_rb(_rb) ((Node *)((char *)(_rb) - offsetof(Node, rb)))
+
+static int compare(CRBTree *t, void *k, CRBNode *n) {
+ unsigned long key = (unsigned long)k;
+ Node *node = node_from_rb(n);
+
+ return (key < node->key) ? -1 : (key > node->key) ? 1 : 0;
+}
+
+/* run tests against the c_rbtree_find*() helpers */
+static void test_map(void) {
+ CRBNode **slot, *p;
+ CRBTree t = {};
+ Node *nodes[2048];
+ unsigned long i;
+
+ /* allocate and initialize all nodes */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
+ nodes[i] = malloc(sizeof(*nodes[i]));
+ assert(nodes[i]);
+ nodes[i]->key = i;
+ c_rbnode_init(&nodes[i]->rb);
+ }
+
+ /* shuffle nodes */
+ shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
+
+ /* add all nodes, and verify that each node is linked */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
+ assert(!c_rbnode_is_linked(&nodes[i]->rb));
+ assert(!c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
+
+ slot = c_rbtree_find_slot(&t, compare, (void *)nodes[i]->key, &p);
+ assert(slot);
+ c_rbtree_add(&t, p, slot, &nodes[i]->rb);
+
+ assert(c_rbnode_is_linked(&nodes[i]->rb));
+ assert(nodes[i] == c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
+ }
+
+ /* shuffle nodes again */
+ shuffle((void **)nodes, sizeof(nodes) / sizeof(*nodes));
+
+ /* remove all nodes (in different order) */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i) {
+ assert(c_rbnode_is_linked(&nodes[i]->rb));
+ assert(nodes[i] == c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
+
+ c_rbtree_remove_init(&t, &nodes[i]->rb);
+
+ assert(!c_rbnode_is_linked(&nodes[i]->rb));
+ assert(!c_rbtree_find_entry(&t, compare, (void *)nodes[i]->key, Node, rb));
+ }
+
+ /* free nodes again */
+ for (i = 0; i < sizeof(nodes) / sizeof(*nodes); ++i)
+ free(nodes[i]);
+}
+
+int main(int argc, char **argv) {
+ unsigned int i;
+
+ /* we want stable tests, so use fixed seed */
+ srand(0xdeadbeef);
+
+ test_api();
+
+ /*
+ * The tests are pseudo random; run them multiple times, each run will
+ * have different orders and thus different results.
+ */
+ for (i = 0; i < 4; ++i) {
+ test_shuffle();
+ test_map();
+ }
+
+ return 0;
+}
diff --git a/src/test/test-rlimit-util.c b/src/test/test-rlimit-util.c
new file mode 100644
index 0000000000..00d3ecc0de
--- /dev/null
+++ b/src/test/test-rlimit-util.c
@@ -0,0 +1,69 @@
+/***
+ This file is part of systemd
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/resource.h>
+
+#include "capability-util.h"
+#include "macro.h"
+#include "rlimit-util.h"
+#include "string-util.h"
+#include "util.h"
+
+int main(int argc, char *argv[]) {
+ struct rlimit old, new, high;
+ struct rlimit err = {
+ .rlim_cur = 10,
+ .rlim_max = 5,
+ };
+
+ log_parse_environment();
+ log_open();
+
+ assert_se(drop_capability(CAP_SYS_RESOURCE) == 0);
+
+ assert_se(getrlimit(RLIMIT_NOFILE, &old) == 0);
+ new.rlim_cur = MIN(5U, old.rlim_max);
+ new.rlim_max = MIN(10U, old.rlim_max);
+ assert_se(setrlimit(RLIMIT_NOFILE, &new) >= 0);
+
+ assert_se(rlimit_from_string("LimitNOFILE") == RLIMIT_NOFILE);
+ assert_se(rlimit_from_string("DefaultLimitNOFILE") == -1);
+
+ assert_se(streq_ptr(rlimit_to_string(RLIMIT_NOFILE), "LimitNOFILE"));
+ assert_se(rlimit_to_string(-1) == NULL);
+
+ assert_se(getrlimit(RLIMIT_NOFILE, &old) == 0);
+ assert_se(setrlimit_closest(RLIMIT_NOFILE, &old) == 0);
+ assert_se(getrlimit(RLIMIT_NOFILE, &new) == 0);
+ assert_se(old.rlim_cur == new.rlim_cur);
+ assert_se(old.rlim_max == new.rlim_max);
+
+ assert_se(getrlimit(RLIMIT_NOFILE, &old) == 0);
+ high = RLIMIT_MAKE_CONST(old.rlim_max + 1);
+ assert_se(setrlimit_closest(RLIMIT_NOFILE, &high) == 0);
+ assert_se(getrlimit(RLIMIT_NOFILE, &new) == 0);
+ assert_se(new.rlim_max == old.rlim_max);
+ assert_se(new.rlim_cur == new.rlim_max);
+
+ assert_se(getrlimit(RLIMIT_NOFILE, &old) == 0);
+ assert_se(setrlimit_closest(RLIMIT_NOFILE, &err) == -EINVAL);
+ assert_se(getrlimit(RLIMIT_NOFILE, &new) == 0);
+ assert_se(old.rlim_cur == new.rlim_cur);
+ assert_se(old.rlim_max == new.rlim_max);
+
+ return 0;
+}
diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c
index 8396ae60f3..60b5160cec 100644
--- a/src/test/test-sched-prio.c
+++ b/src/test/test-sched-prio.c
@@ -23,6 +23,7 @@
#include "macro.h"
#include "manager.h"
+#include "test-helper.h"
int main(int argc, char *argv[]) {
Manager *m = NULL;
@@ -35,8 +36,8 @@ int main(int argc, char *argv[]) {
/* prepare the test */
assert_se(set_unit_path(TEST_DIR) >= 0);
r = manager_new(MANAGER_USER, true, &m);
- if (IN_SET(r, -EPERM, -EACCES, -EADDRINUSE, -EHOSTDOWN, -ENOENT, -ENOEXEC)) {
- printf("Skipping test: manager_new: %s", strerror(-r));
+ if (MANAGER_SKIP_TEST(r)) {
+ printf("Skipping test: manager_new: %s\n", strerror(-r));
return EXIT_TEST_SKIP;
}
assert_se(r >= 0);