summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2021-06-23 13:22:20 -0400
committerGitHub <noreply@github.com>2021-06-23 13:22:20 -0400
commite1c0e78558f8fa0e7c1a1e10af5a0fdd310a4c14 (patch)
treeeedb1c9382008bcf7c96f2f8f7990b7a1bb79f0e
parentdca0a31f036139fb3b65b765da75a4ff6d7d0a89 (diff)
parent8374baf530d7dd84ef547d0409f80efa7d284aaf (diff)
downloadbubblewrap-e1c0e78558f8fa0e7c1a1e10af5a0fdd310a4c14.tar.gz
Merge pull request #404 from smcv/utils-unit-test
Add a simple unit test for utility code
-rw-r--r--Makefile.am22
-rw-r--r--tests/test-utils.c213
2 files changed, 232 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am
index 550a6e7..9aafb18 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,7 +27,15 @@ if PRIV_MODE_SETUID
$(SUDO_BIN) chmod u+s $(DESTDIR)$(bindir)/bwrap
endif
-check_PROGRAMS = test-bwrap
+test_programs = \
+ tests/test-utils \
+ $(NULL)
+test_scripts = \
+ tests/test-run.sh \
+ $(NULL)
+test_extra_programs = \
+ test-bwrap \
+ $(NULL)
test-bwrap: bwrap
rm -rf test-bwrap
@@ -38,20 +46,28 @@ if PRIV_MODE_SETUID
$(SUDO_BIN) chmod u+s test-bwrap
endif
+tests_test_utils_SOURCES = \
+ tests/test-utils.c \
+ utils.h \
+ utils.c \
+ $(NULL)
+tests_test_utils_LDADD = $(SELINUX_LIBS)
+
test_bwrap_SOURCES=
include Makefile-docs.am
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/build-aux/tap-driver.sh
LOG_COMPILER =
-TESTS = tests/test-run.sh
TESTS_ENVIRONMENT = \
BWRAP=$(abs_top_builddir)/test-bwrap \
G_TEST_BUILDDIR=$(abs_top_builddir) \
G_TEST_SRCDIR=$(abs_top_srcdir) \
$(NULL)
+check_PROGRAMS = $(test_programs) $(test_extra_programs)
+TESTS = $(test_programs) $(test_scripts)
-EXTRA_DIST += $(TESTS)
+EXTRA_DIST += $(test_scripts)
EXTRA_DIST += tests/libtest-core.sh
EXTRA_DIST += tests/libtest.sh
diff --git a/tests/test-utils.c b/tests/test-utils.c
new file mode 100644
index 0000000..9d4a63c
--- /dev/null
+++ b/tests/test-utils.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright © 2019-2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: LGPL-2-or-later
+ *
+ * This program 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 of the License, or (at your option) any later version.
+ *
+ * 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 <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "utils.h"
+
+/* A small implementation of TAP */
+static unsigned int test_number = 0;
+static void
+ok (const char *format, ...)
+{
+ va_list ap;
+
+ printf ("ok %u - ", ++test_number);
+ va_start (ap, format);
+ vprintf (format, ap);
+ va_end (ap);
+ printf ("\n");
+}
+
+/* for simplicity we always die immediately on failure */
+#define not_ok(fmt, ...) die (fmt, ## __VA_ARGS__)
+
+/* approximately GLib-compatible helper macros */
+#define g_test_message(fmt, ...) printf ("# " fmt "\n", ## __VA_ARGS__)
+#define g_assert_cmpstr(left_expr, op, right_expr) \
+ do { \
+ const char *left = (left_expr); \
+ const char *right = (right_expr); \
+ if (strcmp0 (left, right) op 0) \
+ ok ("%s (\"%s\") %s %s (\"%s\")", #left_expr, left, #op, #right_expr, right); \
+ else \
+ not_ok ("expected %s (\"%s\") %s %s (\"%s\")", \
+ #left_expr, left, #op, #right_expr, right); \
+ } while (0)
+#define g_assert_cmpint(left_expr, op, right_expr) \
+ do { \
+ intmax_t left = (left_expr); \
+ intmax_t right = (right_expr); \
+ if (left op right) \
+ ok ("%s (%ji) %s %s (%ji)", #left_expr, left, #op, #right_expr, right); \
+ else \
+ not_ok ("expected %s (%ji) %s %s (%ji)", \
+ #left_expr, left, #op, #right_expr, right); \
+ } while (0)
+#define g_assert_cmpuint(left_expr, op, right_expr) \
+ do { \
+ uintmax_t left = (left_expr); \
+ uintmax_t right = (right_expr); \
+ if (left op right) \
+ ok ("%s (%ju) %s %s (%ju)", #left_expr, left, #op, #right_expr, right); \
+ else \
+ not_ok ("expected %s (%ju) %s %s (%ju)", \
+ #left_expr, left, #op, #right_expr, right); \
+ } while (0)
+#define g_assert_true(expr) \
+ do { \
+ if ((expr)) \
+ ok ("%s", #expr); \
+ else \
+ not_ok ("expected %s to be true", #expr); \
+ } while (0)
+#define g_assert_false(expr) \
+ do { \
+ if (!(expr)) \
+ ok ("!(%s)", #expr); \
+ else \
+ not_ok ("expected %s to be false", #expr); \
+ } while (0)
+#define g_assert_null(expr) \
+ do { \
+ if ((expr) == NULL) \
+ ok ("%s was null", #expr); \
+ else \
+ not_ok ("expected %s to be null", #expr); \
+ } while (0)
+#define g_assert_nonnull(expr) \
+ do { \
+ if ((expr) != NULL) \
+ ok ("%s wasn't null", #expr); \
+ else \
+ not_ok ("expected %s to be non-null", #expr); \
+ } while (0)
+
+static int
+strcmp0 (const char *left,
+ const char *right)
+{
+ if (left == right)
+ return 0;
+
+ if (left == NULL)
+ return -1;
+
+ if (right == NULL)
+ return 1;
+
+ return strcmp (left, right);
+}
+
+static void
+test_n_elements (void)
+{
+ int three[] = { 1, 2, 3 };
+ g_assert_cmpuint (N_ELEMENTS (three), ==, 3);
+}
+
+static void
+test_strconcat (void)
+{
+ const char *a = "aaa";
+ const char *b = "bbb";
+ char *ab = strconcat (a, b);
+ g_assert_cmpstr (ab, ==, "aaabbb");
+ free (ab);
+}
+
+static void
+test_strconcat3 (void)
+{
+ const char *a = "aaa";
+ const char *b = "bbb";
+ const char *c = "ccc";
+ char *abc = strconcat3 (a, b, c);
+ g_assert_cmpstr (abc, ==, "aaabbbccc");
+ free (abc);
+}
+
+static void
+test_has_prefix (void)
+{
+ g_assert_true (has_prefix ("foo", "foo"));
+ g_assert_true (has_prefix ("foobar", "foo"));
+ g_assert_false (has_prefix ("foobar", "fool"));
+ g_assert_false (has_prefix ("foo", "fool"));
+ g_assert_true (has_prefix ("foo", ""));
+ g_assert_true (has_prefix ("", ""));
+ g_assert_false (has_prefix ("", "no"));
+ g_assert_false (has_prefix ("yes", "no"));
+}
+
+static void
+test_has_path_prefix (void)
+{
+ static const struct
+ {
+ const char *str;
+ const char *prefix;
+ bool expected;
+ } tests[] =
+ {
+ { "/run/host/usr", "/run/host", TRUE },
+ { "/run/host/usr", "/run/host/", TRUE },
+ { "/run/host", "/run/host", TRUE },
+ { "////run///host////usr", "//run//host", TRUE },
+ { "////run///host////usr", "//run//host////", TRUE },
+ { "/run/hostage", "/run/host", FALSE },
+ /* Any number of leading slashes is ignored, even zero */
+ { "foo/bar", "/foo", TRUE },
+ { "/foo/bar", "foo", TRUE },
+ };
+ size_t i;
+
+ for (i = 0; i < N_ELEMENTS (tests); i++)
+ {
+ const char *str = tests[i].str;
+ const char *prefix = tests[i].prefix;
+ bool expected = tests[i].expected;
+
+ if (expected)
+ g_test_message ("%s should have path prefix %s", str, prefix);
+ else
+ g_test_message ("%s should not have path prefix %s", str, prefix);
+
+ if (expected)
+ g_assert_true (has_path_prefix (str, prefix));
+ else
+ g_assert_false (has_path_prefix (str, prefix));
+ }
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ setvbuf (stdout, NULL, _IONBF, 0);
+ test_n_elements ();
+ test_strconcat ();
+ test_strconcat3 ();
+ test_has_prefix ();
+ test_has_path_prefix ();
+ printf ("1..%u\n", test_number);
+ return 0;
+}