summaryrefslogtreecommitdiff
path: root/tests/lib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib')
-rw-r--r--tests/lib/cli/common_cli.c9
-rw-r--r--tests/lib/cli/common_cli.h3
-rw-r--r--tests/lib/script1.lua54
-rw-r--r--tests/lib/test_frrlua.c111
-rw-r--r--tests/lib/test_frrlua.py14
-rw-r--r--tests/lib/test_frrscript.c104
-rw-r--r--tests/lib/test_frrscript.py14
-rw-r--r--tests/lib/test_plist.c48
8 files changed, 356 insertions, 1 deletions
diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c
index 49bc0f4fb2..8be81cc4cb 100644
--- a/tests/lib/cli/common_cli.c
+++ b/tests/lib/cli/common_cli.c
@@ -59,10 +59,13 @@ static void vty_do_exit(int isexit)
exit(0);
}
+const struct frr_yang_module_info *const *test_yang_modules = NULL;
+
/* main routine. */
int main(int argc, char **argv)
{
struct thread thread;
+ size_t yangcount;
/* Set umask before anything for security */
umask(0027);
@@ -79,7 +82,11 @@ int main(int argc, char **argv)
vty_init(master, false);
lib_cmd_init();
- nb_init(master, NULL, 0, false);
+
+ for (yangcount = 0; test_yang_modules && test_yang_modules[yangcount];
+ yangcount++)
+ ;
+ nb_init(master, test_yang_modules, yangcount, false);
test_init(argc, argv);
diff --git a/tests/lib/cli/common_cli.h b/tests/lib/cli/common_cli.h
index 15abe3b855..3042ff5b12 100644
--- a/tests/lib/cli/common_cli.h
+++ b/tests/lib/cli/common_cli.h
@@ -25,6 +25,9 @@
#include "zebra.h"
#include "vty.h"
#include "command.h"
+#include "northbound.h"
+
+extern const struct frr_yang_module_info *const *test_yang_modules;
/* function to be implemented by test */
extern void test_init(int argc, char **argv);
diff --git a/tests/lib/script1.lua b/tests/lib/script1.lua
new file mode 100644
index 0000000000..6361c960a7
--- /dev/null
+++ b/tests/lib/script1.lua
@@ -0,0 +1,54 @@
+
+-- Positive testing
+
+function foo(a, b)
+ a = a + 1
+ b = b + 1
+ return {
+ a = a,
+ b = b,
+ }
+end
+
+function bar(a, b)
+ a = a + 1
+ b = b + 1
+ c = 303
+ return {
+ b = b,
+ c = c,
+ }
+end
+
+function fact(n)
+ -- outer function must return a table
+ -- inner functions can be used to recurse or as helpers
+ function helper(m)
+ if m == 0 then
+ return 1
+ else
+ return m * helper(m - 1)
+ end
+ end
+ return {
+ ans = helper(n)
+ }
+end
+
+-- Negative testing
+
+function bad_return1()
+end
+
+function bad_return2()
+ return 123
+end
+
+function bad_return3()
+ return {}
+end
+
+function bad_return4()
+ error("Something bad!")
+end
+
diff --git a/tests/lib/test_frrlua.c b/tests/lib/test_frrlua.c
new file mode 100644
index 0000000000..a81446f9ca
--- /dev/null
+++ b/tests/lib/test_frrlua.c
@@ -0,0 +1,111 @@
+/*
+ * frrlua unit tests
+ * Copyright (C) 2021 Donald Lee
+ *
+ * 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
+ */
+
+#include <zebra.h>
+#include "string.h"
+#include "stdio.h"
+#include "lib/frrlua.h"
+
+static void test_encode_decode(void)
+{
+ lua_State *L = luaL_newstate();
+
+ long long a = 123;
+ long long b = a;
+
+ lua_pushintegerp(L, &a);
+ lua_decode_integerp(L, -1, &a);
+ assert(a == b);
+ assert(lua_gettop(L) == 0);
+
+ time_t time_a = 100;
+ time_t time_b = time_a;
+
+ lua_pushtimet(L, &time_a);
+ lua_decode_timet(L, -1, &time_a);
+ assert(time_a == time_b);
+ assert(lua_gettop(L) == 0);
+
+ char str_b[] = "Hello", str_a[6];
+
+ strlcpy(str_a, str_b, sizeof(str_b));
+ lua_pushstring_wrapper(L, str_a);
+ lua_decode_stringp(L, -1, str_a);
+ assert(strncmp(str_a, str_b, sizeof(str_b)) == 0);
+ assert(lua_gettop(L) == 0);
+
+ char p_b_str[] = "10.0.0.0/24", p_a_str[12];
+ struct prefix p_a;
+
+ strlcpy(p_a_str, p_b_str, sizeof(p_b_str));
+ str2prefix(p_a_str, &p_a);
+ lua_pushprefix(L, &p_a);
+ lua_decode_prefix(L, -1, &p_a);
+ prefix2str(&p_a, p_a_str, sizeof(p_b_str));
+ assert(strncmp(p_a_str, p_b_str, sizeof(p_b_str)) == 0);
+ assert(lua_gettop(L) == 0);
+
+ struct interface ifp_a;
+ struct interface ifp_b = ifp_a;
+
+ lua_pushinterface(L, &ifp_a);
+ lua_decode_interface(L, -1, &ifp_a);
+ assert(strncmp(ifp_a.name, ifp_b.name, sizeof(ifp_b.name)) == 0);
+ assert(ifp_a.ifindex == ifp_b.ifindex);
+ assert(ifp_a.status == ifp_b.status);
+ assert(ifp_a.flags == ifp_b.flags);
+ assert(ifp_a.metric == ifp_b.metric);
+ assert(ifp_a.speed == ifp_b.speed);
+ assert(ifp_a.mtu == ifp_b.mtu);
+ assert(ifp_a.mtu6 == ifp_b.mtu6);
+ assert(ifp_a.bandwidth == ifp_b.bandwidth);
+ assert(ifp_a.link_ifindex == ifp_b.link_ifindex);
+ assert(ifp_a.ll_type == ifp_b.ll_type);
+ assert(lua_gettop(L) == 0);
+
+ struct in_addr addr_a;
+ struct in_addr addr_b = addr_a;
+
+ lua_pushinaddr(L, &addr_a);
+ lua_decode_inaddr(L, -1, &addr_a);
+ assert(addr_a.s_addr == addr_b.s_addr);
+ assert(lua_gettop(L) == 0);
+
+ struct in6_addr in6addr_a;
+ struct in6_addr in6addr_b = in6addr_a;
+
+ lua_pushin6addr(L, &in6addr_a);
+ lua_decode_in6addr(L, -1, &in6addr_a);
+ assert(in6addr_cmp(&in6addr_a, &in6addr_b) == 0);
+ assert(lua_gettop(L) == 0);
+
+ union sockunion su_a, su_b;
+
+ memset(&su_a, 0, sizeof(union sockunion));
+ memset(&su_b, 0, sizeof(union sockunion));
+ lua_pushsockunion(L, &su_a);
+ lua_decode_sockunion(L, -1, &su_a);
+ assert(sockunion_cmp(&su_a, &su_b) == 0);
+ assert(lua_gettop(L) == 0);
+}
+
+int main(int argc, char **argv)
+{
+ test_encode_decode();
+}
diff --git a/tests/lib/test_frrlua.py b/tests/lib/test_frrlua.py
new file mode 100644
index 0000000000..2f6ddc1c07
--- /dev/null
+++ b/tests/lib/test_frrlua.py
@@ -0,0 +1,14 @@
+import frrtest
+import pytest
+
+if 'S["SCRIPTING_TRUE"]=""\n' not in open("../config.status").readlines():
+ class TestFrrlua:
+ @pytest.mark.skipif(True, reason="Test unsupported")
+ def test_exit_cleanly(self):
+ pass
+else:
+
+ class TestFrrlua(frrtest.TestMultiOut):
+ program = "./test_frrlua"
+
+ TestFrrlua.exit_cleanly()
diff --git a/tests/lib/test_frrscript.c b/tests/lib/test_frrscript.c
new file mode 100644
index 0000000000..7b23045978
--- /dev/null
+++ b/tests/lib/test_frrscript.c
@@ -0,0 +1,104 @@
+/*
+ * frrscript unit tests
+ * Copyright (C) 2021 Donald Lee
+ *
+ * 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
+ */
+
+#include <zebra.h>
+
+#include "lib/frrscript.h"
+#include "lib/frrlua.h"
+
+int main(int argc, char **argv)
+{
+ frrscript_init("./lib");
+ struct frrscript *fs = frrscript_new("script1");
+ int result;
+
+ /* Positive testing */
+
+ long long a = 100, b = 200;
+
+ result = frrscript_load(fs, "foo", NULL);
+ assert(result == 0);
+ result = frrscript_call(fs, "foo", ("a", &a), ("b", &b));
+ assert(result == 0);
+ assert(a == 101);
+ assert(b == 201);
+
+ a = 100, b = 200;
+
+ result = frrscript_load(fs, "bar", NULL);
+ assert(result == 0);
+ result = frrscript_call(fs, "bar", ("a", &a), ("b", &b));
+ assert(result == 0);
+ long long *cptr = frrscript_get_result(fs, "bar", "c", lua_tointegerp);
+
+ /* a should not occur in the returned table in script */
+ assert(a == 100);
+ assert(b == 201);
+ assert(*cptr == 303);
+ XFREE(MTYPE_SCRIPT_RES, cptr);
+
+ long long n = 5;
+
+ result = frrscript_load(fs, "fact", NULL);
+ assert(result == 0);
+ result = frrscript_call(fs, "fact", ("n", &n));
+ assert(result == 0);
+ long long *ansptr =
+ frrscript_get_result(fs, "fact", "ans", lua_tointegerp);
+ assert(*ansptr == 120);
+ XFREE(MTYPE_SCRIPT_RES, ansptr);
+
+ /* Negative testing */
+
+ /* Function does not exist in script file*/
+ result = frrscript_load(fs, "does_not_exist", NULL);
+ assert(result == 1);
+
+ /* Function was not (successfully) loaded */
+ result = frrscript_call(fs, "does_not_exist", ("a", &a), ("b", &b));
+ assert(result == 1);
+
+ /* Get result from a function that was not loaded */
+ long long *llptr =
+ frrscript_get_result(fs, "does_not_exist", "c", lua_tointegerp);
+ assert(llptr == NULL);
+
+ /* Function returns void */
+ result = frrscript_call(fs, "bad_return1");
+ assert(result == 1);
+
+ /* Function returns number */
+ result = frrscript_call(fs, "bad_return2");
+ assert(result == 1);
+
+ /* Get non-existent result from a function */
+ result = frrscript_call(fs, "bad_return3");
+ assert(result == 1);
+ long long *cllptr =
+ frrscript_get_result(fs, "bad_return3", "c", lua_tointegerp);
+ assert(cllptr == NULL);
+
+ /* Function throws exception */
+ result = frrscript_call(fs, "bad_return4");
+ assert(result == 1);
+
+ frrscript_delete(fs);
+
+ return 0;
+}
diff --git a/tests/lib/test_frrscript.py b/tests/lib/test_frrscript.py
new file mode 100644
index 0000000000..046d97b014
--- /dev/null
+++ b/tests/lib/test_frrscript.py
@@ -0,0 +1,14 @@
+import frrtest
+import pytest
+
+if 'S["SCRIPTING_TRUE"]=""\n' not in open("../config.status").readlines():
+ class TestFrrscript:
+ @pytest.mark.skipif(True, reason="Test unsupported")
+ def test_exit_cleanly(self):
+ pass
+else:
+
+ class TestFrrscript(frrtest.TestMultiOut):
+ program = "./test_frrscript"
+
+ TestFrrscript.exit_cleanly()
diff --git a/tests/lib/test_plist.c b/tests/lib/test_plist.c
new file mode 100644
index 0000000000..ee7a9ebf30
--- /dev/null
+++ b/tests/lib/test_plist.c
@@ -0,0 +1,48 @@
+/*
+ * Simple prefix list querying tool
+ *
+ * Copyright (C) 2021 by David Lamparter,
+ * for Open Source Routing / NetDEF, Inc.
+ *
+ * Quagga 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, or (at your option) any
+ * later version.
+ *
+ * Quagga 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
+ */
+
+#include <zebra.h>
+
+#include "lib/plist.h"
+#include "lib/filter.h"
+#include "tests/lib/cli/common_cli.h"
+
+static const struct frr_yang_module_info *const my_yang_modules[] = {
+ &frr_filter_info,
+ NULL,
+};
+
+__attribute__((_CONSTRUCTOR(2000)))
+static void test_yang_modules_set(void)
+{
+ test_yang_modules = my_yang_modules;
+}
+
+void test_init(int argc, char **argv)
+{
+ prefix_list_init();
+ filter_cli_init();
+
+ /* nothing else to do here, giving stand-alone access to the prefix
+ * list code's "debug prefix-list ..." command is the only purpose of
+ * this "test".
+ */
+}