summaryrefslogtreecommitdiff
path: root/tests/lib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib')
-rw-r--r--tests/lib/cxxcompat.c1
-rw-r--r--tests/lib/test_assert.c64
-rw-r--r--tests/lib/test_assert.py56
-rw-r--r--tests/lib/test_ringbuf.c2
-rw-r--r--tests/lib/test_seqlock.c3
-rw-r--r--tests/lib/test_typelist.h126
6 files changed, 242 insertions, 10 deletions
diff --git a/tests/lib/cxxcompat.c b/tests/lib/cxxcompat.c
index fde0d6af52..2589fca614 100644
--- a/tests/lib/cxxcompat.c
+++ b/tests/lib/cxxcompat.c
@@ -104,7 +104,6 @@
#include "lib/yang.h"
#include "lib/yang_translator.h"
#include "lib/yang_wrappers.h"
-#include "lib/zassert.h"
#include "lib/zclient.h"
PREDECL_RBTREE_UNIQ(footree);
diff --git a/tests/lib/test_assert.c b/tests/lib/test_assert.c
new file mode 100644
index 0000000000..8f1f4f2bad
--- /dev/null
+++ b/tests/lib/test_assert.c
@@ -0,0 +1,64 @@
+/*
+ * Quick test for assert()
+ * Copyright (C) 2021 David Lamparter for NetDEF, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* make sure this works with assert.h & nothing else. also check the include
+ * shadowing, we don't want to pick up system assert.h
+ */
+#include <assert.h>
+
+__attribute__((noinline))
+void func_for_bt(int number)
+{
+ assert(number > 2);
+ assertf(number > 3, "(A) the number was %d", number);
+}
+
+#include <zebra.h>
+#include "lib/zlog.h"
+#include "lib/thread.h"
+#include "lib/sigevent.h"
+
+int main(int argc, char **argv)
+{
+ int number = 10;
+ struct thread_master *master;
+
+ zlog_aux_init("NONE: ", LOG_DEBUG);
+
+ if (argc > 1)
+ number = atoi(argv[1]);
+
+ assert(number > 0);
+ assertf(number > 1, "(B) the number was %d", number);
+
+ /* set up SIGABRT handler */
+ master = thread_master_create("test");
+ signal_init(master, 0, NULL);
+
+ func_for_bt(number);
+ assert(number > 4);
+ assertf(number > 5, "(C) the number was %d", number);
+
+ assertf(number > 10, "(D) the number was %d", number);
+ return 0;
+}
diff --git a/tests/lib/test_assert.py b/tests/lib/test_assert.py
new file mode 100644
index 0000000000..67c88e6220
--- /dev/null
+++ b/tests/lib/test_assert.py
@@ -0,0 +1,56 @@
+import frrtest
+import os
+import re
+import subprocess
+import inspect
+
+basedir = os.path.dirname(__file__)
+program = os.path.join(basedir, "test_assert")
+
+
+def check(number, rex=None):
+ proc = subprocess.Popen(
+ [frrtest.binpath(program), str(number)],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ out, err = proc.communicate()
+ exitcode = proc.wait()
+
+ if rex is None:
+ assert exitcode == 0
+ else:
+ assert exitcode != 0
+
+ text = out.decode("US-ASCII") + err.decode("US-ASCII")
+ rex = re.compile(rex, re.M | re.S)
+ m = rex.search(text)
+ assert m is not None, "non-matching output: %s" % text
+
+
+def test_assert_0():
+ check(0, r"test_assert\.c:\d+.*number > 0")
+
+
+def test_assert_1():
+ check(1, r"test_assert\.c:\d+.*number > 1.*\(B\) the number was 1")
+
+
+def test_assert_2():
+ check(2, r"test_assert\.c:\d+.*number > 2")
+
+
+def test_assert_3():
+ check(3, r"test_assert\.c:\d+.*number > 3.*\(A\) the number was 3")
+
+
+def test_assert_4():
+ check(4, r"test_assert\.c:\d+.*number > 4")
+
+
+def test_assert_10():
+ check(10, r"test_assert\.c:\d+.*number > 10.*\(D\) the number was 10")
+
+
+def test_assert_11():
+ check(11)
diff --git a/tests/lib/test_ringbuf.c b/tests/lib/test_ringbuf.c
index 7ba5a29b62..4ac62940b8 100644
--- a/tests/lib/test_ringbuf.c
+++ b/tests/lib/test_ringbuf.c
@@ -93,7 +93,7 @@ int main(int argc, char **argv)
assert(ringbuf_get(soil, &compost, BUFSIZ) == BUFSIZ);
validate_state(soil, BUFSIZ, 0);
- assert(soil->empty = true);
+ assert(soil->empty == true);
assert(soil->start == soil->end);
assert(soil->start == 15);
diff --git a/tests/lib/test_seqlock.c b/tests/lib/test_seqlock.c
index 639c2bdc2b..768307d56d 100644
--- a/tests/lib/test_seqlock.c
+++ b/tests/lib/test_seqlock.c
@@ -32,6 +32,7 @@
#include "monotime.h"
#include "seqlock.h"
+#include "printfrr.h"
static struct seqlock sqlo;
static pthread_t thr1;
@@ -43,7 +44,7 @@ static void writestr(const char *str)
char buf[32];
int64_t usec = monotime_since(&start, NULL);
- snprintf(buf, sizeof(buf), "[%02"PRId64"] ", usec / 100000);
+ snprintfrr(buf, sizeof(buf), "[%02" PRId64 "] ", usec / 100000);
iov[0].iov_base = buf;
iov[0].iov_len = strlen(buf);
diff --git a/tests/lib/test_typelist.h b/tests/lib/test_typelist.h
index 32331c14a0..379a2396b4 100644
--- a/tests/lib/test_typelist.h
+++ b/tests/lib/test_typelist.h
@@ -17,6 +17,7 @@
/* C++ called, they want their templates back */
#define item concat(item_, TYPE)
#define itm concat(itm_, TYPE)
+#define itmswap concat(itmswap_, TYPE)
#define head concat(head_, TYPE)
#define list concat(TYPE, )
#define list_head concat(TYPE, _head)
@@ -40,8 +41,9 @@
#define list_find_gteq concat(TYPE, _find_gteq)
#define list_del concat(TYPE, _del)
#define list_pop concat(TYPE, _pop)
+#define list_swap_all concat(TYPE, _swap_all)
-#define ts_hash concat(ts_hash_, TYPE)
+#define ts_hash_head concat(ts_hash_head_, TYPE)
#ifndef REALTYPE
#define REALTYPE TYPE
@@ -89,10 +91,12 @@ DECLARE(REALTYPE, list, struct item, itm);
#endif
#define NITEM 10000
-struct item itm[NITEM];
+#define NITEM_SWAP 100 /* other container for swap */
+struct item itm[NITEM], itmswap[NITEM_SWAP];
static struct list_head head = concat(INIT_, REALTYPE)(head);
-static void ts_hash(const char *text, const char *expect)
+static void ts_hash_head(struct list_head *h, const char *text,
+ const char *expect)
{
int64_t us = monotime_since(&ref, NULL);
SHA256_CTX ctx;
@@ -102,13 +106,13 @@ static void ts_hash(const char *text, const char *expect)
char hashtext[65];
uint32_t swap_count, count;
- count = list_count(&head);
+ count = list_count(h);
swap_count = htonl(count);
SHA256_Init(&ctx);
SHA256_Update(&ctx, &swap_count, sizeof(swap_count));
- frr_each (list, &head, item) {
+ frr_each (list, h, item) {
struct {
uint32_t val_upper, val_lower, index;
} hashitem = {
@@ -135,15 +139,20 @@ static void ts_hash(const char *text, const char *expect)
}
/* hashes will have different item ordering */
#if IS_HASH(REALTYPE) || IS_HEAP(REALTYPE)
-#define ts_hashx(pos, csum) ts_hash(pos, NULL)
+#define ts_hash(pos, csum) ts_hash_head(&head, pos, NULL)
+#define ts_hashx(pos, csum) ts_hash_head(&head, pos, NULL)
+#define ts_hash_headx(head, pos, csum) ts_hash_head(head, pos, NULL)
#else
-#define ts_hashx(pos, csum) ts_hash(pos, csum)
+#define ts_hash(pos, csum) ts_hash_head(&head, pos, csum)
+#define ts_hashx(pos, csum) ts_hash_head(&head, pos, csum)
+#define ts_hash_headx(head, pos, csum) ts_hash_head(head, pos, csum)
#endif
static void concat(test_, TYPE)(void)
{
size_t i, j, k, l;
struct prng *prng;
+ struct prng *prng_swap __attribute__((unused));
struct item *item, *prev __attribute__((unused));
struct item dummy __attribute__((unused));
@@ -151,6 +160,10 @@ static void concat(test_, TYPE)(void)
for (i = 0; i < NITEM; i++)
itm[i].val = i;
+ memset(itmswap, 0, sizeof(itmswap));
+ for (i = 0; i < NITEM_SWAP; i++)
+ itmswap[i].val = i;
+
printfrr("%s start\n", str(TYPE));
ts_start();
@@ -178,6 +191,56 @@ static void concat(test_, TYPE)(void)
assert(list_first(&head) != NULL);
ts_hashx("fill", "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");
+#if !IS_ATOMIC(REALTYPE)
+ struct list_head other;
+
+ list_init(&other);
+ list_swap_all(&head, &other);
+
+ assert(list_count(&head) == 0);
+ assert(!list_first(&head));
+ assert(list_count(&other) == k);
+ assert(list_first(&other) != NULL);
+ ts_hash_headx(
+ &other, "swap1",
+ "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");
+
+ prng_swap = prng_new(0x1234dead);
+ l = 0;
+ for (i = 0; i < NITEM_SWAP; i++) {
+ j = prng_rand(prng_swap) % NITEM_SWAP;
+ if (itmswap[j].scratchpad == 0) {
+ list_add(&head, &itmswap[j]);
+ itmswap[j].scratchpad = 1;
+ l++;
+ }
+#if !IS_HEAP(REALTYPE)
+ else {
+ struct item *rv = list_add(&head, &itmswap[j]);
+ assert(rv == &itmswap[j]);
+ }
+#endif
+ }
+ assert(list_count(&head) == l);
+ assert(list_first(&head) != NULL);
+ ts_hash_headx(
+ &head, "swap-fill",
+ "26df437174051cf305d1bbb62d779ee450ca764167a1e7a94be1aece420008e6");
+
+ list_swap_all(&head, &other);
+
+ assert(list_count(&other) == l);
+ assert(list_first(&other));
+ ts_hash_headx(
+ &other, "swap2a",
+ "26df437174051cf305d1bbb62d779ee450ca764167a1e7a94be1aece420008e6");
+ assert(list_count(&head) == k);
+ assert(list_first(&head) != NULL);
+ ts_hash_headx(
+ &head, "swap2b",
+ "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");
+#endif /* !IS_ATOMIC */
+
k = 0;
#if IS_ATOMIC(REALTYPE)
@@ -344,6 +407,50 @@ static void concat(test_, TYPE)(void)
assert(list_first(&head) != NULL);
ts_hash("fill / add_tail", "eabfcf1413936daaf20965abced95762f45110a6619b84aac7d38481bce4ea19");
+#if !IS_ATOMIC(REALTYPE)
+ struct list_head other;
+
+ list_init(&other);
+ list_swap_all(&head, &other);
+
+ assert(list_count(&head) == 0);
+ assert(!list_first(&head));
+ assert(list_count(&other) == k);
+ assert(list_first(&other) != NULL);
+ ts_hash_head(
+ &other, "swap1",
+ "eabfcf1413936daaf20965abced95762f45110a6619b84aac7d38481bce4ea19");
+
+ prng_swap = prng_new(0x1234dead);
+ l = 0;
+ for (i = 0; i < NITEM_SWAP; i++) {
+ j = prng_rand(prng_swap) % NITEM_SWAP;
+ if (itmswap[j].scratchpad == 0) {
+ list_add_tail(&head, &itmswap[j]);
+ itmswap[j].scratchpad = 1;
+ l++;
+ }
+ }
+ assert(list_count(&head) == l);
+ assert(list_first(&head) != NULL);
+ ts_hash_head(
+ &head, "swap-fill",
+ "833e6ae437e322dfbd36eda8cfc33a61109be735b43f15d256c05e52d1b01909");
+
+ list_swap_all(&head, &other);
+
+ assert(list_count(&other) == l);
+ assert(list_first(&other));
+ ts_hash_head(
+ &other, "swap2a",
+ "833e6ae437e322dfbd36eda8cfc33a61109be735b43f15d256c05e52d1b01909");
+ assert(list_count(&head) == k);
+ assert(list_first(&head) != NULL);
+ ts_hash_head(
+ &head, "swap2b",
+ "eabfcf1413936daaf20965abced95762f45110a6619b84aac7d38481bce4ea19");
+#endif
+
for (i = 0; i < NITEM / 2; i++) {
j = prng_rand(prng) % NITEM;
if (itm[j].scratchpad == 1) {
@@ -546,10 +653,14 @@ static void concat(test_, TYPE)(void)
printfrr("%s end\n", str(TYPE));
}
+#undef ts_hash
#undef ts_hashx
+#undef ts_hash_head
+#undef ts_hash_headx
#undef item
#undef itm
+#undef itmswap
#undef head
#undef list
#undef list_head
@@ -571,6 +682,7 @@ static void concat(test_, TYPE)(void)
#undef list_find_gteq
#undef list_del
#undef list_pop
+#undef list_swap_all
#undef REALTYPE
#undef TYPE