]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
tests/unit/test_xasprintf.c: Test x[v]asprintf()
authorAlejandro Colomar <alx@kernel.org>
Fri, 6 Oct 2023 15:44:21 +0000 (17:44 +0200)
committerAlejandro Colomar <alx@kernel.org>
Fri, 20 Oct 2023 19:05:33 +0000 (21:05 +0200)
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>
tests/unit/Makefile.am
tests/unit/test_xasprintf.c [new file with mode: 0644]

index 30277b638d0d7a3370c73e206e8ce2f4cd72d289..2ee1449763d3fafdc88ad13e4de15148672959f3 100644 (file)
@@ -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 (file)
index 0000000..25e36ca
--- /dev/null
@@ -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);
+}