@@ -41,12 +41,13 @@
#endif
#endif
+#define inline __inline__
+#include "../kselftest.h"
+
/* for the type of int_fast16_t and int_fast32_t, musl differs from glibc and nolibc */
#define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2)))
#define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1)
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-
/* will be used to test initialization of environ */
static char **test_envp;
@@ -59,6 +60,8 @@ static int test_argc;
/* will be used by some test cases as readable file, please don't write it */
static const char *argv0;
+static const char *test_name;
+
/* definition of a series of tests */
struct test {
const char *name; /* test name */
@@ -197,15 +200,11 @@ static int expect_nz(int expr, int llen)
#define EXPECT_EQ(cond, expr, val) \
- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_eq(expr, llen, val); } while (0)
+ do { if (!(cond)) ksft_test_result_skip2(test_name, "%s\n", #cond); else expect_eq(expr, val); } while (0)
-static int expect_eq(uint64_t expr, int llen, uint64_t val)
+static int expect_eq(uint64_t expr, uint64_t val)
{
- int ret = !(expr == val);
-
- llen += printf(" = %lld ", (long long)expr);
- result(llen, ret ? FAIL : OK);
- return ret;
+ ksft_test_result(expr = val, "%s = %lld\n", test_name, (long long) expr);
}
@@ -223,15 +222,11 @@ static int expect_ne(int expr, int llen, int val)
#define EXPECT_GE(cond, expr, val) \
- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ge(expr, llen, val); } while (0)
+ do { if (!(cond)) ksft_test_result_skip2(test_name, "%s\n", #cond); else expect_ge(expr, val); } while (0)
-static int expect_ge(int expr, int llen, int val)
+static int expect_ge(int expr, int val)
{
- int ret = !(expr >= val);
-
- llen += printf(" = %d ", expr);
- result(llen, ret ? FAIL : OK);
- return ret;
+ ksft_test_result(expr >= val, "%s = %d\n", test_name, expr);
}
@@ -376,37 +371,19 @@ static int expect_ptrzr(const void *expr, int llen)
#define EXPECT_PTRNZ(cond, expr) \
- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrnz(expr, llen); } while (0)
+ do { if (!(cond)) ksft_test_result_skip("%s: %s\n", test_name, #cond); else expect_ptrnz(expr); } while (0)
-static int expect_ptrnz(const void *expr, int llen)
+static int expect_ptrnz(const void *expr)
{
- int ret = 0;
-
- llen += printf(" = <%p> ", expr);
- if (!expr) {
- ret = 1;
- result(llen, FAIL);
- } else {
- result(llen, OK);
- }
- return ret;
+ ksft_test_result(expr, "%s = <%p>\n", test_name, expr);
}
#define EXPECT_PTREQ(cond, expr, cmp) \
- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptreq(expr, llen, cmp); } while (0)
+ do { if (!(cond)) ksft_test_result_skip("%s: %s\n", test_name, #cond); else expect_ptreq(expr, cmp); } while (0)
-static int expect_ptreq(const void *expr, int llen, const void *cmp)
+static void expect_ptreq(const void *expr, const void *cmp)
{
- int ret = 0;
-
- llen += printf(" = <%p> ", expr);
- if (expr != cmp) {
- ret = 1;
- result(llen, FAIL);
- } else {
- result(llen, OK);
- }
- return ret;
+ ksft_test_result(expr == cmp, "%s = <%p>\n", test_name, expr);
}
#define EXPECT_PTRNE(cond, expr, cmp) \
@@ -439,41 +416,28 @@ static int expect_ptrge(const void *expr, int llen, const void *cmp)
}
#define EXPECT_PTRGT(cond, expr, cmp) \
- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrgt(expr, llen, cmp); } while (0)
+ do { if (!(cond)) ksft_test_result_skip2(test_name, "%s\n", #cond); else expect_ptrgt(expr, cmp); } while (0)
-static int expect_ptrgt(const void *expr, int llen, const void *cmp)
+static void expect_ptrgt(const void *expr, const void *cmp)
{
- int ret = !(expr > cmp);
-
- llen += printf(" = <%p> ", expr);
- result(llen, ret ? FAIL : OK);
- return ret;
+ ksft_test_result(expr > cmp, "%s = <%p>\n", test_name, expr);
}
-
#define EXPECT_PTRLE(cond, expr, cmp) \
- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrle(expr, llen, cmp); } while (0)
+ do { if (!(cond)) ksft_test_result_skip("%s: %s\n", test_name, #cond); else expect_ptrle(expr, cmp); } while (0)
static int expect_ptrle(const void *expr, int llen, const void *cmp)
{
- int ret = !(expr <= cmp);
-
- llen += printf(" = <%p> ", expr);
- result(llen, ret ? FAIL : OK);
- return ret;
+ ksft_test_result(expr <= cmp, "%s = <%p>\n", test_name, expr);
}
#define EXPECT_PTRLT(cond, expr, cmp) \
- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrlt(expr, llen, cmp); } while (0)
+ do { if (!(cond)) ksft_test_result_skip2(test_name, "%s\n", #cond); else expect_ptrlt(expr, cmp); } while (0)
-static int expect_ptrlt(const void *expr, int llen, const void *cmp)
+static int expect_ptrlt(const void *expr, const void *cmp)
{
- int ret = !(expr < cmp);
-
- llen += printf(" = <%p> ", expr);
- result(llen, ret ? FAIL : OK);
- return ret;
+ ksft_test_result(expr < cmp, "%s = <%p>\n", test_name, expr);
}
#define EXPECT_PTRER2(cond, expr, expret, experr1, experr2) \
@@ -520,20 +484,11 @@ static int expect_strzr(const char *expr, int llen)
#define EXPECT_STRNZ(cond, expr) \
- do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strnz(expr, llen); } while (0)
+ do { if (!(cond)) ksft_test_result_skip("%s: %s\n", test_name, #cond); else expect_strnz(expr); } while (0)
-static int expect_strnz(const char *expr, int llen)
+static int expect_strnz(const char *expr)
{
- int ret = 0;
-
- llen += printf(" = <%s> ", expr);
- if (!expr) {
- ret = 1;
- result(llen, FAIL);
- } else {
- result(llen, OK);
- }
- return ret;
+ ksft_test_result(expr, "%s = <%p>\n", test_name, expr);
}
@@ -575,7 +530,7 @@ static int expect_strne(const char *expr, int llen, const char *cmp)
/* declare tests based on line numbers. There must be exactly one test per line. */
#define CASE_TEST(name) \
- case __LINE__: llen += printf("%d %s", test, #name);
+ case __LINE__: test_name = #name;
#define SWITCH_TEST \
int _tests_start = __LINE__; switch (test + __LINE__ + 1) {
@@ -1187,10 +1142,12 @@ int prepare(void)
static const struct test test_names[] = {
/* add new tests here */
{ .name = "startup", .func = run_startup },
+ /*
{ .name = "syscall", .func = run_syscall },
{ .name = "stdlib", .func = run_stdlib },
{ .name = "vfprintf", .func = run_vfprintf },
{ .name = "protection", .func = run_protection },
+ */
};
int is_setting_valid(char *test)
@@ -1317,16 +1274,19 @@ int main(int argc, char **argv, char **envp)
} while (test && *test);
} else {
/* no test mentioned, run everything */
+
+ ksft_print_header_ktap();
+ int total = 0;
+ for (idx = 0; idx < ARRAY_SIZE(test_names); idx++)
+ total += count_subtests(&test_names[idx]);
+ ksft_set_plan(total);
+
for (idx = 0; idx < ARRAY_SIZE(test_names); idx++) {
- printf("Running test '%s'\n", test_names[idx].name);
err = test_names[idx].func(min, max);
ret += err;
- printf("Errors during this test: %d\n\n", err);
}
}
- printf("Total number of errors: %d\n", ret);
-
if (getpid() == 1) {
/* we're running as init, there's no other process on the
* system, thus likely started from a VM for a quick check.
@@ -1335,7 +1295,7 @@ int main(int argc, char **argv, char **envp)
* cleanly will often be reported as a success. This allows
* to use the output of this program for bisecting kernels.
*/
- printf("Leaving init with final status: %d\n", !!ret);
+ ksft_print_msg("Leaving init with final status: %d\n", !!ret);
if (ret == 0)
reboot(RB_POWER_OFF);
#if defined(__x86_64__)
@@ -1349,6 +1309,7 @@ int main(int argc, char **argv, char **envp)
#endif
}
- printf("Exiting with status %d\n", !!ret);
+ ksft_print_msg("Exiting with status %d\n", !!ret);
+ ksft_finished();
return !!ret;
}
new file mode 100755
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -o pipefail
+
+archs=(arm64 x86_64 riscv64)
+
+echo "KTAP version 1"
+echo "1..${#archs[@]}"
+
+for i in "${!archs[@]}"; do
+ arch="${archs[$i]}"
+ ./libc-test | sed -e 's/^/ /'
+ rc=$?
+
+ if [ $rc -eq 0 ]; then
+ res=ok
+ else
+ res="not ok"
+ fi
+
+ echo "$res $(( i + 1 )) $arch"
+done