summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlejandro Colomar <alx@kernel.org>2023-10-06 17:44:21 +0200
committerAlejandro Colomar <alx@kernel.org>2023-10-20 21:05:33 +0200
commit2a558bd8cbd5b070e79cf7694c00c28eb71a9c99 (patch)
treec667080741298b88c1654d1b49d32581c389ac7d
parent83c8a2d3fa10e26569bee58fc4bdba428a92c786 (diff)
tests/unit/test_xasprintf.c: Test x[v]asprintf()
Link: <https://github.com/shadow-maint/shadow/pull/816> Suggested-by: Iker Pedrosa <ipedrosa@redhat.com> Acked-by: Andreas Schneider <https://github.com/cryptomilk> Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
-rw-r--r--tests/unit/Makefile.am19
-rw-r--r--tests/unit/test_xasprintf.c114
2 files changed, 132 insertions, 1 deletions
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 30277b63..2ee14497 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -3,7 +3,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir)
if HAVE_CMOCKA
TESTS = $(check_PROGRAMS)
-check_PROGRAMS =
+check_PROGRAMS = \
+ test_xasprintf
if ENABLE_LOGIND
check_PROGRAMS += \
@@ -29,4 +30,20 @@ test_logind_LDADD = \
$(CMOCKA_LIBS) \
$(LIBSYSTEMD) \
$(NULL)
+
+test_xasprintf_SOURCES = \
+ ../../lib/sprintf.c \
+ test_xasprintf.c \
+ $(NULL)
+test_xasprintf_CFLAGS = \
+ $(AM_FLAGS) \
+ $(NULL)
+test_xasprintf_LDFLAGS = \
+ -Wl,-wrap,vasprintf \
+ -Wl,-wrap,exit \
+ $(NULL)
+test_xasprintf_LDADD = \
+ $(CMOCKA_LIBS) \
+ $(NULL)
+
endif # HAVE_CMOCKA
diff --git a/tests/unit/test_xasprintf.c b/tests/unit/test_xasprintf.c
new file mode 100644
index 00000000..25e36ca5
--- /dev/null
+++ b/tests/unit/test_xasprintf.c
@@ -0,0 +1,114 @@
+/*
+ * SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <setjmp.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdarg.h> // Required by <cmocka.h>
+#include <stddef.h> // Required by <cmocka.h>
+#include <setjmp.h> // Required by <cmocka.h>
+#include <stdint.h> // Required by <cmocka.h>
+#include <cmocka.h>
+
+#include "sprintf.h"
+
+
+#define assert_unreachable() assert_true(0)
+
+#define XASPRINTF_CALLED (-36)
+#define EXIT_CALLED (42)
+#define TEST_OK (-6)
+
+
+static jmp_buf jmpb;
+
+
+/**********************
+ * WRAPPERS
+ **********************/
+int __real_vasprintf(char **restrict p, const char *restrict fmt, va_list ap);
+int __wrap_vasprintf(char **restrict p, const char *restrict fmt, va_list ap);
+void __wrap_exit(int status);
+
+
+int
+__wrap_vasprintf(char **restrict p, const char *restrict fmt, va_list ap)
+{
+ return mock() == -1 ? -1 : __real_vasprintf(p, fmt, ap);
+}
+
+
+void
+__wrap_exit(int status)
+{
+ longjmp(jmpb, EXIT_CALLED);
+}
+
+
+/**********************
+ * TEST
+ **********************/
+static void test_xasprintf_exit(void **state);
+static void test_xasprintf_ok(void **state);
+
+
+static void
+test_xasprintf_exit(void **state)
+{
+ volatile int len;
+ char *volatile p;
+
+ will_return(__wrap_vasprintf, -1);
+
+ len = 0;
+
+ switch (setjmp(jmpb)) {
+ case 0:
+ len = XASPRINTF_CALLED;
+ len = xasprintf(&p, "foo%s", "bar");
+ assert_unreachable();
+ break;
+ case EXIT_CALLED:
+ assert_int_equal(len, XASPRINTF_CALLED);
+ len = TEST_OK;
+ break;
+ default:
+ assert_unreachable();
+ break;
+ }
+
+ assert_int_equal(len, TEST_OK);
+}
+
+
+static void
+test_xasprintf_ok(void **state)
+{
+ int len;
+ char *p;
+
+ // Trick: it will actually return the length, not 0.
+ will_return(__wrap_vasprintf, 0);
+
+ len = xasprintf(&p, "foo%d%s", 1, "bar");
+ assert_int_equal(len, strlen("foo1bar"));
+ assert_string_equal(p, "foo1bar");
+ free(p);
+}
+
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_xasprintf_exit),
+ cmocka_unit_test(test_xasprintf_ok),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}