Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
David Vernet | 753 | 100.00% | 1 | 100.00% |
Total | 753 | 1 |
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2024 Meta Platforms, Inc. and affiliates. * Copyright (c) 2024 David Vernet <dvernet@meta.com> * Copyright (c) 2024 Tejun Heo <tj@kernel.org> */ #include <stdio.h> #include <unistd.h> #include <signal.h> #include <libgen.h> #include <bpf/bpf.h> #include "scx_test.h" const char help_fmt[] = "The runner for sched_ext tests.\n" "\n" "The runner is statically linked against all testcases, and runs them all serially.\n" "It's required for the testcases to be serial, as only a single host-wide sched_ext\n" "scheduler may be loaded at any given time." "\n" "Usage: %s [-t TEST] [-h]\n" "\n" " -t TEST Only run tests whose name includes this string\n" " -s Include print output for skipped tests\n" " -q Don't print the test descriptions during run\n" " -h Display this help and exit\n"; static volatile int exit_req; static bool quiet, print_skipped; #define MAX_SCX_TESTS 2048 static struct scx_test __scx_tests[MAX_SCX_TESTS]; static unsigned __scx_num_tests = 0; static void sigint_handler(int simple) { exit_req = 1; } static void print_test_preamble(const struct scx_test *test, bool quiet) { printf("===== START =====\n"); printf("TEST: %s\n", test->name); if (!quiet) printf("DESCRIPTION: %s\n", test->description); printf("OUTPUT:\n"); } static const char *status_to_result(enum scx_test_status status) { switch (status) { case SCX_TEST_PASS: case SCX_TEST_SKIP: return "ok"; case SCX_TEST_FAIL: return "not ok"; default: return "<UNKNOWN>"; } } static void print_test_result(const struct scx_test *test, enum scx_test_status status, unsigned int testnum) { const char *result = status_to_result(status); const char *directive = status == SCX_TEST_SKIP ? "SKIP " : ""; printf("%s %u %s # %s\n", result, testnum, test->name, directive); printf("===== END =====\n"); } static bool should_skip_test(const struct scx_test *test, const char * filter) { return !strstr(test->name, filter); } static enum scx_test_status run_test(const struct scx_test *test) { enum scx_test_status status; void *context = NULL; if (test->setup) { status = test->setup(&context); if (status != SCX_TEST_PASS) return status; } status = test->run(context); if (test->cleanup) test->cleanup(context); return status; } static bool test_valid(const struct scx_test *test) { if (!test) { fprintf(stderr, "NULL test detected\n"); return false; } if (!test->name) { fprintf(stderr, "Test with no name found. Must specify test name.\n"); return false; } if (!test->description) { fprintf(stderr, "Test %s requires description.\n", test->name); return false; } if (!test->run) { fprintf(stderr, "Test %s has no run() callback\n", test->name); return false; } return true; } int main(int argc, char **argv) { const char *filter = NULL; unsigned testnum = 0, i; unsigned passed = 0, skipped = 0, failed = 0; int opt; signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); libbpf_set_strict_mode(LIBBPF_STRICT_ALL); while ((opt = getopt(argc, argv, "qst:h")) != -1) { switch (opt) { case 'q': quiet = true; break; case 's': print_skipped = true; break; case 't': filter = optarg; break; default: fprintf(stderr, help_fmt, basename(argv[0])); return opt != 'h'; } } for (i = 0; i < __scx_num_tests; i++) { enum scx_test_status status; struct scx_test *test = &__scx_tests[i]; if (filter && should_skip_test(test, filter)) { /* * Printing the skipped tests and their preambles can * add a lot of noise to the runner output. Printing * this is only really useful for CI, so let's skip it * by default. */ if (print_skipped) { print_test_preamble(test, quiet); print_test_result(test, SCX_TEST_SKIP, ++testnum); } continue; } print_test_preamble(test, quiet); status = run_test(test); print_test_result(test, status, ++testnum); switch (status) { case SCX_TEST_PASS: passed++; break; case SCX_TEST_SKIP: skipped++; break; case SCX_TEST_FAIL: failed++; break; } } printf("\n\n=============================\n\n"); printf("RESULTS:\n\n"); printf("PASSED: %u\n", passed); printf("SKIPPED: %u\n", skipped); printf("FAILED: %u\n", failed); return 0; } void scx_test_register(struct scx_test *test) { SCX_BUG_ON(!test_valid(test), "Invalid test found"); SCX_BUG_ON(__scx_num_tests >= MAX_SCX_TESTS, "Maximum tests exceeded"); __scx_tests[__scx_num_tests++] = *test; }
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1