From 1f666e522cc49df2659f40be118624bf7a529a0f Mon Sep 17 00:00:00 2001 From: Naresh Kamboju Date: Mon, 22 May 2017 12:47:43 +0530 Subject: selftests: futex: print testcase-name and PASS/FAIL/ERROR status Most of the tests under selftests follow a pattern for their results, which can then be parsed easily by other external tools easily. Though futex tests do print the test results very well, it doesn't really follow the general selftests pattern. This patch makes necessary changes to fix that. Output before this patch: futex_requeue_pi: Test requeue functionality Arguments: broadcast=0 locked=0 owner=0 timeout=0ns Result: PASS Output after this patch: futex_requeue_pi: Test requeue functionality Arguments: broadcast=0 locked=0 owner=0 timeout=0ns selftests: futex-requeue-pi [PASS] Signed-off-by: Naresh Kamboju Signed-off-by: Shuah Khan --- tools/testing/selftests/futex/functional/futex_requeue_pi.c | 3 ++- .../selftests/futex/functional/futex_requeue_pi_mismatched_ops.c | 4 +++- .../selftests/futex/functional/futex_requeue_pi_signal_restart.c | 3 ++- .../selftests/futex/functional/futex_wait_private_mapped_file.c | 5 +++-- tools/testing/selftests/futex/functional/futex_wait_timeout.c | 4 +++- .../selftests/futex/functional/futex_wait_uninitialized_heap.c | 3 ++- tools/testing/selftests/futex/functional/futex_wait_wouldblock.c | 3 ++- tools/testing/selftests/futex/include/logging.h | 4 ++-- 8 files changed, 19 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi.c b/tools/testing/selftests/futex/functional/futex_requeue_pi.c index 3da06ad23996..d24ab7421e73 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue_pi.c +++ b/tools/testing/selftests/futex/functional/futex_requeue_pi.c @@ -32,6 +32,7 @@ #include "futextest.h" #include "logging.h" +#define TEST_NAME "futex-requeue-pi" #define MAX_WAKE_ITERS 1000 #define THREAD_MAX 10 #define SIGNAL_PERIOD_US 100 @@ -404,6 +405,6 @@ int main(int argc, char *argv[]) */ ret = unit_test(broadcast, locked, owner, timeout_ns); - print_result(ret); + print_result(TEST_NAME, ret); return ret; } diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c b/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c index d5e4f2c4da2a..e0a798ad0d21 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c +++ b/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c @@ -30,6 +30,8 @@ #include "futextest.h" #include "logging.h" +#define TEST_NAME "futex-requeue-pi-mismatched-ops" + futex_t f1 = FUTEX_INITIALIZER; futex_t f2 = FUTEX_INITIALIZER; int child_ret = 0; @@ -130,6 +132,6 @@ int main(int argc, char *argv[]) out: /* If the kernel crashes, we shouldn't return at all. */ - print_result(ret); + print_result(TEST_NAME, ret); return ret; } diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c b/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c index 3d7dc6afc3f8..982f83577501 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c +++ b/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c @@ -32,6 +32,7 @@ #include "futextest.h" #include "logging.h" +#define TEST_NAME "futex-requeue-pi-signal-restart" #define DELAY_US 100 futex_t f1 = FUTEX_INITIALIZER; @@ -218,6 +219,6 @@ int main(int argc, char *argv[]) if (ret == RET_PASS && waiter_ret) ret = waiter_ret; - print_result(ret); + print_result(TEST_NAME, ret); return ret; } diff --git a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c index 5f687f247454..bdc48dc047e5 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c +++ b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c @@ -34,6 +34,7 @@ #include "logging.h" #include "futextest.h" +#define TEST_NAME "futex-wait-private-mapped-file" #define PAGE_SZ 4096 char pad[PAGE_SZ] = {1}; @@ -60,7 +61,7 @@ void *thr_futex_wait(void *arg) ret = futex_wait(&val, 1, &wait_timeout, 0); if (ret && errno != EWOULDBLOCK && errno != ETIMEDOUT) { error("futex error.\n", errno); - print_result(RET_ERROR); + print_result(TEST_NAME, RET_ERROR); exit(RET_ERROR); } @@ -120,6 +121,6 @@ int main(int argc, char **argv) pthread_join(thr, NULL); out: - print_result(ret); + print_result(TEST_NAME, ret); return ret; } diff --git a/tools/testing/selftests/futex/functional/futex_wait_timeout.c b/tools/testing/selftests/futex/functional/futex_wait_timeout.c index ab428ca894de..6aadd560366e 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_timeout.c +++ b/tools/testing/selftests/futex/functional/futex_wait_timeout.c @@ -27,6 +27,8 @@ #include "futextest.h" #include "logging.h" +#define TEST_NAME "futex-wait-timeout" + static long timeout_ns = 100000; /* 100us default timeout */ void usage(char *prog) @@ -81,6 +83,6 @@ int main(int argc, char *argv[]) ret = RET_FAIL; } - print_result(ret); + print_result(TEST_NAME, ret); return ret; } diff --git a/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c b/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c index fe7aee96844b..d237a8b702f0 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c +++ b/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c @@ -36,6 +36,7 @@ #include "logging.h" #include "futextest.h" +#define TEST_NAME "futex-wait-uninitialized-heap" #define WAIT_US 5000000 static int child_blocked = 1; @@ -119,6 +120,6 @@ int main(int argc, char **argv) } out: - print_result(ret); + print_result(TEST_NAME, ret); return ret; } diff --git a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c index b6b027448825..9a2c56fa7305 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c +++ b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c @@ -28,6 +28,7 @@ #include "futextest.h" #include "logging.h" +#define TEST_NAME "futex-wait-wouldblock" #define timeout_ns 100000 void usage(char *prog) @@ -74,6 +75,6 @@ int main(int argc, char *argv[]) ret = RET_FAIL; } - print_result(ret); + print_result(TEST_NAME, ret); return ret; } diff --git a/tools/testing/selftests/futex/include/logging.h b/tools/testing/selftests/futex/include/logging.h index e14469103f07..4e7944984fbb 100644 --- a/tools/testing/selftests/futex/include/logging.h +++ b/tools/testing/selftests/futex/include/logging.h @@ -107,7 +107,7 @@ void log_verbosity(int level) * * print_result() is primarily intended for functional tests. */ -void print_result(int ret) +void print_result(const char *test_name, int ret) { const char *result = "Unknown return code"; @@ -124,7 +124,7 @@ void print_result(int ret) result = FAIL; break; } - printf("Result: %s\n", result); + printf("selftests: %s [%s]\n", test_name, result); } /* log level macros */ -- cgit v1.2.3 From eff33cfa0631a8f887df5f941e6ad1ae9a43a013 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Thu, 18 May 2017 14:52:58 +0200 Subject: selftests/vm: Fix test for virtual address range mapping for arm64 Arm64 has 256TB address space so fix the test to pass on Arm as well. Also remove unneeded numaif header. Signed-off-by: Michal Suchanek Signed-off-by: Shuah Khan --- tools/testing/selftests/vm/virtual_address_range.c | 35 ++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/vm/virtual_address_range.c b/tools/testing/selftests/vm/virtual_address_range.c index 3b02aa6eb9da..1830d66a6f0e 100644 --- a/tools/testing/selftests/vm/virtual_address_range.c +++ b/tools/testing/selftests/vm/virtual_address_range.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -32,15 +31,33 @@ * different areas one below 128TB and one above 128TB * till it reaches 512TB. One with size 128TB and the * other being 384TB. + * + * On Arm64 the address space is 256TB and no high mappings + * are supported so far. */ + #define NR_CHUNKS_128TB 8192UL /* Number of 16GB chunks for 128TB */ -#define NR_CHUNKS_384TB 24576UL /* Number of 16GB chunks for 384TB */ +#define NR_CHUNKS_256TB (NR_CHUNKS_128TB * 2UL) +#define NR_CHUNKS_384TB (NR_CHUNKS_128TB * 3UL) #define ADDR_MARK_128TB (1UL << 47) /* First address beyond 128TB */ +#define ADDR_MARK_256TB (1UL << 48) /* First address beyond 256TB */ + +#ifdef __aarch64__ +#define HIGH_ADDR_MARK ADDR_MARK_256TB +#define HIGH_ADDR_SHIFT 49 +#define NR_CHUNKS_LOW NR_CHUNKS_256TB +#define NR_CHUNKS_HIGH 0 +#else +#define HIGH_ADDR_MARK ADDR_MARK_128TB +#define HIGH_ADDR_SHIFT 48 +#define NR_CHUNKS_LOW NR_CHUNKS_128TB +#define NR_CHUNKS_HIGH NR_CHUNKS_384TB +#endif static char *hind_addr(void) { - int bits = 48 + rand() % 15; + int bits = HIGH_ADDR_SHIFT + rand() % (63 - HIGH_ADDR_SHIFT); return (char *) (1UL << bits); } @@ -50,14 +67,14 @@ static int validate_addr(char *ptr, int high_addr) unsigned long addr = (unsigned long) ptr; if (high_addr) { - if (addr < ADDR_MARK_128TB) { + if (addr < HIGH_ADDR_MARK) { printf("Bad address %lx\n", addr); return 1; } return 0; } - if (addr > ADDR_MARK_128TB) { + if (addr > HIGH_ADDR_MARK) { printf("Bad address %lx\n", addr); return 1; } @@ -79,12 +96,12 @@ static int validate_lower_address_hint(void) int main(int argc, char *argv[]) { - char *ptr[NR_CHUNKS_128TB]; - char *hptr[NR_CHUNKS_384TB]; + char *ptr[NR_CHUNKS_LOW]; + char *hptr[NR_CHUNKS_HIGH]; char *hint; unsigned long i, lchunks, hchunks; - for (i = 0; i < NR_CHUNKS_128TB; i++) { + for (i = 0; i < NR_CHUNKS_LOW; i++) { ptr[i] = mmap(NULL, MAP_CHUNK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); @@ -99,7 +116,7 @@ int main(int argc, char *argv[]) } lchunks = i; - for (i = 0; i < NR_CHUNKS_384TB; i++) { + for (i = 0; i < NR_CHUNKS_HIGH; i++) { hint = hind_addr(); hptr[i] = mmap(hint, MAP_CHUNK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -- cgit v1.2.3 From 4996976fcde4bb738ce68ca01a8b358d71aab7bb Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 31 May 2017 20:40:15 +1000 Subject: selftests: sync: Skip the test if kernel support is not found The "Sync framework" test doesn't work if the kernel has no support, obviously. Rather than reporting a failure, check for the kernel support by looking for /sys/kernel/debug/sync/sw_sync, and if not found skip the test. Signed-off-by: Michael Ellerman Reviewed-by: Gustavo Padovan Signed-off-by: Shuah Khan --- tools/testing/selftests/sync/sync_test.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/sync/sync_test.c b/tools/testing/selftests/sync/sync_test.c index 9ea08d9f0b13..62fa666e501a 100644 --- a/tools/testing/selftests/sync/sync_test.c +++ b/tools/testing/selftests/sync/sync_test.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "synctest.h" @@ -52,10 +53,22 @@ static int run_test(int (*test)(void), char *name) exit(test()); } +static int sync_api_supported(void) +{ + struct stat sbuf; + + return 0 == stat("/sys/kernel/debug/sync/sw_sync", &sbuf); +} + int main(void) { int err = 0; + if (!sync_api_supported()) { + printf("SKIP: Sync framework not supported by kernel\n"); + return 0; + } + printf("[RUN]\tTesting sync framework\n"); err += RUN_TEST(test_alloc_timeline); -- cgit v1.2.3 From 0b40808a10842131742b1646a465b877a277168a Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Fri, 26 May 2017 20:43:56 +0200 Subject: selftests: Make test_harness.h more generally available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The seccomp/test_harness.h file contains useful helpers to build tests. Moving it to the selftest directory should benefit to other test components. Keep seccomp maintainers for this file. Signed-off-by: Mickaël Salaün Acked-by: Kees Cook Acked-by: Will Drewry Cc: Andy Lutomirski Cc: Shuah Khan Link: https://lkml.kernel.org/r/CAGXu5j+8CVz8vL51DRYXqOY=xc3zuKFf=PTENe88XYHzFYidUQ@mail.gmail.com Signed-off-by: Shuah Khan --- MAINTAINERS | 1 + tools/testing/selftests/kselftest_harness.h | 535 +++++++++++++++++++++++++ tools/testing/selftests/seccomp/seccomp_bpf.c | 2 +- tools/testing/selftests/seccomp/test_harness.h | 535 ------------------------- 4 files changed, 537 insertions(+), 536 deletions(-) create mode 100644 tools/testing/selftests/kselftest_harness.h delete mode 100644 tools/testing/selftests/seccomp/test_harness.h (limited to 'tools') diff --git a/MAINTAINERS b/MAINTAINERS index 7a28acd7f525..85bafa901e4b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11495,6 +11495,7 @@ F: kernel/seccomp.c F: include/uapi/linux/seccomp.h F: include/linux/seccomp.h F: tools/testing/selftests/seccomp/* +F: tools/testing/selftests/kselftest_harness.h K: \bsecure_computing K: \bTIF_SECCOMP\b diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h new file mode 100644 index 000000000000..a786c69c7584 --- /dev/null +++ b/tools/testing/selftests/kselftest_harness.h @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by the GPLv2 license. + * + * test_harness.h: simple C unit test helper. + * + * Usage: + * #include "test_harness.h" + * TEST(standalone_test) { + * do_some_stuff; + * EXPECT_GT(10, stuff) { + * stuff_state_t state; + * enumerate_stuff_state(&state); + * TH_LOG("expectation failed with state: %s", state.msg); + * } + * more_stuff; + * ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!"); + * last_stuff; + * EXPECT_EQ(0, last_stuff); + * } + * + * FIXTURE(my_fixture) { + * mytype_t *data; + * int awesomeness_level; + * }; + * FIXTURE_SETUP(my_fixture) { + * self->data = mytype_new(); + * ASSERT_NE(NULL, self->data); + * } + * FIXTURE_TEARDOWN(my_fixture) { + * mytype_free(self->data); + * } + * TEST_F(my_fixture, data_is_good) { + * EXPECT_EQ(1, is_my_data_good(self->data)); + * } + * + * TEST_HARNESS_MAIN + * + * API inspired by code.google.com/p/googletest + */ +#ifndef TEST_HARNESS_H_ +#define TEST_HARNESS_H_ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +/* All exported functionality should be declared through this macro. */ +#define TEST_API(x) _##x + +/* + * Exported APIs + */ + +/* TEST(name) { implementation } + * Defines a test by name. + * Names must be unique and tests must not be run in parallel. The + * implementation containing block is a function and scoping should be treated + * as such. Returning early may be performed with a bare "return;" statement. + * + * EXPECT_* and ASSERT_* are valid in a TEST() { } context. + */ +#define TEST TEST_API(TEST) + +/* TEST_SIGNAL(name, signal) { implementation } + * Defines a test by name and the expected term signal. + * Names must be unique and tests must not be run in parallel. The + * implementation containing block is a function and scoping should be treated + * as such. Returning early may be performed with a bare "return;" statement. + * + * EXPECT_* and ASSERT_* are valid in a TEST() { } context. + */ +#define TEST_SIGNAL TEST_API(TEST_SIGNAL) + +/* FIXTURE(datatype name) { + * type property1; + * ... + * }; + * Defines the data provided to TEST_F()-defined tests as |self|. It should be + * populated and cleaned up using FIXTURE_SETUP and FIXTURE_TEARDOWN. + */ +#define FIXTURE TEST_API(FIXTURE) + +/* FIXTURE_DATA(datatype name) + * This call may be used when the type of the fixture data + * is needed. In general, this should not be needed unless + * the |self| is being passed to a helper directly. + */ +#define FIXTURE_DATA TEST_API(FIXTURE_DATA) + +/* FIXTURE_SETUP(fixture name) { implementation } + * Populates the required "setup" function for a fixture. An instance of the + * datatype defined with _FIXTURE_DATA will be exposed as |self| for the + * implementation. + * + * ASSERT_* are valid for use in this context and will prempt the execution + * of any dependent fixture tests. + * + * A bare "return;" statement may be used to return early. + */ +#define FIXTURE_SETUP TEST_API(FIXTURE_SETUP) + +/* FIXTURE_TEARDOWN(fixture name) { implementation } + * Populates the required "teardown" function for a fixture. An instance of the + * datatype defined with _FIXTURE_DATA will be exposed as |self| for the + * implementation to clean up. + * + * A bare "return;" statement may be used to return early. + */ +#define FIXTURE_TEARDOWN TEST_API(FIXTURE_TEARDOWN) + +/* TEST_F(fixture, name) { implementation } + * Defines a test that depends on a fixture (e.g., is part of a test case). + * Very similar to TEST() except that |self| is the setup instance of fixture's + * datatype exposed for use by the implementation. + */ +#define TEST_F TEST_API(TEST_F) + +#define TEST_F_SIGNAL TEST_API(TEST_F_SIGNAL) + +/* Use once to append a main() to the test file. E.g., + * TEST_HARNESS_MAIN + */ +#define TEST_HARNESS_MAIN TEST_API(TEST_HARNESS_MAIN) + +/* + * Operators for use in TEST and TEST_F. + * ASSERT_* calls will stop test execution immediately. + * EXPECT_* calls will emit a failure warning, note it, and continue. + */ + +/* ASSERT_EQ(expected, measured): expected == measured */ +#define ASSERT_EQ TEST_API(ASSERT_EQ) +/* ASSERT_NE(expected, measured): expected != measured */ +#define ASSERT_NE TEST_API(ASSERT_NE) +/* ASSERT_LT(expected, measured): expected < measured */ +#define ASSERT_LT TEST_API(ASSERT_LT) +/* ASSERT_LE(expected, measured): expected <= measured */ +#define ASSERT_LE TEST_API(ASSERT_LE) +/* ASSERT_GT(expected, measured): expected > measured */ +#define ASSERT_GT TEST_API(ASSERT_GT) +/* ASSERT_GE(expected, measured): expected >= measured */ +#define ASSERT_GE TEST_API(ASSERT_GE) +/* ASSERT_NULL(measured): NULL == measured */ +#define ASSERT_NULL TEST_API(ASSERT_NULL) +/* ASSERT_TRUE(measured): measured != 0 */ +#define ASSERT_TRUE TEST_API(ASSERT_TRUE) +/* ASSERT_FALSE(measured): measured == 0 */ +#define ASSERT_FALSE TEST_API(ASSERT_FALSE) +/* ASSERT_STREQ(expected, measured): !strcmp(expected, measured) */ +#define ASSERT_STREQ TEST_API(ASSERT_STREQ) +/* ASSERT_STRNE(expected, measured): strcmp(expected, measured) */ +#define ASSERT_STRNE TEST_API(ASSERT_STRNE) +/* EXPECT_EQ(expected, measured): expected == measured */ +#define EXPECT_EQ TEST_API(EXPECT_EQ) +/* EXPECT_NE(expected, measured): expected != measured */ +#define EXPECT_NE TEST_API(EXPECT_NE) +/* EXPECT_LT(expected, measured): expected < measured */ +#define EXPECT_LT TEST_API(EXPECT_LT) +/* EXPECT_LE(expected, measured): expected <= measured */ +#define EXPECT_LE TEST_API(EXPECT_LE) +/* EXPECT_GT(expected, measured): expected > measured */ +#define EXPECT_GT TEST_API(EXPECT_GT) +/* EXPECT_GE(expected, measured): expected >= measured */ +#define EXPECT_GE TEST_API(EXPECT_GE) +/* EXPECT_NULL(measured): NULL == measured */ +#define EXPECT_NULL TEST_API(EXPECT_NULL) +/* EXPECT_TRUE(measured): 0 != measured */ +#define EXPECT_TRUE TEST_API(EXPECT_TRUE) +/* EXPECT_FALSE(measured): 0 == measured */ +#define EXPECT_FALSE TEST_API(EXPECT_FALSE) +/* EXPECT_STREQ(expected, measured): !strcmp(expected, measured) */ +#define EXPECT_STREQ TEST_API(EXPECT_STREQ) +/* EXPECT_STRNE(expected, measured): strcmp(expected, measured) */ +#define EXPECT_STRNE TEST_API(EXPECT_STRNE) + +/* TH_LOG(format, ...) + * Optional debug logging function available for use in tests. + * Logging may be enabled or disabled by defining TH_LOG_ENABLED. + * E.g., #define TH_LOG_ENABLED 1 + * If no definition is provided, logging is enabled by default. + */ +#define TH_LOG TEST_API(TH_LOG) + +/* + * Internal implementation. + * + */ + +/* Utilities exposed to the test definitions */ +#ifndef TH_LOG_STREAM +# define TH_LOG_STREAM stderr +#endif + +#ifndef TH_LOG_ENABLED +# define TH_LOG_ENABLED 1 +#endif + +#define _TH_LOG(fmt, ...) do { \ + if (TH_LOG_ENABLED) \ + __TH_LOG(fmt, ##__VA_ARGS__); \ +} while (0) + +/* Unconditional logger for internal use. */ +#define __TH_LOG(fmt, ...) \ + fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \ + __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) + +/* Defines the test function and creates the registration stub. */ +#define _TEST(test_name) __TEST_IMPL(test_name, -1) + +#define _TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal) + +#define __TEST_IMPL(test_name, _signal) \ + static void test_name(struct __test_metadata *_metadata); \ + static struct __test_metadata _##test_name##_object = \ + { name: "global." #test_name, \ + fn: &test_name, termsig: _signal }; \ + static void __attribute__((constructor)) _register_##test_name(void) \ + { \ + __register_test(&_##test_name##_object); \ + } \ + static void test_name( \ + struct __test_metadata __attribute__((unused)) *_metadata) + +/* Wraps the struct name so we have one less argument to pass around. */ +#define _FIXTURE_DATA(fixture_name) struct _test_data_##fixture_name + +/* Called once per fixture to setup the data and register. */ +#define _FIXTURE(fixture_name) \ + static void __attribute__((constructor)) \ + _register_##fixture_name##_data(void) \ + { \ + __fixture_count++; \ + } \ + _FIXTURE_DATA(fixture_name) + +/* Prepares the setup function for the fixture. |_metadata| is included + * so that ASSERT_* work as a convenience. + */ +#define _FIXTURE_SETUP(fixture_name) \ + void fixture_name##_setup( \ + struct __test_metadata __attribute__((unused)) *_metadata, \ + _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) +#define _FIXTURE_TEARDOWN(fixture_name) \ + void fixture_name##_teardown( \ + struct __test_metadata __attribute__((unused)) *_metadata, \ + _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) + +/* Emits test registration and helpers for fixture-based test + * cases. + * TODO(wad) register fixtures on dedicated test lists. + */ +#define _TEST_F(fixture_name, test_name) \ + __TEST_F_IMPL(fixture_name, test_name, -1) + +#define _TEST_F_SIGNAL(fixture_name, test_name, signal) \ + __TEST_F_IMPL(fixture_name, test_name, signal) + +#define __TEST_F_IMPL(fixture_name, test_name, signal) \ + static void fixture_name##_##test_name( \ + struct __test_metadata *_metadata, \ + _FIXTURE_DATA(fixture_name) *self); \ + static inline void wrapper_##fixture_name##_##test_name( \ + struct __test_metadata *_metadata) \ + { \ + /* fixture data is alloced, setup, and torn down per call. */ \ + _FIXTURE_DATA(fixture_name) self; \ + memset(&self, 0, sizeof(_FIXTURE_DATA(fixture_name))); \ + fixture_name##_setup(_metadata, &self); \ + /* Let setup failure terminate early. */ \ + if (!_metadata->passed) \ + return; \ + fixture_name##_##test_name(_metadata, &self); \ + fixture_name##_teardown(_metadata, &self); \ + } \ + static struct __test_metadata \ + _##fixture_name##_##test_name##_object = { \ + name: #fixture_name "." #test_name, \ + fn: &wrapper_##fixture_name##_##test_name, \ + termsig: signal, \ + }; \ + static void __attribute__((constructor)) \ + _register_##fixture_name##_##test_name(void) \ + { \ + __register_test(&_##fixture_name##_##test_name##_object); \ + } \ + static void fixture_name##_##test_name( \ + struct __test_metadata __attribute__((unused)) *_metadata, \ + _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) + +/* Exports a simple wrapper to run the test harness. */ +#define _TEST_HARNESS_MAIN \ + static void __attribute__((constructor)) \ + __constructor_order_last(void) \ + { \ + if (!__constructor_order) \ + __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \ + } \ + int main(int argc, char **argv) { \ + return test_harness_run(argc, argv); \ + } + +#define _ASSERT_EQ(_expected, _seen) \ + __EXPECT(_expected, _seen, ==, 1) +#define _ASSERT_NE(_expected, _seen) \ + __EXPECT(_expected, _seen, !=, 1) +#define _ASSERT_LT(_expected, _seen) \ + __EXPECT(_expected, _seen, <, 1) +#define _ASSERT_LE(_expected, _seen) \ + __EXPECT(_expected, _seen, <=, 1) +#define _ASSERT_GT(_expected, _seen) \ + __EXPECT(_expected, _seen, >, 1) +#define _ASSERT_GE(_expected, _seen) \ + __EXPECT(_expected, _seen, >=, 1) +#define _ASSERT_NULL(_seen) \ + __EXPECT(NULL, _seen, ==, 1) + +#define _ASSERT_TRUE(_seen) \ + _ASSERT_NE(0, _seen) +#define _ASSERT_FALSE(_seen) \ + _ASSERT_EQ(0, _seen) +#define _ASSERT_STREQ(_expected, _seen) \ + __EXPECT_STR(_expected, _seen, ==, 1) +#define _ASSERT_STRNE(_expected, _seen) \ + __EXPECT_STR(_expected, _seen, !=, 1) + +#define _EXPECT_EQ(_expected, _seen) \ + __EXPECT(_expected, _seen, ==, 0) +#define _EXPECT_NE(_expected, _seen) \ + __EXPECT(_expected, _seen, !=, 0) +#define _EXPECT_LT(_expected, _seen) \ + __EXPECT(_expected, _seen, <, 0) +#define _EXPECT_LE(_expected, _seen) \ + __EXPECT(_expected, _seen, <=, 0) +#define _EXPECT_GT(_expected, _seen) \ + __EXPECT(_expected, _seen, >, 0) +#define _EXPECT_GE(_expected, _seen) \ + __EXPECT(_expected, _seen, >=, 0) + +#define _EXPECT_NULL(_seen) \ + __EXPECT(NULL, _seen, ==, 0) +#define _EXPECT_TRUE(_seen) \ + _EXPECT_NE(0, _seen) +#define _EXPECT_FALSE(_seen) \ + _EXPECT_EQ(0, _seen) + +#define _EXPECT_STREQ(_expected, _seen) \ + __EXPECT_STR(_expected, _seen, ==, 0) +#define _EXPECT_STRNE(_expected, _seen) \ + __EXPECT_STR(_expected, _seen, !=, 0) + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +/* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is + * not thread-safe, but it should be fine in most sane test scenarios. + * + * Using __bail(), which optionally abort()s, is the easiest way to early + * return while still providing an optional block to the API consumer. + */ +#define OPTIONAL_HANDLER(_assert) \ + for (; _metadata->trigger; _metadata->trigger = __bail(_assert)) + +#define __EXPECT(_expected, _seen, _t, _assert) do { \ + /* Avoid multiple evaluation of the cases */ \ + __typeof__(_expected) __exp = (_expected); \ + __typeof__(_seen) __seen = (_seen); \ + if (!(__exp _t __seen)) { \ + unsigned long long __exp_print = (uintptr_t)__exp; \ + unsigned long long __seen_print = (uintptr_t)__seen; \ + __TH_LOG("Expected %s (%llu) %s %s (%llu)", \ + #_expected, __exp_print, #_t, \ + #_seen, __seen_print); \ + _metadata->passed = 0; \ + /* Ensure the optional handler is triggered */ \ + _metadata->trigger = 1; \ + } \ +} while (0); OPTIONAL_HANDLER(_assert) + +#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \ + const char *__exp = (_expected); \ + const char *__seen = (_seen); \ + if (!(strcmp(__exp, __seen) _t 0)) { \ + __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \ + _metadata->passed = 0; \ + _metadata->trigger = 1; \ + } \ +} while (0); OPTIONAL_HANDLER(_assert) + +/* Contains all the information for test execution and status checking. */ +struct __test_metadata { + const char *name; + void (*fn)(struct __test_metadata *); + int termsig; + int passed; + int trigger; /* extra handler after the evaluation */ + struct __test_metadata *prev, *next; +}; + +/* Storage for the (global) tests to be run. */ +static struct __test_metadata *__test_list; +static unsigned int __test_count; +static unsigned int __fixture_count; +static int __constructor_order; + +#define _CONSTRUCTOR_ORDER_FORWARD 1 +#define _CONSTRUCTOR_ORDER_BACKWARD -1 + +/* + * Since constructors are called in reverse order, reverse the test + * list so tests are run in source declaration order. + * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html + * However, it seems not all toolchains do this correctly, so use + * __constructor_order to detect which direction is called first + * and adjust list building logic to get things running in the right + * direction. + */ +static inline void __register_test(struct __test_metadata *t) +{ + __test_count++; + /* Circular linked list where only prev is circular. */ + if (__test_list == NULL) { + __test_list = t; + t->next = NULL; + t->prev = t; + return; + } + if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { + t->next = NULL; + t->prev = __test_list->prev; + t->prev->next = t; + __test_list->prev = t; + } else { + t->next = __test_list; + t->next->prev = t; + t->prev = t; + __test_list = t; + } +} + +static inline int __bail(int for_realz) +{ + if (for_realz) + abort(); + return 0; +} + +void __run_test(struct __test_metadata *t) +{ + pid_t child_pid; + int status; + + t->passed = 1; + t->trigger = 0; + printf("[ RUN ] %s\n", t->name); + child_pid = fork(); + if (child_pid < 0) { + printf("ERROR SPAWNING TEST CHILD\n"); + t->passed = 0; + } else if (child_pid == 0) { + t->fn(t); + _exit(t->passed); + } else { + /* TODO(wad) add timeout support. */ + waitpid(child_pid, &status, 0); + if (WIFEXITED(status)) { + t->passed = t->termsig == -1 ? WEXITSTATUS(status) : 0; + if (t->termsig != -1) { + fprintf(TH_LOG_STREAM, + "%s: Test exited normally " + "instead of by signal (code: %d)\n", + t->name, + WEXITSTATUS(status)); + } + } else if (WIFSIGNALED(status)) { + t->passed = 0; + if (WTERMSIG(status) == SIGABRT) { + fprintf(TH_LOG_STREAM, + "%s: Test terminated by assertion\n", + t->name); + } else if (WTERMSIG(status) == t->termsig) { + t->passed = 1; + } else { + fprintf(TH_LOG_STREAM, + "%s: Test terminated unexpectedly " + "by signal %d\n", + t->name, + WTERMSIG(status)); + } + } else { + fprintf(TH_LOG_STREAM, + "%s: Test ended in some other way [%u]\n", + t->name, + status); + } + } + printf("[ %4s ] %s\n", (t->passed ? "OK" : "FAIL"), t->name); +} + +static int test_harness_run(int __attribute__((unused)) argc, + char __attribute__((unused)) **argv) +{ + struct __test_metadata *t; + int ret = 0; + unsigned int count = 0; + unsigned int pass_count = 0; + + /* TODO(wad) add optional arguments similar to gtest. */ + printf("[==========] Running %u tests from %u test cases.\n", + __test_count, __fixture_count + 1); + for (t = __test_list; t; t = t->next) { + count++; + __run_test(t); + if (t->passed) + pass_count++; + else + ret = 1; + } + printf("[==========] %u / %u tests passed.\n", pass_count, count); + printf("[ %s ]\n", (ret ? "FAILED" : "PASSED")); + return ret; +} + +static void __attribute__((constructor)) __constructor_order_first(void) +{ + if (!__constructor_order) + __constructor_order = _CONSTRUCTOR_ORDER_FORWARD; +} + +#endif /* TEST_HARNESS_H_ */ diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 03f1fa495d74..7ba94efb24fd 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -37,7 +37,7 @@ #include #include -#include "test_harness.h" +#include "../kselftest_harness.h" #ifndef PR_SET_PTRACER # define PR_SET_PTRACER 0x59616d61 diff --git a/tools/testing/selftests/seccomp/test_harness.h b/tools/testing/selftests/seccomp/test_harness.h deleted file mode 100644 index a786c69c7584..000000000000 --- a/tools/testing/selftests/seccomp/test_harness.h +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by the GPLv2 license. - * - * test_harness.h: simple C unit test helper. - * - * Usage: - * #include "test_harness.h" - * TEST(standalone_test) { - * do_some_stuff; - * EXPECT_GT(10, stuff) { - * stuff_state_t state; - * enumerate_stuff_state(&state); - * TH_LOG("expectation failed with state: %s", state.msg); - * } - * more_stuff; - * ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!"); - * last_stuff; - * EXPECT_EQ(0, last_stuff); - * } - * - * FIXTURE(my_fixture) { - * mytype_t *data; - * int awesomeness_level; - * }; - * FIXTURE_SETUP(my_fixture) { - * self->data = mytype_new(); - * ASSERT_NE(NULL, self->data); - * } - * FIXTURE_TEARDOWN(my_fixture) { - * mytype_free(self->data); - * } - * TEST_F(my_fixture, data_is_good) { - * EXPECT_EQ(1, is_my_data_good(self->data)); - * } - * - * TEST_HARNESS_MAIN - * - * API inspired by code.google.com/p/googletest - */ -#ifndef TEST_HARNESS_H_ -#define TEST_HARNESS_H_ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include - -/* All exported functionality should be declared through this macro. */ -#define TEST_API(x) _##x - -/* - * Exported APIs - */ - -/* TEST(name) { implementation } - * Defines a test by name. - * Names must be unique and tests must not be run in parallel. The - * implementation containing block is a function and scoping should be treated - * as such. Returning early may be performed with a bare "return;" statement. - * - * EXPECT_* and ASSERT_* are valid in a TEST() { } context. - */ -#define TEST TEST_API(TEST) - -/* TEST_SIGNAL(name, signal) { implementation } - * Defines a test by name and the expected term signal. - * Names must be unique and tests must not be run in parallel. The - * implementation containing block is a function and scoping should be treated - * as such. Returning early may be performed with a bare "return;" statement. - * - * EXPECT_* and ASSERT_* are valid in a TEST() { } context. - */ -#define TEST_SIGNAL TEST_API(TEST_SIGNAL) - -/* FIXTURE(datatype name) { - * type property1; - * ... - * }; - * Defines the data provided to TEST_F()-defined tests as |self|. It should be - * populated and cleaned up using FIXTURE_SETUP and FIXTURE_TEARDOWN. - */ -#define FIXTURE TEST_API(FIXTURE) - -/* FIXTURE_DATA(datatype name) - * This call may be used when the type of the fixture data - * is needed. In general, this should not be needed unless - * the |self| is being passed to a helper directly. - */ -#define FIXTURE_DATA TEST_API(FIXTURE_DATA) - -/* FIXTURE_SETUP(fixture name) { implementation } - * Populates the required "setup" function for a fixture. An instance of the - * datatype defined with _FIXTURE_DATA will be exposed as |self| for the - * implementation. - * - * ASSERT_* are valid for use in this context and will prempt the execution - * of any dependent fixture tests. - * - * A bare "return;" statement may be used to return early. - */ -#define FIXTURE_SETUP TEST_API(FIXTURE_SETUP) - -/* FIXTURE_TEARDOWN(fixture name) { implementation } - * Populates the required "teardown" function for a fixture. An instance of the - * datatype defined with _FIXTURE_DATA will be exposed as |self| for the - * implementation to clean up. - * - * A bare "return;" statement may be used to return early. - */ -#define FIXTURE_TEARDOWN TEST_API(FIXTURE_TEARDOWN) - -/* TEST_F(fixture, name) { implementation } - * Defines a test that depends on a fixture (e.g., is part of a test case). - * Very similar to TEST() except that |self| is the setup instance of fixture's - * datatype exposed for use by the implementation. - */ -#define TEST_F TEST_API(TEST_F) - -#define TEST_F_SIGNAL TEST_API(TEST_F_SIGNAL) - -/* Use once to append a main() to the test file. E.g., - * TEST_HARNESS_MAIN - */ -#define TEST_HARNESS_MAIN TEST_API(TEST_HARNESS_MAIN) - -/* - * Operators for use in TEST and TEST_F. - * ASSERT_* calls will stop test execution immediately. - * EXPECT_* calls will emit a failure warning, note it, and continue. - */ - -/* ASSERT_EQ(expected, measured): expected == measured */ -#define ASSERT_EQ TEST_API(ASSERT_EQ) -/* ASSERT_NE(expected, measured): expected != measured */ -#define ASSERT_NE TEST_API(ASSERT_NE) -/* ASSERT_LT(expected, measured): expected < measured */ -#define ASSERT_LT TEST_API(ASSERT_LT) -/* ASSERT_LE(expected, measured): expected <= measured */ -#define ASSERT_LE TEST_API(ASSERT_LE) -/* ASSERT_GT(expected, measured): expected > measured */ -#define ASSERT_GT TEST_API(ASSERT_GT) -/* ASSERT_GE(expected, measured): expected >= measured */ -#define ASSERT_GE TEST_API(ASSERT_GE) -/* ASSERT_NULL(measured): NULL == measured */ -#define ASSERT_NULL TEST_API(ASSERT_NULL) -/* ASSERT_TRUE(measured): measured != 0 */ -#define ASSERT_TRUE TEST_API(ASSERT_TRUE) -/* ASSERT_FALSE(measured): measured == 0 */ -#define ASSERT_FALSE TEST_API(ASSERT_FALSE) -/* ASSERT_STREQ(expected, measured): !strcmp(expected, measured) */ -#define ASSERT_STREQ TEST_API(ASSERT_STREQ) -/* ASSERT_STRNE(expected, measured): strcmp(expected, measured) */ -#define ASSERT_STRNE TEST_API(ASSERT_STRNE) -/* EXPECT_EQ(expected, measured): expected == measured */ -#define EXPECT_EQ TEST_API(EXPECT_EQ) -/* EXPECT_NE(expected, measured): expected != measured */ -#define EXPECT_NE TEST_API(EXPECT_NE) -/* EXPECT_LT(expected, measured): expected < measured */ -#define EXPECT_LT TEST_API(EXPECT_LT) -/* EXPECT_LE(expected, measured): expected <= measured */ -#define EXPECT_LE TEST_API(EXPECT_LE) -/* EXPECT_GT(expected, measured): expected > measured */ -#define EXPECT_GT TEST_API(EXPECT_GT) -/* EXPECT_GE(expected, measured): expected >= measured */ -#define EXPECT_GE TEST_API(EXPECT_GE) -/* EXPECT_NULL(measured): NULL == measured */ -#define EXPECT_NULL TEST_API(EXPECT_NULL) -/* EXPECT_TRUE(measured): 0 != measured */ -#define EXPECT_TRUE TEST_API(EXPECT_TRUE) -/* EXPECT_FALSE(measured): 0 == measured */ -#define EXPECT_FALSE TEST_API(EXPECT_FALSE) -/* EXPECT_STREQ(expected, measured): !strcmp(expected, measured) */ -#define EXPECT_STREQ TEST_API(EXPECT_STREQ) -/* EXPECT_STRNE(expected, measured): strcmp(expected, measured) */ -#define EXPECT_STRNE TEST_API(EXPECT_STRNE) - -/* TH_LOG(format, ...) - * Optional debug logging function available for use in tests. - * Logging may be enabled or disabled by defining TH_LOG_ENABLED. - * E.g., #define TH_LOG_ENABLED 1 - * If no definition is provided, logging is enabled by default. - */ -#define TH_LOG TEST_API(TH_LOG) - -/* - * Internal implementation. - * - */ - -/* Utilities exposed to the test definitions */ -#ifndef TH_LOG_STREAM -# define TH_LOG_STREAM stderr -#endif - -#ifndef TH_LOG_ENABLED -# define TH_LOG_ENABLED 1 -#endif - -#define _TH_LOG(fmt, ...) do { \ - if (TH_LOG_ENABLED) \ - __TH_LOG(fmt, ##__VA_ARGS__); \ -} while (0) - -/* Unconditional logger for internal use. */ -#define __TH_LOG(fmt, ...) \ - fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \ - __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) - -/* Defines the test function and creates the registration stub. */ -#define _TEST(test_name) __TEST_IMPL(test_name, -1) - -#define _TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal) - -#define __TEST_IMPL(test_name, _signal) \ - static void test_name(struct __test_metadata *_metadata); \ - static struct __test_metadata _##test_name##_object = \ - { name: "global." #test_name, \ - fn: &test_name, termsig: _signal }; \ - static void __attribute__((constructor)) _register_##test_name(void) \ - { \ - __register_test(&_##test_name##_object); \ - } \ - static void test_name( \ - struct __test_metadata __attribute__((unused)) *_metadata) - -/* Wraps the struct name so we have one less argument to pass around. */ -#define _FIXTURE_DATA(fixture_name) struct _test_data_##fixture_name - -/* Called once per fixture to setup the data and register. */ -#define _FIXTURE(fixture_name) \ - static void __attribute__((constructor)) \ - _register_##fixture_name##_data(void) \ - { \ - __fixture_count++; \ - } \ - _FIXTURE_DATA(fixture_name) - -/* Prepares the setup function for the fixture. |_metadata| is included - * so that ASSERT_* work as a convenience. - */ -#define _FIXTURE_SETUP(fixture_name) \ - void fixture_name##_setup( \ - struct __test_metadata __attribute__((unused)) *_metadata, \ - _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) -#define _FIXTURE_TEARDOWN(fixture_name) \ - void fixture_name##_teardown( \ - struct __test_metadata __attribute__((unused)) *_metadata, \ - _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) - -/* Emits test registration and helpers for fixture-based test - * cases. - * TODO(wad) register fixtures on dedicated test lists. - */ -#define _TEST_F(fixture_name, test_name) \ - __TEST_F_IMPL(fixture_name, test_name, -1) - -#define _TEST_F_SIGNAL(fixture_name, test_name, signal) \ - __TEST_F_IMPL(fixture_name, test_name, signal) - -#define __TEST_F_IMPL(fixture_name, test_name, signal) \ - static void fixture_name##_##test_name( \ - struct __test_metadata *_metadata, \ - _FIXTURE_DATA(fixture_name) *self); \ - static inline void wrapper_##fixture_name##_##test_name( \ - struct __test_metadata *_metadata) \ - { \ - /* fixture data is alloced, setup, and torn down per call. */ \ - _FIXTURE_DATA(fixture_name) self; \ - memset(&self, 0, sizeof(_FIXTURE_DATA(fixture_name))); \ - fixture_name##_setup(_metadata, &self); \ - /* Let setup failure terminate early. */ \ - if (!_metadata->passed) \ - return; \ - fixture_name##_##test_name(_metadata, &self); \ - fixture_name##_teardown(_metadata, &self); \ - } \ - static struct __test_metadata \ - _##fixture_name##_##test_name##_object = { \ - name: #fixture_name "." #test_name, \ - fn: &wrapper_##fixture_name##_##test_name, \ - termsig: signal, \ - }; \ - static void __attribute__((constructor)) \ - _register_##fixture_name##_##test_name(void) \ - { \ - __register_test(&_##fixture_name##_##test_name##_object); \ - } \ - static void fixture_name##_##test_name( \ - struct __test_metadata __attribute__((unused)) *_metadata, \ - _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) - -/* Exports a simple wrapper to run the test harness. */ -#define _TEST_HARNESS_MAIN \ - static void __attribute__((constructor)) \ - __constructor_order_last(void) \ - { \ - if (!__constructor_order) \ - __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \ - } \ - int main(int argc, char **argv) { \ - return test_harness_run(argc, argv); \ - } - -#define _ASSERT_EQ(_expected, _seen) \ - __EXPECT(_expected, _seen, ==, 1) -#define _ASSERT_NE(_expected, _seen) \ - __EXPECT(_expected, _seen, !=, 1) -#define _ASSERT_LT(_expected, _seen) \ - __EXPECT(_expected, _seen, <, 1) -#define _ASSERT_LE(_expected, _seen) \ - __EXPECT(_expected, _seen, <=, 1) -#define _ASSERT_GT(_expected, _seen) \ - __EXPECT(_expected, _seen, >, 1) -#define _ASSERT_GE(_expected, _seen) \ - __EXPECT(_expected, _seen, >=, 1) -#define _ASSERT_NULL(_seen) \ - __EXPECT(NULL, _seen, ==, 1) - -#define _ASSERT_TRUE(_seen) \ - _ASSERT_NE(0, _seen) -#define _ASSERT_FALSE(_seen) \ - _ASSERT_EQ(0, _seen) -#define _ASSERT_STREQ(_expected, _seen) \ - __EXPECT_STR(_expected, _seen, ==, 1) -#define _ASSERT_STRNE(_expected, _seen) \ - __EXPECT_STR(_expected, _seen, !=, 1) - -#define _EXPECT_EQ(_expected, _seen) \ - __EXPECT(_expected, _seen, ==, 0) -#define _EXPECT_NE(_expected, _seen) \ - __EXPECT(_expected, _seen, !=, 0) -#define _EXPECT_LT(_expected, _seen) \ - __EXPECT(_expected, _seen, <, 0) -#define _EXPECT_LE(_expected, _seen) \ - __EXPECT(_expected, _seen, <=, 0) -#define _EXPECT_GT(_expected, _seen) \ - __EXPECT(_expected, _seen, >, 0) -#define _EXPECT_GE(_expected, _seen) \ - __EXPECT(_expected, _seen, >=, 0) - -#define _EXPECT_NULL(_seen) \ - __EXPECT(NULL, _seen, ==, 0) -#define _EXPECT_TRUE(_seen) \ - _EXPECT_NE(0, _seen) -#define _EXPECT_FALSE(_seen) \ - _EXPECT_EQ(0, _seen) - -#define _EXPECT_STREQ(_expected, _seen) \ - __EXPECT_STR(_expected, _seen, ==, 0) -#define _EXPECT_STRNE(_expected, _seen) \ - __EXPECT_STR(_expected, _seen, !=, 0) - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -/* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is - * not thread-safe, but it should be fine in most sane test scenarios. - * - * Using __bail(), which optionally abort()s, is the easiest way to early - * return while still providing an optional block to the API consumer. - */ -#define OPTIONAL_HANDLER(_assert) \ - for (; _metadata->trigger; _metadata->trigger = __bail(_assert)) - -#define __EXPECT(_expected, _seen, _t, _assert) do { \ - /* Avoid multiple evaluation of the cases */ \ - __typeof__(_expected) __exp = (_expected); \ - __typeof__(_seen) __seen = (_seen); \ - if (!(__exp _t __seen)) { \ - unsigned long long __exp_print = (uintptr_t)__exp; \ - unsigned long long __seen_print = (uintptr_t)__seen; \ - __TH_LOG("Expected %s (%llu) %s %s (%llu)", \ - #_expected, __exp_print, #_t, \ - #_seen, __seen_print); \ - _metadata->passed = 0; \ - /* Ensure the optional handler is triggered */ \ - _metadata->trigger = 1; \ - } \ -} while (0); OPTIONAL_HANDLER(_assert) - -#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \ - const char *__exp = (_expected); \ - const char *__seen = (_seen); \ - if (!(strcmp(__exp, __seen) _t 0)) { \ - __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \ - _metadata->passed = 0; \ - _metadata->trigger = 1; \ - } \ -} while (0); OPTIONAL_HANDLER(_assert) - -/* Contains all the information for test execution and status checking. */ -struct __test_metadata { - const char *name; - void (*fn)(struct __test_metadata *); - int termsig; - int passed; - int trigger; /* extra handler after the evaluation */ - struct __test_metadata *prev, *next; -}; - -/* Storage for the (global) tests to be run. */ -static struct __test_metadata *__test_list; -static unsigned int __test_count; -static unsigned int __fixture_count; -static int __constructor_order; - -#define _CONSTRUCTOR_ORDER_FORWARD 1 -#define _CONSTRUCTOR_ORDER_BACKWARD -1 - -/* - * Since constructors are called in reverse order, reverse the test - * list so tests are run in source declaration order. - * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html - * However, it seems not all toolchains do this correctly, so use - * __constructor_order to detect which direction is called first - * and adjust list building logic to get things running in the right - * direction. - */ -static inline void __register_test(struct __test_metadata *t) -{ - __test_count++; - /* Circular linked list where only prev is circular. */ - if (__test_list == NULL) { - __test_list = t; - t->next = NULL; - t->prev = t; - return; - } - if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { - t->next = NULL; - t->prev = __test_list->prev; - t->prev->next = t; - __test_list->prev = t; - } else { - t->next = __test_list; - t->next->prev = t; - t->prev = t; - __test_list = t; - } -} - -static inline int __bail(int for_realz) -{ - if (for_realz) - abort(); - return 0; -} - -void __run_test(struct __test_metadata *t) -{ - pid_t child_pid; - int status; - - t->passed = 1; - t->trigger = 0; - printf("[ RUN ] %s\n", t->name); - child_pid = fork(); - if (child_pid < 0) { - printf("ERROR SPAWNING TEST CHILD\n"); - t->passed = 0; - } else if (child_pid == 0) { - t->fn(t); - _exit(t->passed); - } else { - /* TODO(wad) add timeout support. */ - waitpid(child_pid, &status, 0); - if (WIFEXITED(status)) { - t->passed = t->termsig == -1 ? WEXITSTATUS(status) : 0; - if (t->termsig != -1) { - fprintf(TH_LOG_STREAM, - "%s: Test exited normally " - "instead of by signal (code: %d)\n", - t->name, - WEXITSTATUS(status)); - } - } else if (WIFSIGNALED(status)) { - t->passed = 0; - if (WTERMSIG(status) == SIGABRT) { - fprintf(TH_LOG_STREAM, - "%s: Test terminated by assertion\n", - t->name); - } else if (WTERMSIG(status) == t->termsig) { - t->passed = 1; - } else { - fprintf(TH_LOG_STREAM, - "%s: Test terminated unexpectedly " - "by signal %d\n", - t->name, - WTERMSIG(status)); - } - } else { - fprintf(TH_LOG_STREAM, - "%s: Test ended in some other way [%u]\n", - t->name, - status); - } - } - printf("[ %4s ] %s\n", (t->passed ? "OK" : "FAIL"), t->name); -} - -static int test_harness_run(int __attribute__((unused)) argc, - char __attribute__((unused)) **argv) -{ - struct __test_metadata *t; - int ret = 0; - unsigned int count = 0; - unsigned int pass_count = 0; - - /* TODO(wad) add optional arguments similar to gtest. */ - printf("[==========] Running %u tests from %u test cases.\n", - __test_count, __fixture_count + 1); - for (t = __test_list; t; t = t->next) { - count++; - __run_test(t); - if (t->passed) - pass_count++; - else - ret = 1; - } - printf("[==========] %u / %u tests passed.\n", pass_count, count); - printf("[ %s ]\n", (ret ? "FAILED" : "PASSED")); - return ret; -} - -static void __attribute__((constructor)) __constructor_order_first(void) -{ - if (!__constructor_order) - __constructor_order = _CONSTRUCTOR_ORDER_FORWARD; -} - -#endif /* TEST_HARNESS_H_ */ -- cgit v1.2.3 From dfa47d31fa0a5120c53c48da1b2a15dab3b8ea8c Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Fri, 26 May 2017 20:43:57 +0200 Subject: selftests: Cosmetic renames in kselftest_harness.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the content consistent with the new name. Signed-off-by: Mickaël Salaün Acked-by: Kees Cook Cc: Andy Lutomirski Cc: Shuah Khan Cc: Will Drewry Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index a786c69c7584..171e70aead9c 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -2,10 +2,10 @@ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by the GPLv2 license. * - * test_harness.h: simple C unit test helper. + * kselftest_harness.h: simple C unit test helper. * * Usage: - * #include "test_harness.h" + * #include "../kselftest_harness.h" * TEST(standalone_test) { * do_some_stuff; * EXPECT_GT(10, stuff) { @@ -38,8 +38,9 @@ * * API inspired by code.google.com/p/googletest */ -#ifndef TEST_HARNESS_H_ -#define TEST_HARNESS_H_ + +#ifndef __KSELFTEST_HARNESS_H +#define __KSELFTEST_HARNESS_H #define _GNU_SOURCE #include @@ -532,4 +533,4 @@ static void __attribute__((constructor)) __constructor_order_first(void) __constructor_order = _CONSTRUCTOR_ORDER_FORWARD; } -#endif /* TEST_HARNESS_H_ */ +#endif /* __KSELFTEST_HARNESS_H */ -- cgit v1.2.3 From 1256a525573120a79d5893b7342285f088b47dcc Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Fri, 26 May 2017 20:44:01 +0200 Subject: selftests: Remove the TEST_API() wrapper from kselftest_harness.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the TEST_API() wrapper to expose the underlying macro arguments to the documentation tools. Signed-off-by: Mickaël Salaün Acked-by: Kees Cook Cc: Andy Lutomirski Cc: Jonathan Corbet Cc: Kees Cook Cc: Shuah Khan Cc: Will Drewry Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest_harness.h | 355 ++++++++++++---------------- 1 file changed, 150 insertions(+), 205 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 171e70aead9c..45f807ce37e1 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -51,12 +51,31 @@ #include #include -/* All exported functionality should be declared through this macro. */ -#define TEST_API(x) _##x -/* - * Exported APIs +/* Utilities exposed to the test definitions */ +#ifndef TH_LOG_STREAM +# define TH_LOG_STREAM stderr +#endif + +#ifndef TH_LOG_ENABLED +# define TH_LOG_ENABLED 1 +#endif + +/* TH_LOG(format, ...) + * Optional debug logging function available for use in tests. + * Logging may be enabled or disabled by defining TH_LOG_ENABLED. + * E.g., #define TH_LOG_ENABLED 1 + * If no definition is provided, logging is enabled by default. */ +#define TH_LOG(fmt, ...) do { \ + if (TH_LOG_ENABLED) \ + __TH_LOG(fmt, ##__VA_ARGS__); \ +} while (0) + +/* Unconditional logger for internal use. */ +#define __TH_LOG(fmt, ...) \ + fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \ + __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) /* TEST(name) { implementation } * Defines a test by name. @@ -66,7 +85,8 @@ * * EXPECT_* and ASSERT_* are valid in a TEST() { } context. */ -#define TEST TEST_API(TEST) +/* Defines the test function and creates the registration stub. */ +#define TEST(test_name) __TEST_IMPL(test_name, -1) /* TEST_SIGNAL(name, signal) { implementation } * Defines a test by name and the expected term signal. @@ -76,7 +96,27 @@ * * EXPECT_* and ASSERT_* are valid in a TEST() { } context. */ -#define TEST_SIGNAL TEST_API(TEST_SIGNAL) +#define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal) + +#define __TEST_IMPL(test_name, _signal) \ + static void test_name(struct __test_metadata *_metadata); \ + static struct __test_metadata _##test_name##_object = \ + { name: "global." #test_name, \ + fn: &test_name, termsig: _signal }; \ + static void __attribute__((constructor)) _register_##test_name(void) \ + { \ + __register_test(&_##test_name##_object); \ + } \ + static void test_name( \ + struct __test_metadata __attribute__((unused)) *_metadata) + +/* FIXTURE_DATA(datatype name) + * This call may be used when the type of the fixture data + * is needed. In general, this should not be needed unless + * the |self| is being passed to a helper directly. + */ +/* Wraps the struct name so we have one less argument to pass around. */ +#define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name /* FIXTURE(datatype name) { * type property1; @@ -85,14 +125,14 @@ * Defines the data provided to TEST_F()-defined tests as |self|. It should be * populated and cleaned up using FIXTURE_SETUP and FIXTURE_TEARDOWN. */ -#define FIXTURE TEST_API(FIXTURE) - -/* FIXTURE_DATA(datatype name) - * This call may be used when the type of the fixture data - * is needed. In general, this should not be needed unless - * the |self| is being passed to a helper directly. - */ -#define FIXTURE_DATA TEST_API(FIXTURE_DATA) +/* Called once per fixture to setup the data and register. */ +#define FIXTURE(fixture_name) \ + static void __attribute__((constructor)) \ + _register_##fixture_name##_data(void) \ + { \ + __fixture_count++; \ + } \ + FIXTURE_DATA(fixture_name) /* FIXTURE_SETUP(fixture name) { implementation } * Populates the required "setup" function for a fixture. An instance of the @@ -104,8 +144,13 @@ * * A bare "return;" statement may be used to return early. */ -#define FIXTURE_SETUP TEST_API(FIXTURE_SETUP) - +/* Prepares the setup function for the fixture. |_metadata| is included + * so that ASSERT_* work as a convenience. + */ +#define FIXTURE_SETUP(fixture_name) \ + void fixture_name##_setup( \ + struct __test_metadata __attribute__((unused)) *_metadata, \ + FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) /* FIXTURE_TEARDOWN(fixture name) { implementation } * Populates the required "teardown" function for a fixture. An instance of the * datatype defined with _FIXTURE_DATA will be exposed as |self| for the @@ -113,166 +158,36 @@ * * A bare "return;" statement may be used to return early. */ -#define FIXTURE_TEARDOWN TEST_API(FIXTURE_TEARDOWN) +#define FIXTURE_TEARDOWN(fixture_name) \ + void fixture_name##_teardown( \ + struct __test_metadata __attribute__((unused)) *_metadata, \ + FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) /* TEST_F(fixture, name) { implementation } * Defines a test that depends on a fixture (e.g., is part of a test case). * Very similar to TEST() except that |self| is the setup instance of fixture's * datatype exposed for use by the implementation. */ -#define TEST_F TEST_API(TEST_F) - -#define TEST_F_SIGNAL TEST_API(TEST_F_SIGNAL) - -/* Use once to append a main() to the test file. E.g., - * TEST_HARNESS_MAIN - */ -#define TEST_HARNESS_MAIN TEST_API(TEST_HARNESS_MAIN) - -/* - * Operators for use in TEST and TEST_F. - * ASSERT_* calls will stop test execution immediately. - * EXPECT_* calls will emit a failure warning, note it, and continue. - */ - -/* ASSERT_EQ(expected, measured): expected == measured */ -#define ASSERT_EQ TEST_API(ASSERT_EQ) -/* ASSERT_NE(expected, measured): expected != measured */ -#define ASSERT_NE TEST_API(ASSERT_NE) -/* ASSERT_LT(expected, measured): expected < measured */ -#define ASSERT_LT TEST_API(ASSERT_LT) -/* ASSERT_LE(expected, measured): expected <= measured */ -#define ASSERT_LE TEST_API(ASSERT_LE) -/* ASSERT_GT(expected, measured): expected > measured */ -#define ASSERT_GT TEST_API(ASSERT_GT) -/* ASSERT_GE(expected, measured): expected >= measured */ -#define ASSERT_GE TEST_API(ASSERT_GE) -/* ASSERT_NULL(measured): NULL == measured */ -#define ASSERT_NULL TEST_API(ASSERT_NULL) -/* ASSERT_TRUE(measured): measured != 0 */ -#define ASSERT_TRUE TEST_API(ASSERT_TRUE) -/* ASSERT_FALSE(measured): measured == 0 */ -#define ASSERT_FALSE TEST_API(ASSERT_FALSE) -/* ASSERT_STREQ(expected, measured): !strcmp(expected, measured) */ -#define ASSERT_STREQ TEST_API(ASSERT_STREQ) -/* ASSERT_STRNE(expected, measured): strcmp(expected, measured) */ -#define ASSERT_STRNE TEST_API(ASSERT_STRNE) -/* EXPECT_EQ(expected, measured): expected == measured */ -#define EXPECT_EQ TEST_API(EXPECT_EQ) -/* EXPECT_NE(expected, measured): expected != measured */ -#define EXPECT_NE TEST_API(EXPECT_NE) -/* EXPECT_LT(expected, measured): expected < measured */ -#define EXPECT_LT TEST_API(EXPECT_LT) -/* EXPECT_LE(expected, measured): expected <= measured */ -#define EXPECT_LE TEST_API(EXPECT_LE) -/* EXPECT_GT(expected, measured): expected > measured */ -#define EXPECT_GT TEST_API(EXPECT_GT) -/* EXPECT_GE(expected, measured): expected >= measured */ -#define EXPECT_GE TEST_API(EXPECT_GE) -/* EXPECT_NULL(measured): NULL == measured */ -#define EXPECT_NULL TEST_API(EXPECT_NULL) -/* EXPECT_TRUE(measured): 0 != measured */ -#define EXPECT_TRUE TEST_API(EXPECT_TRUE) -/* EXPECT_FALSE(measured): 0 == measured */ -#define EXPECT_FALSE TEST_API(EXPECT_FALSE) -/* EXPECT_STREQ(expected, measured): !strcmp(expected, measured) */ -#define EXPECT_STREQ TEST_API(EXPECT_STREQ) -/* EXPECT_STRNE(expected, measured): strcmp(expected, measured) */ -#define EXPECT_STRNE TEST_API(EXPECT_STRNE) - -/* TH_LOG(format, ...) - * Optional debug logging function available for use in tests. - * Logging may be enabled or disabled by defining TH_LOG_ENABLED. - * E.g., #define TH_LOG_ENABLED 1 - * If no definition is provided, logging is enabled by default. - */ -#define TH_LOG TEST_API(TH_LOG) - -/* - * Internal implementation. - * - */ - -/* Utilities exposed to the test definitions */ -#ifndef TH_LOG_STREAM -# define TH_LOG_STREAM stderr -#endif - -#ifndef TH_LOG_ENABLED -# define TH_LOG_ENABLED 1 -#endif - -#define _TH_LOG(fmt, ...) do { \ - if (TH_LOG_ENABLED) \ - __TH_LOG(fmt, ##__VA_ARGS__); \ -} while (0) - -/* Unconditional logger for internal use. */ -#define __TH_LOG(fmt, ...) \ - fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \ - __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) - -/* Defines the test function and creates the registration stub. */ -#define _TEST(test_name) __TEST_IMPL(test_name, -1) - -#define _TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal) - -#define __TEST_IMPL(test_name, _signal) \ - static void test_name(struct __test_metadata *_metadata); \ - static struct __test_metadata _##test_name##_object = \ - { name: "global." #test_name, \ - fn: &test_name, termsig: _signal }; \ - static void __attribute__((constructor)) _register_##test_name(void) \ - { \ - __register_test(&_##test_name##_object); \ - } \ - static void test_name( \ - struct __test_metadata __attribute__((unused)) *_metadata) - -/* Wraps the struct name so we have one less argument to pass around. */ -#define _FIXTURE_DATA(fixture_name) struct _test_data_##fixture_name - -/* Called once per fixture to setup the data and register. */ -#define _FIXTURE(fixture_name) \ - static void __attribute__((constructor)) \ - _register_##fixture_name##_data(void) \ - { \ - __fixture_count++; \ - } \ - _FIXTURE_DATA(fixture_name) - -/* Prepares the setup function for the fixture. |_metadata| is included - * so that ASSERT_* work as a convenience. - */ -#define _FIXTURE_SETUP(fixture_name) \ - void fixture_name##_setup( \ - struct __test_metadata __attribute__((unused)) *_metadata, \ - _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) -#define _FIXTURE_TEARDOWN(fixture_name) \ - void fixture_name##_teardown( \ - struct __test_metadata __attribute__((unused)) *_metadata, \ - _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) - /* Emits test registration and helpers for fixture-based test * cases. * TODO(wad) register fixtures on dedicated test lists. */ -#define _TEST_F(fixture_name, test_name) \ +#define TEST_F(fixture_name, test_name) \ __TEST_F_IMPL(fixture_name, test_name, -1) -#define _TEST_F_SIGNAL(fixture_name, test_name, signal) \ +#define TEST_F_SIGNAL(fixture_name, test_name, signal) \ __TEST_F_IMPL(fixture_name, test_name, signal) #define __TEST_F_IMPL(fixture_name, test_name, signal) \ static void fixture_name##_##test_name( \ struct __test_metadata *_metadata, \ - _FIXTURE_DATA(fixture_name) *self); \ + FIXTURE_DATA(fixture_name) *self); \ static inline void wrapper_##fixture_name##_##test_name( \ struct __test_metadata *_metadata) \ { \ /* fixture data is alloced, setup, and torn down per call. */ \ - _FIXTURE_DATA(fixture_name) self; \ - memset(&self, 0, sizeof(_FIXTURE_DATA(fixture_name))); \ + FIXTURE_DATA(fixture_name) self; \ + memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \ fixture_name##_setup(_metadata, &self); \ /* Let setup failure terminate early. */ \ if (!_metadata->passed) \ @@ -293,10 +208,13 @@ } \ static void fixture_name##_##test_name( \ struct __test_metadata __attribute__((unused)) *_metadata, \ - _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) + FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) +/* Use once to append a main() to the test file. E.g., + * TEST_HARNESS_MAIN + */ /* Exports a simple wrapper to run the test harness. */ -#define _TEST_HARNESS_MAIN \ +#define TEST_HARNESS_MAIN \ static void __attribute__((constructor)) \ __constructor_order_last(void) \ { \ @@ -307,54 +225,81 @@ return test_harness_run(argc, argv); \ } -#define _ASSERT_EQ(_expected, _seen) \ - __EXPECT(_expected, _seen, ==, 1) -#define _ASSERT_NE(_expected, _seen) \ - __EXPECT(_expected, _seen, !=, 1) -#define _ASSERT_LT(_expected, _seen) \ - __EXPECT(_expected, _seen, <, 1) -#define _ASSERT_LE(_expected, _seen) \ - __EXPECT(_expected, _seen, <=, 1) -#define _ASSERT_GT(_expected, _seen) \ - __EXPECT(_expected, _seen, >, 1) -#define _ASSERT_GE(_expected, _seen) \ - __EXPECT(_expected, _seen, >=, 1) -#define _ASSERT_NULL(_seen) \ - __EXPECT(NULL, _seen, ==, 1) - -#define _ASSERT_TRUE(_seen) \ - _ASSERT_NE(0, _seen) -#define _ASSERT_FALSE(_seen) \ - _ASSERT_EQ(0, _seen) -#define _ASSERT_STREQ(_expected, _seen) \ - __EXPECT_STR(_expected, _seen, ==, 1) -#define _ASSERT_STRNE(_expected, _seen) \ - __EXPECT_STR(_expected, _seen, !=, 1) - -#define _EXPECT_EQ(_expected, _seen) \ - __EXPECT(_expected, _seen, ==, 0) -#define _EXPECT_NE(_expected, _seen) \ - __EXPECT(_expected, _seen, !=, 0) -#define _EXPECT_LT(_expected, _seen) \ - __EXPECT(_expected, _seen, <, 0) -#define _EXPECT_LE(_expected, _seen) \ - __EXPECT(_expected, _seen, <=, 0) -#define _EXPECT_GT(_expected, _seen) \ - __EXPECT(_expected, _seen, >, 0) -#define _EXPECT_GE(_expected, _seen) \ - __EXPECT(_expected, _seen, >=, 0) - -#define _EXPECT_NULL(_seen) \ - __EXPECT(NULL, _seen, ==, 0) -#define _EXPECT_TRUE(_seen) \ - _EXPECT_NE(0, _seen) -#define _EXPECT_FALSE(_seen) \ - _EXPECT_EQ(0, _seen) - -#define _EXPECT_STREQ(_expected, _seen) \ - __EXPECT_STR(_expected, _seen, ==, 0) -#define _EXPECT_STRNE(_expected, _seen) \ - __EXPECT_STR(_expected, _seen, !=, 0) +/* + * Operators for use in TEST and TEST_F. + * ASSERT_* calls will stop test execution immediately. + * EXPECT_* calls will emit a failure warning, note it, and continue. + */ +/* ASSERT_EQ(expected, measured): expected == measured */ +#define ASSERT_EQ(expected, seen) \ + __EXPECT(expected, seen, ==, 1) +/* ASSERT_NE(expected, measured): expected != measured */ +#define ASSERT_NE(expected, seen) \ + __EXPECT(expected, seen, !=, 1) +/* ASSERT_LT(expected, measured): expected < measured */ +#define ASSERT_LT(expected, seen) \ + __EXPECT(expected, seen, <, 1) +/* ASSERT_LE(expected, measured): expected <= measured */ +#define ASSERT_LE(expected, seen) \ + __EXPECT(expected, seen, <=, 1) +/* ASSERT_GT(expected, measured): expected > measured */ +#define ASSERT_GT(expected, seen) \ + __EXPECT(expected, seen, >, 1) +/* ASSERT_GE(expected, measured): expected >= measured */ +#define ASSERT_GE(expected, seen) \ + __EXPECT(expected, seen, >=, 1) +/* ASSERT_NULL(measured): NULL == measured */ +#define ASSERT_NULL(seen) \ + __EXPECT(NULL, seen, ==, 1) + +/* ASSERT_TRUE(measured): measured != 0 */ +#define ASSERT_TRUE(seen) \ + ASSERT_NE(0, seen) +/* ASSERT_FALSE(measured): measured == 0 */ +#define ASSERT_FALSE(seen) \ + ASSERT_EQ(0, seen) +/* ASSERT_STREQ(expected, measured): !strcmp(expected, measured) */ +#define ASSERT_STREQ(expected, seen) \ + __EXPECT_STR(expected, seen, ==, 1) +/* ASSERT_STRNE(expected, measured): strcmp(expected, measured) */ +#define ASSERT_STRNE(expected, seen) \ + __EXPECT_STR(expected, seen, !=, 1) + +/* EXPECT_EQ(expected, measured): expected == measured */ +#define EXPECT_EQ(expected, seen) \ + __EXPECT(expected, seen, ==, 0) +/* EXPECT_NE(expected, measured): expected != measured */ +#define EXPECT_NE(expected, seen) \ + __EXPECT(expected, seen, !=, 0) +/* EXPECT_LT(expected, measured): expected < measured */ +#define EXPECT_LT(expected, seen) \ + __EXPECT(expected, seen, <, 0) +/* EXPECT_LE(expected, measured): expected <= measured */ +#define EXPECT_LE(expected, seen) \ + __EXPECT(expected, seen, <=, 0) +/* EXPECT_GT(expected, measured): expected > measured */ +#define EXPECT_GT(expected, seen) \ + __EXPECT(expected, seen, >, 0) +/* EXPECT_GE(expected, measured): expected >= measured */ +#define EXPECT_GE(expected, seen) \ + __EXPECT(expected, seen, >=, 0) + +/* EXPECT_NULL(measured): NULL == measured */ +#define EXPECT_NULL(seen) \ + __EXPECT(NULL, seen, ==, 0) +/* EXPECT_TRUE(measured): 0 != measured */ +#define EXPECT_TRUE(seen) \ + EXPECT_NE(0, seen) +/* EXPECT_FALSE(measured): 0 == measured */ +#define EXPECT_FALSE(seen) \ + EXPECT_EQ(0, seen) + +/* EXPECT_STREQ(expected, measured): !strcmp(expected, measured) */ +#define EXPECT_STREQ(expected, seen) \ + __EXPECT_STR(expected, seen, ==, 0) +/* EXPECT_STRNE(expected, measured): strcmp(expected, measured) */ +#define EXPECT_STRNE(expected, seen) \ + __EXPECT_STR(expected, seen, !=, 0) #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) -- cgit v1.2.3 From 7e6a32abdded8ed3d50ca7d26d17b19ffa0ea34d Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Mon, 5 Jun 2017 20:37:17 +0200 Subject: Documentation/dev-tools: Add kselftest_harness documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ReST metadata to kselftest_harness.h to be able to include the comments in the Sphinx documentation. Signed-off-by: Mickaël Salaün Cc: Andy Lutomirski Cc: Jonathan Corbet Cc: Kees Cook Cc: Shuah Khan Cc: Will Drewry Signed-off-by: Shuah Khan --- Documentation/dev-tools/kselftest.rst | 33 +++ tools/testing/selftests/kselftest_harness.h | 415 ++++++++++++++++++++++------ 2 files changed, 363 insertions(+), 85 deletions(-) (limited to 'tools') diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst index 9232ce94612c..b3861500c42d 100644 --- a/Documentation/dev-tools/kselftest.rst +++ b/Documentation/dev-tools/kselftest.rst @@ -120,3 +120,36 @@ Contributing new tests (details) executable which is not tested by default. TEST_FILES, TEST_GEN_FILES mean it is the file which is used by test. + +Test Harness +============ + +The kselftest_harness.h file contains useful helpers to build tests. The tests +from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as example. + +Example +------- + +.. kernel-doc:: tools/testing/selftests/kselftest_harness.h + :doc: example + + +Helpers +------- + +.. kernel-doc:: tools/testing/selftests/kselftest_harness.h + :functions: TH_LOG TEST TEST_SIGNAL FIXTURE FIXTURE_DATA FIXTURE_SETUP + FIXTURE_TEARDOWN TEST_F TEST_HARNESS_MAIN + +Operators +--------- + +.. kernel-doc:: tools/testing/selftests/kselftest_harness.h + :doc: operators + +.. kernel-doc:: tools/testing/selftests/kselftest_harness.h + :functions: ASSERT_EQ ASSERT_NE ASSERT_LT ASSERT_LE ASSERT_GT ASSERT_GE + ASSERT_NULL ASSERT_TRUE ASSERT_NULL ASSERT_TRUE ASSERT_FALSE + ASSERT_STREQ ASSERT_STRNE EXPECT_EQ EXPECT_NE EXPECT_LT + EXPECT_LE EXPECT_GT EXPECT_GE EXPECT_NULL EXPECT_TRUE + EXPECT_FALSE EXPECT_STREQ EXPECT_STRNE diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 45f807ce37e1..c56f72e07cd7 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -4,41 +4,49 @@ * * kselftest_harness.h: simple C unit test helper. * - * Usage: - * #include "../kselftest_harness.h" - * TEST(standalone_test) { - * do_some_stuff; - * EXPECT_GT(10, stuff) { - * stuff_state_t state; - * enumerate_stuff_state(&state); - * TH_LOG("expectation failed with state: %s", state.msg); - * } - * more_stuff; - * ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!"); - * last_stuff; - * EXPECT_EQ(0, last_stuff); - * } - * - * FIXTURE(my_fixture) { - * mytype_t *data; - * int awesomeness_level; - * }; - * FIXTURE_SETUP(my_fixture) { - * self->data = mytype_new(); - * ASSERT_NE(NULL, self->data); - * } - * FIXTURE_TEARDOWN(my_fixture) { - * mytype_free(self->data); - * } - * TEST_F(my_fixture, data_is_good) { - * EXPECT_EQ(1, is_my_data_good(self->data)); - * } - * - * TEST_HARNESS_MAIN + * See documentation in Documentation/dev-tools/kselftest.rst * * API inspired by code.google.com/p/googletest */ +/** + * DOC: example + * + * .. code-block:: c + * + * #include "../kselftest_harness.h" + * + * TEST(standalone_test) { + * do_some_stuff; + * EXPECT_GT(10, stuff) { + * stuff_state_t state; + * enumerate_stuff_state(&state); + * TH_LOG("expectation failed with state: %s", state.msg); + * } + * more_stuff; + * ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!"); + * last_stuff; + * EXPECT_EQ(0, last_stuff); + * } + * + * FIXTURE(my_fixture) { + * mytype_t *data; + * int awesomeness_level; + * }; + * FIXTURE_SETUP(my_fixture) { + * self->data = mytype_new(); + * ASSERT_NE(NULL, self->data); + * } + * FIXTURE_TEARDOWN(my_fixture) { + * mytype_free(self->data); + * } + * TEST_F(my_fixture, data_is_good) { + * EXPECT_EQ(1, is_my_data_good(self->data)); + * } + * + * TEST_HARNESS_MAIN + */ + #ifndef __KSELFTEST_HARNESS_H #define __KSELFTEST_HARNESS_H @@ -61,10 +69,20 @@ # define TH_LOG_ENABLED 1 #endif -/* TH_LOG(format, ...) +/** + * TH_LOG(fmt, ...) + * + * @fmt: format string + * @...: optional arguments + * + * .. code-block:: c + * + * TH_LOG(format, ...) + * * Optional debug logging function available for use in tests. * Logging may be enabled or disabled by defining TH_LOG_ENABLED. * E.g., #define TH_LOG_ENABLED 1 + * * If no definition is provided, logging is enabled by default. */ #define TH_LOG(fmt, ...) do { \ @@ -77,7 +95,16 @@ fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \ __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) -/* TEST(name) { implementation } +/** + * TEST(test_name) - Defines the test function and creates the registration + * stub + * + * @test_name: test name + * + * .. code-block:: c + * + * TEST(name) { implementation } + * * Defines a test by name. * Names must be unique and tests must not be run in parallel. The * implementation containing block is a function and scoping should be treated @@ -85,10 +112,18 @@ * * EXPECT_* and ASSERT_* are valid in a TEST() { } context. */ -/* Defines the test function and creates the registration stub. */ #define TEST(test_name) __TEST_IMPL(test_name, -1) -/* TEST_SIGNAL(name, signal) { implementation } +/** + * TEST_SIGNAL(test_name, signal) + * + * @test_name: test name + * @signal: signal number + * + * .. code-block:: c + * + * TEST_SIGNAL(name, signal) { implementation } + * * Defines a test by name and the expected term signal. * Names must be unique and tests must not be run in parallel. The * implementation containing block is a function and scoping should be treated @@ -110,22 +145,38 @@ static void test_name( \ struct __test_metadata __attribute__((unused)) *_metadata) -/* FIXTURE_DATA(datatype name) +/** + * FIXTURE_DATA(datatype_name) - Wraps the struct name so we have one less + * argument to pass around + * + * @datatype_name: datatype name + * + * .. code-block:: c + * + * FIXTURE_DATA(datatype name) + * * This call may be used when the type of the fixture data * is needed. In general, this should not be needed unless - * the |self| is being passed to a helper directly. + * the *self* is being passed to a helper directly. */ -/* Wraps the struct name so we have one less argument to pass around. */ #define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name -/* FIXTURE(datatype name) { - * type property1; - * ... - * }; - * Defines the data provided to TEST_F()-defined tests as |self|. It should be - * populated and cleaned up using FIXTURE_SETUP and FIXTURE_TEARDOWN. +/** + * FIXTURE(fixture_name) - Called once per fixture to setup the data and + * register + * + * @fixture_name: fixture name + * + * .. code-block:: c + * + * FIXTURE(datatype name) { + * type property1; + * ... + * }; + * + * Defines the data provided to TEST_F()-defined tests as *self*. It should be + * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN(). */ -/* Called once per fixture to setup the data and register. */ #define FIXTURE(fixture_name) \ static void __attribute__((constructor)) \ _register_##fixture_name##_data(void) \ @@ -134,9 +185,18 @@ } \ FIXTURE_DATA(fixture_name) -/* FIXTURE_SETUP(fixture name) { implementation } +/** + * FIXTURE_SETUP(fixture_name) - Prepares the setup function for the fixture. + * *_metadata* is included so that ASSERT_* work as a convenience + * + * @fixture_name: fixture name + * + * .. code-block:: c + * + * FIXTURE_SETUP(fixture name) { implementation } + * * Populates the required "setup" function for a fixture. An instance of the - * datatype defined with _FIXTURE_DATA will be exposed as |self| for the + * datatype defined with FIXTURE_DATA() will be exposed as *self* for the * implementation. * * ASSERT_* are valid for use in this context and will prempt the execution @@ -144,16 +204,21 @@ * * A bare "return;" statement may be used to return early. */ -/* Prepares the setup function for the fixture. |_metadata| is included - * so that ASSERT_* work as a convenience. - */ #define FIXTURE_SETUP(fixture_name) \ void fixture_name##_setup( \ struct __test_metadata __attribute__((unused)) *_metadata, \ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) -/* FIXTURE_TEARDOWN(fixture name) { implementation } +/** + * FIXTURE_TEARDOWN(fixture_name) + * + * @fixture_name: fixture name + * + * .. code-block:: c + * + * FIXTURE_TEARDOWN(fixture name) { implementation } + * * Populates the required "teardown" function for a fixture. An instance of the - * datatype defined with _FIXTURE_DATA will be exposed as |self| for the + * datatype defined with FIXTURE_DATA() will be exposed as *self* for the * implementation to clean up. * * A bare "return;" statement may be used to return early. @@ -163,15 +228,22 @@ struct __test_metadata __attribute__((unused)) *_metadata, \ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) -/* TEST_F(fixture, name) { implementation } +/** + * TEST_F(fixture_name, test_name) - Emits test registration and helpers for + * fixture-based test cases + * + * @fixture_name: fixture name + * @test_name: test name + * + * .. code-block:: c + * + * TEST_F(fixture, name) { implementation } + * * Defines a test that depends on a fixture (e.g., is part of a test case). - * Very similar to TEST() except that |self| is the setup instance of fixture's + * Very similar to TEST() except that *self* is the setup instance of fixture's * datatype exposed for use by the implementation. */ -/* Emits test registration and helpers for fixture-based test - * cases. - * TODO(wad) register fixtures on dedicated test lists. - */ +/* TODO(wad) register fixtures on dedicated test lists. */ #define TEST_F(fixture_name, test_name) \ __TEST_F_IMPL(fixture_name, test_name, -1) @@ -210,10 +282,15 @@ struct __test_metadata __attribute__((unused)) *_metadata, \ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) -/* Use once to append a main() to the test file. E.g., - * TEST_HARNESS_MAIN +/** + * TEST_HARNESS_MAIN - Simple wrapper to run the test harness + * + * .. code-block:: c + * + * TEST_HARNESS_MAIN + * + * Use once to append a main() to the test file. */ -/* Exports a simple wrapper to run the test harness. */ #define TEST_HARNESS_MAIN \ static void __attribute__((constructor)) \ __constructor_order_last(void) \ @@ -225,79 +302,247 @@ return test_harness_run(argc, argv); \ } -/* - * Operators for use in TEST and TEST_F. +/** + * DOC: operators + * + * Operators for use in TEST() and TEST_F(). * ASSERT_* calls will stop test execution immediately. * EXPECT_* calls will emit a failure warning, note it, and continue. */ -/* ASSERT_EQ(expected, measured): expected == measured */ + +/** + * ASSERT_EQ(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * ASSERT_EQ(expected, measured): expected == measured + */ #define ASSERT_EQ(expected, seen) \ __EXPECT(expected, seen, ==, 1) -/* ASSERT_NE(expected, measured): expected != measured */ + +/** + * ASSERT_NE(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * ASSERT_NE(expected, measured): expected != measured + */ #define ASSERT_NE(expected, seen) \ __EXPECT(expected, seen, !=, 1) -/* ASSERT_LT(expected, measured): expected < measured */ + +/** + * ASSERT_LT(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * ASSERT_LT(expected, measured): expected < measured + */ #define ASSERT_LT(expected, seen) \ __EXPECT(expected, seen, <, 1) -/* ASSERT_LE(expected, measured): expected <= measured */ + +/** + * ASSERT_LE(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * ASSERT_LE(expected, measured): expected <= measured + */ #define ASSERT_LE(expected, seen) \ __EXPECT(expected, seen, <=, 1) -/* ASSERT_GT(expected, measured): expected > measured */ + +/** + * ASSERT_GT(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * ASSERT_GT(expected, measured): expected > measured + */ #define ASSERT_GT(expected, seen) \ __EXPECT(expected, seen, >, 1) -/* ASSERT_GE(expected, measured): expected >= measured */ + +/** + * ASSERT_GE(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * ASSERT_GE(expected, measured): expected >= measured + */ #define ASSERT_GE(expected, seen) \ __EXPECT(expected, seen, >=, 1) -/* ASSERT_NULL(measured): NULL == measured */ + +/** + * ASSERT_NULL(seen) + * + * @seen: measured value + * + * ASSERT_NULL(measured): NULL == measured + */ #define ASSERT_NULL(seen) \ __EXPECT(NULL, seen, ==, 1) -/* ASSERT_TRUE(measured): measured != 0 */ +/** + * ASSERT_TRUE(seen) + * + * @seen: measured value + * + * ASSERT_TRUE(measured): measured != 0 + */ #define ASSERT_TRUE(seen) \ ASSERT_NE(0, seen) -/* ASSERT_FALSE(measured): measured == 0 */ + +/** + * ASSERT_FALSE(seen) + * + * @seen: measured value + * + * ASSERT_FALSE(measured): measured == 0 + */ #define ASSERT_FALSE(seen) \ ASSERT_EQ(0, seen) -/* ASSERT_STREQ(expected, measured): !strcmp(expected, measured) */ + +/** + * ASSERT_STREQ(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * ASSERT_STREQ(expected, measured): !strcmp(expected, measured) + */ #define ASSERT_STREQ(expected, seen) \ __EXPECT_STR(expected, seen, ==, 1) -/* ASSERT_STRNE(expected, measured): strcmp(expected, measured) */ + +/** + * ASSERT_STRNE(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * ASSERT_STRNE(expected, measured): strcmp(expected, measured) + */ #define ASSERT_STRNE(expected, seen) \ __EXPECT_STR(expected, seen, !=, 1) -/* EXPECT_EQ(expected, measured): expected == measured */ +/** + * EXPECT_EQ(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * EXPECT_EQ(expected, measured): expected == measured + */ #define EXPECT_EQ(expected, seen) \ __EXPECT(expected, seen, ==, 0) -/* EXPECT_NE(expected, measured): expected != measured */ + +/** + * EXPECT_NE(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * EXPECT_NE(expected, measured): expected != measured + */ #define EXPECT_NE(expected, seen) \ __EXPECT(expected, seen, !=, 0) -/* EXPECT_LT(expected, measured): expected < measured */ + +/** + * EXPECT_LT(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * EXPECT_LT(expected, measured): expected < measured + */ #define EXPECT_LT(expected, seen) \ __EXPECT(expected, seen, <, 0) -/* EXPECT_LE(expected, measured): expected <= measured */ + +/** + * EXPECT_LE(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * EXPECT_LE(expected, measured): expected <= measured + */ #define EXPECT_LE(expected, seen) \ __EXPECT(expected, seen, <=, 0) -/* EXPECT_GT(expected, measured): expected > measured */ + +/** + * EXPECT_GT(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * EXPECT_GT(expected, measured): expected > measured + */ #define EXPECT_GT(expected, seen) \ __EXPECT(expected, seen, >, 0) -/* EXPECT_GE(expected, measured): expected >= measured */ + +/** + * EXPECT_GE(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * EXPECT_GE(expected, measured): expected >= measured + */ #define EXPECT_GE(expected, seen) \ __EXPECT(expected, seen, >=, 0) -/* EXPECT_NULL(measured): NULL == measured */ +/** + * EXPECT_NULL(seen) + * + * @seen: measured value + * + * EXPECT_NULL(measured): NULL == measured + */ #define EXPECT_NULL(seen) \ __EXPECT(NULL, seen, ==, 0) -/* EXPECT_TRUE(measured): 0 != measured */ + +/** + * EXPECT_TRUE(seen) + * + * @seen: measured value + * + * EXPECT_TRUE(measured): 0 != measured + */ #define EXPECT_TRUE(seen) \ EXPECT_NE(0, seen) -/* EXPECT_FALSE(measured): 0 == measured */ + +/** + * EXPECT_FALSE(seen) + * + * @seen: measured value + * + * EXPECT_FALSE(measured): 0 == measured + */ #define EXPECT_FALSE(seen) \ EXPECT_EQ(0, seen) -/* EXPECT_STREQ(expected, measured): !strcmp(expected, measured) */ +/** + * EXPECT_STREQ(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * EXPECT_STREQ(expected, measured): !strcmp(expected, measured) + */ #define EXPECT_STREQ(expected, seen) \ __EXPECT_STR(expected, seen, ==, 0) -/* EXPECT_STRNE(expected, measured): strcmp(expected, measured) */ + +/** + * EXPECT_STRNE(expected, seen) + * + * @expected: expected value + * @seen: measured value + * + * EXPECT_STRNE(expected, measured): strcmp(expected, measured) + */ #define EXPECT_STRNE(expected, seen) \ __EXPECT_STR(expected, seen, !=, 0) -- cgit v1.2.3 From 08f9f03a5340d2a996049b7c54b2e1769b2755bb Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Fri, 26 May 2017 20:43:58 +0200 Subject: selftests/seccomp: Force rebuild according to dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rebuild the seccomp tests when kselftest_harness.h is updated. Signed-off-by: Mickaël Salaün Acked-by: Kees Cook Cc: Andy Lutomirski Cc: Shuah Khan Cc: Will Drewry Signed-off-by: Shuah Khan --- tools/testing/selftests/seccomp/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/seccomp/Makefile b/tools/testing/selftests/seccomp/Makefile index 5fa6fd2246b1..aeb0c805f3ca 100644 --- a/tools/testing/selftests/seccomp/Makefile +++ b/tools/testing/selftests/seccomp/Makefile @@ -4,3 +4,5 @@ LDFLAGS += -lpthread include ../lib.mk +$(TEST_GEN_PROGS): seccomp_bpf.c ../kselftest_harness.h + $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -- cgit v1.2.3 From 27af344ba09c552d6ee9f1ef05bc00dc676fb0e8 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 23 May 2017 15:03:43 +0900 Subject: selftests/ftrace: Skip full-glob-matching filter test on older kernel Skip a part of ftrace filter test related to full-glob matching if we are sure that the testing kernel is so old that it does not support full-glob-matching yet. Signed-off-by: Masami Hiramatsu Signed-off-by: Shuah Khan --- .../ftrace/test.d/ftrace/func-filter-glob.tc | 28 +++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc index 9dcd0ca1f49c..8095e122daa9 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc @@ -11,17 +11,6 @@ fi disable_tracing clear_trace -# filter by ?, schedule is always good -if ! echo "sch?dule" > set_ftrace_filter; then - # test for powerpc 64 - if ! echo ".sch?dule" > set_ftrace_filter; then - fail "can not enable schedule filter" - fi - cat set_ftrace_filter | grep '^.schedule$' -else - cat set_ftrace_filter | grep '^schedule$' -fi - ftrace_filter_check() { # glob grep echo "$1" > set_ftrace_filter cut -f1 -d" " set_ftrace_filter > $TMPDIR/actual @@ -39,11 +28,28 @@ ftrace_filter_check '*schedule*' '^.*schedule.*$' # filter by *, end match ftrace_filter_check 'schedule*' '^schedule.*$' +# Advanced full-glob matching feature is recently supported. +# Skip the tests if we are sure the kernel does not support it. +if grep -q 'accepts: .* glob-matching-pattern' README ; then + # filter by *, both side match ftrace_filter_check 'sch*ule' '^sch.*ule$' # filter by char class. ftrace_filter_check '[Ss]y[Ss]_*' '^[Ss]y[Ss]_.*$' +# filter by ?, schedule is always good +if ! echo "sch?dule" > set_ftrace_filter; then + # test for powerpc 64 + if ! echo ".sch?dule" > set_ftrace_filter; then + fail "can not enable schedule filter" + fi + cat set_ftrace_filter | grep '^.schedule$' +else + cat set_ftrace_filter | grep '^schedule$' +fi + +fi + echo > set_ftrace_filter enable_tracing -- cgit v1.2.3 From 1d0864db8f3af3978d7b5207f9165fbe2a37148c Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 23 May 2017 15:04:46 +0900 Subject: selftests/ftrace: Reduce trace buffer checking overhead Current event/toplevel-enable.tc checking the trace buffer by dumping all events while recording events. However, this makes system very busy. To reduce this overhead comes from reading trace buffer and recording trace buffer, use head instead of cat and stop tracing while reading. Signed-off-by: Masami Hiramatsu Signed-off-by: Shuah Khan --- tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc index 0bb5df3c00d4..15e2d3fe1731 100644 --- a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc @@ -28,7 +28,9 @@ echo '*:*' > set_event yield -count=`cat trace | grep -v ^# | wc -l` +echo 0 > tracing_on + +count=`head -n 128 trace | grep -v ^# | wc -l` if [ $count -eq 0 ]; then fail "none of events are recorded" fi @@ -36,10 +38,12 @@ fi do_reset echo 1 > events/enable +echo 1 > tracing_on yield -count=`cat trace | grep -v ^# | wc -l` +echo 0 > tracing_on +count=`head -n 128 trace | grep -v ^# | wc -l` if [ $count -eq 0 ]; then fail "none of events are recorded" fi -- cgit v1.2.3 From c3ca46ef719580eb01994fc6032db470fde92d85 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 23 May 2017 15:05:50 +0900 Subject: ftrace/kprobes: selftests: Check kretprobe maxactive is supported Check the kretprobe maxactive is supported by kprobe_events interface. To ensure the kernel feature, this changes ftrace README to describe it. Signed-off-by: Masami Hiramatsu Signed-off-by: Shuah Khan --- kernel/trace/trace.c | 3 ++- tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_maxactive.tc | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1122f151466f..dc3f91e70345 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4473,7 +4473,8 @@ static const char readme_msg[] = #endif #if defined(CONFIG_KPROBE_EVENTS) || defined(CONFIG_UPROBE_EVENTS) "\t accepts: event-definitions (one definition per line)\n" - "\t Format: p|r[:[/]] []\n" + "\t Format: p[:[/]] []\n" + "\t r[maxactive][:[/]] []\n" "\t -:[/]\n" #ifdef CONFIG_KPROBE_EVENTS "\t place: [:][+]|\n" diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_maxactive.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_maxactive.tc index 57abdf1caabf..7ec6f2639ad6 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_maxactive.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_maxactive.tc @@ -2,6 +2,7 @@ # description: Kretprobe dynamic event with maxactive [ -f kprobe_events ] || exit_unsupported # this is configurable +grep -q 'r\[maxactive\]' README || exit_unsupported # this is older version echo > kprobe_events -- cgit v1.2.3 From d7b91c0b1c7f40241d8d47f0a2a0d616a1127635 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 23 May 2017 15:06:53 +0900 Subject: selftests/ftrace: Reset ftrace filter on older kernel Since older kernel didn't support separated instance of set_ftrace_filter, if the test case set the filter in an instance, it will propagate to top-level instance. This means that the filter setting remains even if we remove the instance, and will cause other tests failure. To avoid this issue, reset the ftrace filter if we detect the propagation. Signed-off-by: Masami Hiramatsu Signed-off-by: Shuah Khan --- tools/testing/selftests/ftrace/test.d/instances/instance-event.tc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc index c73db7863adb..8a353314dc9b 100644 --- a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc +++ b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc @@ -82,7 +82,10 @@ rmdir foo if [ -d foo ]; then fail "foo still exists" fi - +if grep -q "schedule:enable_event:sched:sched_switch" ../set_ftrace_filter; then + echo "Older kernel detected. Cleanup filter" + echo '!schedule:enable_event:sched:sched_switch' > ../set_ftrace_filter +fi instance_slam() { while :; do -- cgit v1.2.3 From 1917d2c82bc4ba121b16c4afcaf0c3723c36bf4e Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 23 May 2017 15:07:57 +0900 Subject: selftests/ftrace: Add instance indication in test log Add instance test indication in test log too. Current ftracetest shows instance test indication on the list of test, but not in the log for each test. This adds instance test indication on the top of each log, like below; execute (instance) : /ftrace/test.d/ftrace/func_set_ftrace_file.tc Signed-off-by: Masami Hiramatsu Signed-off-by: Shuah Khan --- tools/testing/selftests/ftrace/ftracetest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest index 717581145cfc..14a03ea1e21d 100755 --- a/tools/testing/selftests/ftrace/ftracetest +++ b/tools/testing/selftests/ftrace/ftracetest @@ -250,7 +250,7 @@ run_test() { # testfile local testlog=`mktemp $LOG_DIR/${testname}-log.XXXXXX` export TMPDIR=`mktemp -d /tmp/ftracetest-dir.XXXXXX` testcase $1 - echo "execute: "$1 > $testlog + echo "execute$INSTANCE: "$1 > $testlog SIG_RESULT=0 if [ $VERBOSE -ge 2 ]; then __run_test $1 2>> $testlog | tee -a $testlog -- cgit v1.2.3 From 565d557603231468ab71c74df383da42dc72b334 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 23 May 2017 15:09:01 +0900 Subject: selftests/ftrace: Use top-level available_filter_function Use top-level available_filter_function if the test case is running under an instance. Signed-off-by: Masami Hiramatsu Signed-off-by: Shuah Khan --- .../selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc index c8e02ec01eaf..1b0817bfa286 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc @@ -63,6 +63,10 @@ fi # powerpc uses .schedule func="schedule" +available_file=available_filter_functions +if [ -d ../../instances -a -f ../../available_filter_functions ]; then + available_file=../../available_filter_functions +fi x=`grep '^\.schedule$' available_filter_functions | wc -l` if [ "$x" -eq 1 ]; then func=".schedule" -- cgit v1.2.3 From bc5f1598e9b1de209ff05ddef6b1aa3ace11deab Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 23 May 2017 15:10:04 +0900 Subject: selftests/ftrace: Return unsupported if it detects older kernel Return unsupported if the kernel is too old to support instance independent ftrace filter for some testcases. Signed-off-by: Masami Hiramatsu Signed-off-by: Shuah Khan --- .../selftests/ftrace/test.d/ftrace/func_event_triggers.tc | 9 +++++++++ .../selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc | 9 +++++++++ 2 files changed, 18 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc index aa31368851c9..77dfb6b48186 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc @@ -72,6 +72,15 @@ run_enable_disable() { test_event_enabled $check_disable echo "schedule:${enable}_event:$EVENT" > set_ftrace_filter + if [ -d ../../instances ]; then # Check instances + cur=`cat set_ftrace_filter` + top=`cat ../../set_ftrace_filter` + if [ "$cur" = "$top" ]; then + echo "This kernel is too old to support per instance filter" + reset_ftrace_filter + exit_unsupported + fi + fi echo " make sure it works 5 times" diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc index 1b0817bfa286..9cf385297c1a 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc @@ -75,6 +75,15 @@ fi echo '** SET TRACEOFF' echo "$func:traceoff" > set_ftrace_filter +if [ -d ../../instances ]; then # Check instances + cur=`cat set_ftrace_filter` + top=`cat ../../set_ftrace_filter` + if [ "$cur" = "$top" ]; then + echo "This kernel is too old to support per instance filter" + reset_ftrace_filter + exit_unsupported + fi +fi cnt=`grep schedule set_ftrace_filter | wc -l` if [ $cnt -ne 1 ]; then -- cgit v1.2.3 From 34a048cc06802556e5f96f325dc32cc2f6a11225 Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Sun, 11 Jun 2017 14:32:58 +0200 Subject: selftests: kselftest_harness: Fix compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not confuse the compiler with a semicolon preceding a block. Replace the semicolon with an empty block to avoid a warning: gcc -Wl,-no-as-needed -Wall -lpthread seccomp_bpf.c -o /.../linux/tools/testing/selftests/seccomp/seccomp_bpf In file included from seccomp_bpf.c:40:0: seccomp_bpf.c: In function ‘change_syscall’: ../kselftest_harness.h:558:2: warning: this ‘for’ clause does not guard... [-Wmisleading-indentation] for (; _metadata->trigger; _metadata->trigger = __bail(_assert)) ^ ../kselftest_harness.h:574:14: note: in expansion of macro ‘OPTIONAL_HANDLER’ } while (0); OPTIONAL_HANDLER(_assert) ^~~~~~~~~~~~~~~~ ../kselftest_harness.h:440:2: note: in expansion of macro ‘__EXPECT’ __EXPECT(expected, seen, ==, 0) ^~~~~~~~ seccomp_bpf.c:1313:2: note: in expansion of macro ‘EXPECT_EQ’ EXPECT_EQ(0, ret); ^~~~~~~~~ seccomp_bpf.c:1317:2: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘for’ { ^ Signed-off-by: Mickaël Salaün Cc: Andy Lutomirski Cc: Kees Cook Cc: Shuah Khan Cc: Will Drewry Acked-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/seccomp/seccomp_bpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 7ba94efb24fd..18dad07ae16b 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -1310,7 +1310,7 @@ void change_syscall(struct __test_metadata *_metadata, iov.iov_len = sizeof(regs); ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov); #endif - EXPECT_EQ(0, ret); + EXPECT_EQ(0, ret) {} #if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \ defined(__s390__) || defined(__hppa__) -- cgit v1.2.3 From b6a4b66d845ae4c7f4eece419269c65ca332ba7b Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Mon, 12 Jun 2017 08:56:47 +0200 Subject: kselftest: add TAP13 conformant versions of ksft_* functions Add TAP13 conformat output functions to kselftest.h. Also add exit functions that output TAP13 exiting text, as well as functions to keep track of testing progress. Signed-off-by: Paul Elder Signed-off-by: Alice Ferrazzi Signed-off-by: Greg Kroah-Hartman Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest.h | 52 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h index ef1c80d67ac7..1d874a50d957 100644 --- a/tools/testing/selftests/kselftest.h +++ b/tools/testing/selftests/kselftest.h @@ -31,38 +31,82 @@ struct ksft_count { static struct ksft_count ksft_cnt; +static inline int ksft_test_num(void) +{ + return ksft_cnt.ksft_pass + ksft_cnt.ksft_fail + + ksft_cnt.ksft_xfail + ksft_cnt.ksft_xpass + + ksft_cnt.ksft_xskip; +} + static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; } static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; } static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; } static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; } static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; } +static inline void ksft_print_header(void) +{ + printf("TAP version 13\n"); +} + static inline void ksft_print_cnts(void) { - printf("Pass: %d Fail: %d Xfail: %d Xpass: %d, Xskip: %d\n", - ksft_cnt.ksft_pass, ksft_cnt.ksft_fail, - ksft_cnt.ksft_xfail, ksft_cnt.ksft_xpass, - ksft_cnt.ksft_xskip); + printf("1..%d\n", ksft_test_num()); +} + +static inline void ksft_test_result_pass(const char *msg) +{ + ksft_cnt.ksft_pass++; + printf("ok %d %s\n", ksft_test_num(), msg); +} + +static inline void ksft_test_result_fail(const char *msg) +{ + ksft_cnt.ksft_fail++; + printf("not ok %d %s\n", ksft_test_num(), msg); +} + +static inline void ksft_test_result_skip(const char *msg) +{ + ksft_cnt.ksft_xskip++; + printf("ok %d # skip %s\n", ksft_test_num(), msg); } static inline int ksft_exit_pass(void) { + ksft_print_cnts(); exit(KSFT_PASS); } + static inline int ksft_exit_fail(void) { + printf("Bail out!\n"); + ksft_print_cnts(); exit(KSFT_FAIL); } + +static inline int ksft_exit_fail_msg(const char *msg) +{ + printf("Bail out! %s\n", msg); + ksft_print_cnts(); + exit(KSFT_FAIL); +} + static inline int ksft_exit_xfail(void) { + ksft_print_cnts(); exit(KSFT_XFAIL); } + static inline int ksft_exit_xpass(void) { + ksft_print_cnts(); exit(KSFT_XPASS); } + static inline int ksft_exit_skip(void) { + ksft_print_cnts(); exit(KSFT_SKIP); } -- cgit v1.2.3 From 326f57a4c378f4dacf8fbeb05a1decfeff74f54e Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Mon, 12 Jun 2017 08:56:48 +0200 Subject: kselftest: membarrier: convert to TAP13 output Make the membarrier test output in the TAP13 format by using the TAP13 output functions defined in kselftest.h Signed-off-by: Paul Elder Signed-off-by: Alice Ferrazzi Signed-off-by: Greg Kroah-Hartman Signed-off-by: Shuah Khan --- .../testing/selftests/membarrier/membarrier_test.c | 35 ++++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c index 535f0fef4d0b..cae8c984dfb0 100644 --- a/tools/testing/selftests/membarrier/membarrier_test.c +++ b/tools/testing/selftests/membarrier/membarrier_test.c @@ -21,36 +21,42 @@ static int sys_membarrier(int cmd, int flags) static enum test_membarrier_status test_membarrier_cmd_fail(void) { int cmd = -1, flags = 0; + const char *test_name = "membarrier command fail"; if (sys_membarrier(cmd, flags) != -1) { - printf("membarrier: Wrong command should fail but passed.\n"); + ksft_test_result_fail(test_name); return TEST_MEMBARRIER_FAIL; } + + ksft_test_result_pass(test_name); return TEST_MEMBARRIER_PASS; } static enum test_membarrier_status test_membarrier_flags_fail(void) { int cmd = MEMBARRIER_CMD_QUERY, flags = 1; + const char *test_name = "Wrong flags should fail"; if (sys_membarrier(cmd, flags) != -1) { - printf("membarrier: Wrong flags should fail but passed.\n"); + ksft_test_result_fail(test_name); return TEST_MEMBARRIER_FAIL; } + + ksft_test_result_pass(test_name); return TEST_MEMBARRIER_PASS; } static enum test_membarrier_status test_membarrier_success(void) { int cmd = MEMBARRIER_CMD_SHARED, flags = 0; + const char *test_name = "execute MEMBARRIER_CMD_SHARED"; if (sys_membarrier(cmd, flags) != 0) { - printf("membarrier: Executing MEMBARRIER_CMD_SHARED failed. %s.\n", - strerror(errno)); + ksft_test_result_fail(test_name); return TEST_MEMBARRIER_FAIL; } - printf("membarrier: MEMBARRIER_CMD_SHARED success.\n"); + ksft_test_result_pass(test_name); return TEST_MEMBARRIER_PASS; } @@ -74,32 +80,30 @@ static enum test_membarrier_status test_membarrier_query(void) { int flags = 0, ret; - printf("membarrier MEMBARRIER_CMD_QUERY "); ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags); if (ret < 0) { - printf("failed. %s.\n", strerror(errno)); - switch (errno) { - case ENOSYS: + if (errno == ENOSYS) { /* * It is valid to build a kernel with * CONFIG_MEMBARRIER=n. However, this skips the tests. */ - return TEST_MEMBARRIER_SKIP; - case EINVAL: - default: - return TEST_MEMBARRIER_FAIL; + ksft_test_result_skip("CONFIG_MEMBARRIER is not enabled\n"); + return ksft_exit_skip(); } + ksft_test_result_fail("sys_membarrier() failed\n"); + return TEST_MEMBARRIER_FAIL; } if (!(ret & MEMBARRIER_CMD_SHARED)) { - printf("command MEMBARRIER_CMD_SHARED is not supported.\n"); + ksft_test_result_fail("command MEMBARRIER_CMD_SHARED is not supported.\n"); return TEST_MEMBARRIER_FAIL; } - printf("syscall available.\n"); + ksft_test_result_pass("sys_membarrier available"); return TEST_MEMBARRIER_PASS; } int main(int argc, char **argv) { + ksft_print_header(); switch (test_membarrier_query()) { case TEST_MEMBARRIER_FAIL: return ksft_exit_fail(); @@ -113,6 +117,5 @@ int main(int argc, char **argv) return ksft_exit_skip(); } - printf("membarrier: tests done!\n"); return ksft_exit_pass(); } -- cgit v1.2.3 From 748e84b79af0121a39eb55f0cb5a727e08eb91b2 Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Mon, 12 Jun 2017 08:56:49 +0200 Subject: kselftest: breakpoints: convert breakpoint_test to TAP13 output Make the breakpoints test output in the TAP13 format by using the TAP13 output functions defined in kselftest.h Signed-off-by: Paul Elder Signed-off-by: Alice Ferrazzi Signed-off-by: Greg Kroah-Hartman Signed-off-by: Shuah Khan --- .../selftests/breakpoints/breakpoint_test.c | 29 +++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/breakpoints/breakpoint_test.c b/tools/testing/selftests/breakpoints/breakpoint_test.c index 120895ab5505..c02fc9a0e228 100644 --- a/tools/testing/selftests/breakpoints/breakpoint_test.c +++ b/tools/testing/selftests/breakpoints/breakpoint_test.c @@ -42,10 +42,8 @@ static void set_breakpoint_addr(void *addr, int n) ret = ptrace(PTRACE_POKEUSER, child_pid, offsetof(struct user, u_debugreg[n]), addr); - if (ret) { - perror("Can't set breakpoint addr\n"); - ksft_exit_fail(); - } + if (ret) + ksft_exit_fail_msg("Can't set breakpoint addr"); } static void toggle_breakpoint(int n, int type, int len, @@ -105,10 +103,8 @@ static void toggle_breakpoint(int n, int type, int len, ret = ptrace(PTRACE_POKEUSER, child_pid, offsetof(struct user, u_debugreg[7]), dr7); - if (ret) { - perror("Can't set dr7"); - ksft_exit_fail(); - } + if (ret) + ksft_exit_fail_msg("Can't set dr7"); } /* Dummy variables to test read/write accesses */ @@ -264,26 +260,29 @@ static void check_success(const char *msg) const char *msg2; int child_nr_tests; int status; + int ret; /* Wait for the child to SIGTRAP */ wait(&status); msg2 = "Failed"; + ret = 0; if (WSTOPSIG(status) == SIGTRAP) { child_nr_tests = ptrace(PTRACE_PEEKDATA, child_pid, &nr_tests, 0); if (child_nr_tests == nr_tests) - msg2 = "Ok"; - if (ptrace(PTRACE_POKEDATA, child_pid, &trapped, 1)) { - perror("Can't poke\n"); - ksft_exit_fail(); - } + ret = 1; + if (ptrace(PTRACE_POKEDATA, child_pid, &trapped, 1)) + ksft_exit_fail_msg("Can't poke"); } nr_tests++; - printf("%s [%s]\n", msg, msg2); + if (ret) + ksft_test_result_pass(msg); + else + ksft_test_result_fail(msg); } static void launch_instruction_breakpoints(char *buf, int local, int global) @@ -378,6 +377,8 @@ int main(int argc, char **argv) pid_t pid; int ret; + ksft_print_header(); + pid = fork(); if (!pid) { trigger_tests(); -- cgit v1.2.3 From b901216441e6599063ff2828ec7f2f902b9902f0 Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Mon, 12 Jun 2017 08:56:50 +0200 Subject: kselftest: breakpoints: convert step_after_suspend_test to TAP13 output Make the step_after_suspend test output in the TAP13 format by using the TAP13 output functions defined in kselftest.h Signed-off-by: Paul Elder Signed-off-by: Alice Ferrazzi Signed-off-by: Greg Kroah-Hartman Signed-off-by: Shuah Khan --- .../breakpoints/step_after_suspend_test.c | 43 +++++++++------------- 1 file changed, 17 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c index 60b8a95dac26..bf37c1087f25 100644 --- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c +++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c @@ -135,28 +135,21 @@ void suspend(void) struct itimerspec spec = {}; power_state_fd = open("/sys/power/state", O_RDWR); - if (power_state_fd < 0) { - perror("open(\"/sys/power/state\") failed (is this test running as root?)"); - ksft_exit_fail(); - } + if (power_state_fd < 0) + ksft_exit_fail_msg( + "open(\"/sys/power/state\") failed (is this test running as root?)"); timerfd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0); - if (timerfd < 0) { - perror("timerfd_create() failed"); - ksft_exit_fail(); - } + if (timerfd < 0) + ksft_exit_fail_msg("timerfd_create() failed"); spec.it_value.tv_sec = 5; err = timerfd_settime(timerfd, 0, &spec, NULL); - if (err < 0) { - perror("timerfd_settime() failed"); - ksft_exit_fail(); - } + if (err < 0) + ksft_exit_fail_msg("timerfd_settime() failed"); - if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem")) { - perror("entering suspend failed"); - ksft_exit_fail(); - } + if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem")) + ksft_exit_fail_msg("entering suspend failed"); close(timerfd); close(power_state_fd); @@ -170,6 +163,9 @@ int main(int argc, char **argv) cpu_set_t available_cpus; int err; int cpu; + char buf[10]; + + ksft_print_header(); while ((opt = getopt(argc, argv, "n")) != -1) { switch (opt) { @@ -187,10 +183,8 @@ int main(int argc, char **argv) suspend(); err = sched_getaffinity(0, sizeof(available_cpus), &available_cpus); - if (err < 0) { - perror("sched_getaffinity() failed"); - ksft_exit_fail(); - } + if (err < 0) + ksft_exit_fail_msg("sched_getaffinity() failed"); for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { bool test_success; @@ -199,18 +193,15 @@ int main(int argc, char **argv) continue; test_success = run_test(cpu); - printf("CPU %d: ", cpu); + sprintf(buf, "CPU %d", cpu); if (test_success) { - printf("[OK]\n"); - ksft_inc_pass_cnt(); + ksft_test_result_pass(buf); } else { - printf("[FAILED]\n"); - ksft_inc_fail_cnt(); + ksft_test_result_fail(buf); succeeded = false; } } - ksft_print_cnts(); if (succeeded) ksft_exit_pass(); else -- cgit v1.2.3 From 48e42f91c10482992b474cc0874c0e33d76cb509 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Wed, 14 Jun 2017 15:28:02 -0700 Subject: kselftest: convert get_size to use stricter TAP13 format 1. Add the TAP13 header 2. remove variable data from the test description line 3. move the plan count to the end of the file, for consistency with other kselftests 4. convert memory data from diagnostic (comment) format, to a YAML block Signed-off-by: Tim Bird Signed-off-by: Shuah Khan --- tools/testing/selftests/size/get_size.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/size/get_size.c b/tools/testing/selftests/size/get_size.c index 2d1af7cca463..d4b59ab979a0 100644 --- a/tools/testing/selftests/size/get_size.c +++ b/tools/testing/selftests/size/get_size.c @@ -75,26 +75,31 @@ void _start(void) int ccode; struct sysinfo info; unsigned long used; + static const char *test_name = " get runtime memory use\n"; - print("Testing system size.\n"); - print("1..1\n"); + print("TAP version 13\n"); + print("# Testing system size.\n"); ccode = sysinfo(&info); if (ccode < 0) { - print("not ok 1 get runtime memory use\n"); - print("# could not get sysinfo\n"); + print("not ok 1"); + print(test_name); + print(" ---\n reason: \"could not get sysinfo\"\n ...\n"); _exit(ccode); } + print("ok 1"); + print(test_name); + /* ignore cache complexities for now */ used = info.totalram - info.freeram - info.bufferram; - print_k_value("ok 1 get runtime memory use # size = ", used, - info.mem_unit); - print("# System runtime memory report (units in Kilobytes):\n"); - print_k_value("# Total: ", info.totalram, info.mem_unit); - print_k_value("# Free: ", info.freeram, info.mem_unit); - print_k_value("# Buffer: ", info.bufferram, info.mem_unit); - print_k_value("# In use: ", used, info.mem_unit); + print(" ---\n"); + print_k_value(" Total: ", info.totalram, info.mem_unit); + print_k_value(" Free: ", info.freeram, info.mem_unit); + print_k_value(" Buffer: ", info.bufferram, info.mem_unit); + print_k_value(" In use: ", used, info.mem_unit); + print(" ...\n"); + print("1..1\n"); _exit(0); } -- cgit v1.2.3 From 54f57baab644e99b6da34d9538b2a9c0a05b690d Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Fri, 16 Jun 2017 00:54:20 +0900 Subject: kselftest: make ksft_exit_skip() output a reason for skipping Make ksft_exit_skip() input an optional message string as the reason for skipping all the tests and outputs it prior to exiting. Signed-off-by: Paul Elder Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h index 1d874a50d957..be01f2d15472 100644 --- a/tools/testing/selftests/kselftest.h +++ b/tools/testing/selftests/kselftest.h @@ -104,9 +104,12 @@ static inline int ksft_exit_xpass(void) exit(KSFT_XPASS); } -static inline int ksft_exit_skip(void) +static inline int ksft_exit_skip(const char *msg) { - ksft_print_cnts(); + if (msg) + printf("1..%d # Skipped: %s\n", ksft_test_num(), msg); + else + ksft_print_cnts(); exit(KSFT_SKIP); } -- cgit v1.2.3 From e4d1065b315b433f224920f1617bc3783230501c Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Fri, 16 Jun 2017 00:54:22 +0900 Subject: kselftest: make callers of ksft_exit_skip() output the reason for skipping Make the three tests that did use the old ksft_ext_skip() (breakpoints/breakpoint_test_arm64, breakpoints/step_after_suspend_test, and membarrier_test) use the new one, with an output for the reason for skipping all the tests. Signed-off-by: Paul Elder Signed-off-by: Shuah Khan --- tools/testing/selftests/breakpoints/breakpoint_test_arm64.c | 3 +-- tools/testing/selftests/breakpoints/step_after_suspend_test.c | 4 ++-- tools/testing/selftests/membarrier/membarrier_test.c | 7 +++---- 3 files changed, 6 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c b/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c index 3897e996541e..fa6d57af5217 100644 --- a/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c +++ b/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c @@ -101,9 +101,8 @@ static bool set_watchpoint(pid_t pid, int size, int wp) return true; if (errno == EIO) { - printf("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) " + ksft_exit_skip("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) " "not supported on this hardware\n"); - ksft_exit_skip(); } perror("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) failed"); return false; diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c index bf37c1087f25..c60c2effb6bc 100644 --- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c +++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c @@ -83,8 +83,8 @@ bool run_test(int cpu) if (ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) < 0) { if (errno == EIO) { - printf("ptrace(PTRACE_SINGLESTEP) not supported on this architecture\n"); - ksft_exit_skip(); + ksft_exit_skip("ptrace(PTRACE_SINGLESTEP) " + "not supported on this architecture"); } perror("ptrace(PTRACE_SINGLESTEP) failed"); return false; diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c index cae8c984dfb0..18cb9d1da4e4 100644 --- a/tools/testing/selftests/membarrier/membarrier_test.c +++ b/tools/testing/selftests/membarrier/membarrier_test.c @@ -87,8 +87,7 @@ static enum test_membarrier_status test_membarrier_query(void) * It is valid to build a kernel with * CONFIG_MEMBARRIER=n. However, this skips the tests. */ - ksft_test_result_skip("CONFIG_MEMBARRIER is not enabled\n"); - return ksft_exit_skip(); + ksft_exit_skip("CONFIG_MEMBARRIER is not enabled\n"); } ksft_test_result_fail("sys_membarrier() failed\n"); return TEST_MEMBARRIER_FAIL; @@ -108,13 +107,13 @@ int main(int argc, char **argv) case TEST_MEMBARRIER_FAIL: return ksft_exit_fail(); case TEST_MEMBARRIER_SKIP: - return ksft_exit_skip(); + return ksft_exit_skip(NULL); } switch (test_membarrier()) { case TEST_MEMBARRIER_FAIL: return ksft_exit_fail(); case TEST_MEMBARRIER_SKIP: - return ksft_exit_skip(); + return ksft_exit_skip(NULL); } return ksft_exit_pass(); -- cgit v1.2.3 From 34539b6c487c3d1cd1f3cafd1643e5ca89167813 Mon Sep 17 00:00:00 2001 From: Alice Ferrazzi Date: Fri, 16 Jun 2017 01:19:16 +0900 Subject: kselftest: membarrier: make test names more informative Make membarrier test names more informative. Signed-off-by: Alice Ferrazzi Signed-off-by: Paul Elder Signed-off-by: Shuah Khan --- tools/testing/selftests/membarrier/membarrier_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c index 18cb9d1da4e4..74a712eab2e6 100644 --- a/tools/testing/selftests/membarrier/membarrier_test.c +++ b/tools/testing/selftests/membarrier/membarrier_test.c @@ -21,7 +21,7 @@ static int sys_membarrier(int cmd, int flags) static enum test_membarrier_status test_membarrier_cmd_fail(void) { int cmd = -1, flags = 0; - const char *test_name = "membarrier command fail"; + const char *test_name = "membarrier command cmd=-1. Wrong command should fail"; if (sys_membarrier(cmd, flags) != -1) { ksft_test_result_fail(test_name); @@ -35,7 +35,7 @@ static enum test_membarrier_status test_membarrier_cmd_fail(void) static enum test_membarrier_status test_membarrier_flags_fail(void) { int cmd = MEMBARRIER_CMD_QUERY, flags = 1; - const char *test_name = "Wrong flags should fail"; + const char *test_name = "MEMBARRIER_CMD_QUERY, flags=1, Wrong flags should fail"; if (sys_membarrier(cmd, flags) != -1) { ksft_test_result_fail(test_name); -- cgit v1.2.3 From e0912c0129038e1e8eb20e0441fc3d6b33215d68 Mon Sep 17 00:00:00 2001 From: Sumit Semwal Date: Tue, 20 Jun 2017 10:18:18 +0530 Subject: selftests: lib: Skip tests on missing test modules With older kernels, printf.sh and bitmap.sh fail because they can't find the respective test modules they are looking for. Use modprobe dry run to check for missing test_XXX module. Error out with the same error code as prime_numbers.sh. Signed-off-by: Sumit Semwal Signed-off-by: Shuah Khan --- tools/testing/selftests/lib/bitmap.sh | 4 ++++ tools/testing/selftests/lib/printf.sh | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/lib/bitmap.sh b/tools/testing/selftests/lib/bitmap.sh index 2da187b6ddad..b073c22a3435 100755 --- a/tools/testing/selftests/lib/bitmap.sh +++ b/tools/testing/selftests/lib/bitmap.sh @@ -1,5 +1,9 @@ #!/bin/sh # Runs bitmap infrastructure tests using test_bitmap kernel module +if ! /sbin/modprobe -q -n test_bitmap; then + echo "bitmap: [SKIP]" + exit 77 +fi if /sbin/modprobe -q test_bitmap; then /sbin/modprobe -q -r test_bitmap diff --git a/tools/testing/selftests/lib/printf.sh b/tools/testing/selftests/lib/printf.sh index 4fdc70fe6980..cbf3b124bd94 100755 --- a/tools/testing/selftests/lib/printf.sh +++ b/tools/testing/selftests/lib/printf.sh @@ -1,5 +1,9 @@ #!/bin/sh # Runs printf infrastructure using test_printf kernel module +if ! /sbin/modprobe -q -n test_printf; then + echo "printf: [SKIP]" + exit 77 +fi if /sbin/modprobe -q test_printf; then /sbin/modprobe -q -r test_printf -- cgit v1.2.3 From d02db4f5b2c9159a9c8e22c57b90b48268ccd6ee Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 18 Jun 2017 09:56:02 +0900 Subject: selftest/memfd/Makefile: Fix build error Selftest for memfd shows build error as below: ``` gcc -D_FILE_OFFSET_BITS=64 -I../../../../include/uapi/ -I../../../../include/ -I../../../../usr/include/ fuse_mnt.c -o /home/sjpark/linux/tools/testing/selftests/memfd/fuse_mnt /tmp/cc6NHdwJ.o: In function `main': fuse_mnt.c:(.text+0x249): undefined reference to `fuse_main_real' collect2: error: ld returned 1 exit status ``` The build fails because output file is specified without $(OUTPUT) and LDFLAGS is used though Makefile implicit rule is used. This commit fixes the error by specifying output file path with $(OUTPUT) and using LDLIBS instead of LDFLAGS. Signed-off-by: SeongJae Park Signed-off-by: Shuah Khan --- tools/testing/selftests/memfd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index 79891d033de1..ad8a0897e47f 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile @@ -7,7 +7,7 @@ TEST_PROGS := run_fuse_test.sh TEST_GEN_FILES := memfd_test fuse_mnt fuse_test fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) -fuse_mnt: LDFLAGS += $(shell pkg-config fuse --libs) include ../lib.mk +$(OUTPUT)/fuse_mnt: LDLIBS += $(shell pkg-config fuse --libs) -- cgit v1.2.3 From dc816e5d84cbc28baf776799839a632d6002236f Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 18 Jun 2017 09:56:03 +0900 Subject: selftest/intel_pstate/aperf: Use LDLIBS instead of LDFLAGS Build of aperf fails as below: ``` gcc -Wall -D_GNU_SOURCE -lm aperf.c -o /tools/testing/selftests/intel_pstate/aperf /tmp/ccKf3GF6.o: In function `main': aperf.c:(.text+0x278): undefined reference to `sqrt' collect2: error: ld returned 1 exit status ``` The faulure occurs because -lm was defined as LDFLAGS and implicit rule of make places LDFLAGS before source file. This commit fixes the problem by using LDLIBS instead of LDFLAGS. Signed-off-by: SeongJae Park Signed-off-by: Shuah Khan --- tools/testing/selftests/intel_pstate/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile index 19678e90efb2..849a90ffe8dd 100644 --- a/tools/testing/selftests/intel_pstate/Makefile +++ b/tools/testing/selftests/intel_pstate/Makefile @@ -1,5 +1,5 @@ CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE -LDFLAGS := $(LDFLAGS) -lm +LDLIBS := $(LDLIBS) -lm TEST_GEN_FILES := msr aperf -- cgit v1.2.3 From 6dff86a30d1475a42d9bc0f0b4bba9b8f51c3776 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 18 Jun 2017 09:56:04 +0900 Subject: selftest/net/Makefile: Specify output with $(OUTPUT) After commit a8ba798bc8ec ("selftests: enable O and KBUILD_OUTPUT"), net selftest build fails because it points output file without $(OUTPUT) yet. This commit fixes the error. Signed-off-by: SeongJae Park Fixes: a8ba798bc8ec ("selftests: enable O and KBUILD_OUTPUT") Signed-off-by: Shuah Khan --- tools/testing/selftests/net/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 35cbb4cba410..f6c9dbf478f8 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -3,8 +3,6 @@ CFLAGS = -Wall -Wl,--no-as-needed -O2 -g CFLAGS += -I../../../../usr/include/ -reuseport_bpf_numa: LDFLAGS += -lnuma - TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh TEST_GEN_FILES = socket TEST_GEN_FILES += psock_fanout psock_tpacket @@ -13,3 +11,4 @@ TEST_GEN_FILES += reuseport_dualstack include ../lib.mk +$(OUTPUT)/reuseport_bpf_numa: LDFLAGS += -lnuma -- cgit v1.2.3 From d644437a1dc6226afb7b8a814657961d8812f763 Mon Sep 17 00:00:00 2001 From: Orson Zhai Date: Tue, 27 Jun 2017 08:52:09 +0800 Subject: tools/testing/selftests/sysctl: Add pre-check to the value of writes_strict Sysctl test will fail in some items if the value of /proc/sys/kernel /sysctrl_writes_strict is 0 as the default value in kernel older than v4.5. Make this test more robus and compatible with older kernel by checking and update writes_strict value and restore it when test is done. Signed-off-by: Orson Zhai Reviewed-by: Sumit Semwal Tested-by: Sumit Semwal Reviewed-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/sysctl/common_tests | 22 ++++++++++++++++++++++ tools/testing/selftests/sysctl/run_numerictests | 2 +- tools/testing/selftests/sysctl/run_stringtests | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/sysctl/common_tests b/tools/testing/selftests/sysctl/common_tests index 17d534b1b7b4..b6862322962f 100644 --- a/tools/testing/selftests/sysctl/common_tests +++ b/tools/testing/selftests/sysctl/common_tests @@ -24,6 +24,14 @@ verify() return 0 } +exit_test() +{ + if [ ! -z ${old_strict} ]; then + echo ${old_strict} > ${WRITES_STRICT} + fi + exit $rc +} + trap 'set_orig; rm -f "${TEST_FILE}"' EXIT rc=0 @@ -63,6 +71,20 @@ else echo "ok" fi +echo -n "Checking write strict setting ... " +WRITES_STRICT="${SYSCTL}/kernel/sysctl_writes_strict" +if [ ! -e ${WRITES_STRICT} ]; then + echo "FAIL, but skip in case of old kernel" >&2 +else + old_strict=$(cat ${WRITES_STRICT}) + if [ "$old_strict" = "1" ]; then + echo "ok" + else + echo "FAIL, strict value is 0 but force to 1 to continue" >&2 + echo "1" > ${WRITES_STRICT} + fi +fi + # Now that we've validated the sanity of "set_test" and "set_orig", # we can use those functions to set starting states before running # specific behavioral tests. diff --git a/tools/testing/selftests/sysctl/run_numerictests b/tools/testing/selftests/sysctl/run_numerictests index 8510f93f2d14..e6e76c93d948 100755 --- a/tools/testing/selftests/sysctl/run_numerictests +++ b/tools/testing/selftests/sysctl/run_numerictests @@ -7,4 +7,4 @@ TEST_STR=$(( $ORIG + 1 )) . ./common_tests -exit $rc +exit_test diff --git a/tools/testing/selftests/sysctl/run_stringtests b/tools/testing/selftests/sysctl/run_stringtests index 90a9293d520c..857ec667fb02 100755 --- a/tools/testing/selftests/sysctl/run_stringtests +++ b/tools/testing/selftests/sysctl/run_stringtests @@ -74,4 +74,4 @@ else echo "ok" fi -exit $rc +exit_test -- cgit v1.2.3 From d87b29179aa00efe15c88eebbcb88819e87e7f2a Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 27 Jun 2017 19:28:32 +0900 Subject: selftests: ftrace: Use md5sum to take less time of checking logs Use md5sum so that it takes less time of checking trace logs update. Since busybox tail/cat takes too long time to read the trace log, this uses md5sum to check whether trace log is updated or not. Signed-off-by: Masami Hiramatsu Acked-by: Steven Rostedt (VMware) Signed-off-by: Shuah Khan --- .../selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc index 9cf385297c1a..7a9ab4ff83b6 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc @@ -103,11 +103,11 @@ if [ $on != "0" ]; then fail "Tracing is not off" fi -line1=`cat trace | tail -1` +csum1=`md5sum trace` sleep $SLEEP_TIME -line2=`cat trace | tail -1` +csum2=`md5sum trace` -if [ "$line1" != "$line2" ]; then +if [ "$csum1" != "$csum2" ]; then fail "Tracing file is still changing" fi -- cgit v1.2.3 From 593f927851a58fdca559b173c807a0b78c9f6e49 Mon Sep 17 00:00:00 2001 From: Po-Hsu Lin Date: Tue, 27 Jun 2017 14:17:11 +0800 Subject: selftests: typo correction for memory-hotplug test Typo fixed for hotpluggable_offline_memory() in memory-hotplug test. Signed-off-by: Po-Hsu Lin Signed-off-by: Shuah Khan --- tools/testing/selftests/memory-hotplug/mem-on-off-test.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh index 6cddde0b96f8..a8d858767102 100755 --- a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh +++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh @@ -39,7 +39,7 @@ hotpluggable_memory() done } -hotplaggable_offline_memory() +hotpluggable_offline_memory() { hotpluggable_memory offline } @@ -150,7 +150,7 @@ echo -e "\t online all hotplug memory in offline state" # # Online all hot-pluggable memory # -for memory in `hotplaggable_offline_memory`; do +for memory in `hotpluggable_offline_memory`; do echo offline-online $memory online_memory_expect_success $memory done @@ -168,7 +168,7 @@ done # # Online all hot-pluggable memory again # -for memory in `hotplaggable_offline_memory`; do +for memory in `hotpluggable_offline_memory`; do echo offline-online $memory online_memory_expect_success $memory done @@ -214,7 +214,7 @@ done # Test memory hot-add error handling (offline => online) # echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error -for memory in `hotplaggable_offline_memory`; do +for memory in `hotpluggable_offline_memory`; do online_memory_expect_fail $memory done @@ -222,7 +222,7 @@ done # Online all hot-pluggable memory # echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error -for memory in `hotplaggable_offline_memory`; do +for memory in `hotpluggable_offline_memory`; do online_memory_expect_success $memory done -- cgit v1.2.3 From a34b28c92ec8c92938de03c18c5fab32efd2e29a Mon Sep 17 00:00:00 2001 From: Po-Hsu Lin Date: Tue, 27 Jun 2017 14:17:12 +0800 Subject: selftests: check hot-pluggagble memory for memory-hotplug test Check for hot-pluggable memory availability in prerequisite() of the memory-hotplug test. Signed-off-by: Po-Hsu Lin Signed-off-by: Shuah Khan --- tools/testing/selftests/memory-hotplug/mem-on-off-test.sh | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh index a8d858767102..993ff2bcfc7b 100755 --- a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh +++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh @@ -22,6 +22,11 @@ prerequisite() echo $msg memory hotplug is not supported >&2 exit 0 fi + + if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then + echo $msg no hot-pluggable memory >&2 + exit 0 + fi } # -- cgit v1.2.3 From 72441ea5886780d04ac96913e02dba9e84ea80e5 Mon Sep 17 00:00:00 2001 From: Po-Hsu Lin Date: Tue, 27 Jun 2017 14:17:13 +0800 Subject: selftests: check percentage range for memory-hotplug test Check the precentage range for -r flag in memory-hotplug test. Signed-off-by: Po-Hsu Lin Signed-off-by: Shuah Khan --- tools/testing/selftests/memory-hotplug/mem-on-off-test.sh | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh index 993ff2bcfc7b..c735ece968f8 100755 --- a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh +++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh @@ -136,6 +136,10 @@ while getopts e:hp:r: opt; do ;; r) ratio=$OPTARG + if [ "$ratio" -gt 100 ] || [ "$ratio" -lt 0 ]; then + echo "The percentage should be an integer within 0~100 range" + exit 1 + fi ;; esac done -- cgit v1.2.3 From 02d8f075ac44f6f0dc46881965f815576921f2c0 Mon Sep 17 00:00:00 2001 From: Po-Hsu Lin Date: Tue, 27 Jun 2017 14:17:14 +0800 Subject: selftests: add missing test name in memory-hotplug test There is no prompt for testing memory notifier error injection, added with the same echo format of other tests above. Signed-off-by: Po-Hsu Lin Signed-off-by: Shuah Khan --- tools/testing/selftests/memory-hotplug/mem-on-off-test.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh index c735ece968f8..0f62c16c35c4 100755 --- a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh +++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh @@ -207,6 +207,7 @@ prerequisite_extra() fi } +echo -e "\t Test with memory notifier error injection" prerequisite_extra # -- cgit v1.2.3 From 5ff0c60b0e5e8c2a2139c304d7620b0ea70d721a Mon Sep 17 00:00:00 2001 From: Po-Hsu Lin Date: Tue, 27 Jun 2017 14:17:15 +0800 Subject: selftests: fix memory-hotplug test In the memory offline test, the $ration was used with RANDOM as the possibility to get it offlined, correct it to become the portion of available removable memory blocks. Also ask the tool to try to offline the next available memory block if the attempt is unsuccessful. It will only fail if all removable memory blocks are busy. A nice example: $ sudo ./test.sh Test scope: 10% hotplug memory online all hot-pluggable memory in offline state: SKIPPED - no hot-pluggable memory in offline state offline 10% hot-pluggable memory in online state trying to offline 3 out of 28 memory block(s): online->offline memory1 online->offline memory10 ./test.sh: line 74: echo: write error: Resource temporarily unavailable offline_memory_expect_success 10: unexpected fail online->offline memory100 online->offline memory101 online all hot-pluggable memory in offline state: offline->online memory1 offline->online memory100 offline->online memory101 skip extra tests: debugfs is not mounted $ echo $? 0 Signed-off-by: Po-Hsu Lin Signed-off-by: Shuah Khan --- .../selftests/memory-hotplug/mem-on-off-test.sh | 70 +++++++++++++++++----- 1 file changed, 54 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh index 0f62c16c35c4..35025ce9ca66 100755 --- a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh +++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh @@ -80,9 +80,12 @@ online_memory_expect_success() if ! online_memory $memory; then echo $FUNCNAME $memory: unexpected fail >&2 + return 1 elif ! memory_is_online $memory; then echo $FUNCNAME $memory: unexpected offline >&2 + return 1 fi + return 0 } online_memory_expect_fail() @@ -91,9 +94,12 @@ online_memory_expect_fail() if online_memory $memory 2> /dev/null; then echo $FUNCNAME $memory: unexpected success >&2 + return 1 elif ! memory_is_offline $memory; then echo $FUNCNAME $memory: unexpected online >&2 + return 1 fi + return 0 } offline_memory_expect_success() @@ -102,9 +108,12 @@ offline_memory_expect_success() if ! offline_memory $memory; then echo $FUNCNAME $memory: unexpected fail >&2 + return 1 elif ! memory_is_offline $memory; then echo $FUNCNAME $memory: unexpected offline >&2 + return 1 fi + return 0 } offline_memory_expect_fail() @@ -113,14 +122,18 @@ offline_memory_expect_fail() if offline_memory $memory 2> /dev/null; then echo $FUNCNAME $memory: unexpected success >&2 + return 1 elif ! memory_is_online $memory; then echo $FUNCNAME $memory: unexpected offline >&2 + return 1 fi + return 0 } error=-12 priority=0 ratio=10 +retval=0 while getopts e:hp:r: opt; do case $opt in @@ -152,35 +165,58 @@ fi prerequisite echo "Test scope: $ratio% hotplug memory" -echo -e "\t online all hotplug memory in offline state" -echo -e "\t offline $ratio% hotplug memory in online state" -echo -e "\t online all hotplug memory in offline state" # # Online all hot-pluggable memory # -for memory in `hotpluggable_offline_memory`; do - echo offline-online $memory - online_memory_expect_success $memory -done +hotpluggable_num=`hotpluggable_offline_memory | wc -l` +echo -e "\t online all hot-pluggable memory in offline state:" +if [ "$hotpluggable_num" -gt 0 ]; then + for memory in `hotpluggable_offline_memory`; do + echo "offline->online memory$memory" + if ! online_memory_expect_success $memory; then + retval=1 + fi + done +else + echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state" +fi # # Offline $ratio percent of hot-pluggable memory # +hotpluggable_num=`hotpluggable_online_memory | wc -l` +target=`echo "a=$hotpluggable_num*$ratio; if ( a%100 ) a/100+1 else a/100" | bc` +echo -e "\t offline $ratio% hot-pluggable memory in online state" +echo -e "\t trying to offline $target out of $hotpluggable_num memory block(s):" for memory in `hotpluggable_online_memory`; do - if [ $((RANDOM % 100)) -lt $ratio ]; then - echo online-offline $memory - offline_memory_expect_success $memory + if [ "$target" -gt 0 ]; then + echo "online->offline memory$memory" + if offline_memory_expect_success $memory; then + target=$(($target - 1)) + fi fi done +if [ "$target" -gt 0 ]; then + retval=1 + echo -e "\t\t FAILED - unable to offline some memory blocks, device busy?" +fi # # Online all hot-pluggable memory again # -for memory in `hotpluggable_offline_memory`; do - echo offline-online $memory - online_memory_expect_success $memory -done +hotpluggable_num=`hotpluggable_offline_memory | wc -l` +echo -e "\t online all hot-pluggable memory in offline state:" +if [ "$hotpluggable_num" -gt 0 ]; then + for memory in `hotpluggable_offline_memory`; do + echo "offline->online memory$memory" + if ! online_memory_expect_success $memory; then + retval=1 + fi + done +else + echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state" +fi # # Test with memory notifier error injection @@ -198,12 +234,12 @@ prerequisite_extra() if [ ! -d "$DEBUGFS" ]; then echo $msg debugfs is not mounted >&2 - exit 0 + exit $retval fi if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then echo $msg memory-notifier-error-inject module is not available >&2 - exit 0 + exit $retval fi } @@ -246,3 +282,5 @@ done echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error /sbin/modprobe -q -r memory-notifier-error-inject + +exit $retval -- cgit v1.2.3 From 4ca90c21b215b6b09761b51547b88993a2046893 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Mon, 26 Jun 2017 10:52:58 -0600 Subject: selftests: intel_pstate: add .gitignore Add .gitignore for generated files. Signed-off-by: Shuah Khan --- tools/testing/selftests/intel_pstate/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tools/testing/selftests/intel_pstate/.gitignore (limited to 'tools') diff --git a/tools/testing/selftests/intel_pstate/.gitignore b/tools/testing/selftests/intel_pstate/.gitignore new file mode 100644 index 000000000000..3bfcbae5fa13 --- /dev/null +++ b/tools/testing/selftests/intel_pstate/.gitignore @@ -0,0 +1,2 @@ +aperf +msr -- cgit v1.2.3 From 796a3bae2fba6810427efdb314a1c126c9490fb3 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 29 Jun 2017 08:46:12 -0700 Subject: selftests/capabilities: Fix the test_execve test test_execve does rather odd mount manipulations to safely create temporary setuid and setgid executables that aren't visible to the rest of the system. Those executables end up in the test's cwd, but that cwd is MNT_DETACHed. The core namespace code considers MNT_DETACHed trees to belong to no mount namespace at all and, in general, MNT_DETACHed trees are only barely function. This interacted with commit 380cf5ba6b0a ("fs: Treat foreign mounts as nosuid") to cause all MNT_DETACHed trees to act as though they're nosuid, breaking the test. Fix it by just not detaching the tree. It's still in a private mount namespace and is therefore still invisible to the rest of the system (except via /proc, and the same nosuid logic will protect all other programs on the system from believing in test_execve's setuid bits). While we're at it, fix some blatant whitespace problems. Reported-by: Naresh Kamboju Fixes: 380cf5ba6b0a ("fs: Treat foreign mounts as nosuid") Cc: stable@vger.kernel.org Cc: "Eric W. Biederman" Cc: Kees Cook Cc: Shuah Khan Cc: Greg KH Cc: linux-kselftest@vger.kernel.org Signed-off-by: Andy Lutomirski Acked-by: Greg Kroah-Hartman Signed-off-by: Shuah Khan --- tools/testing/selftests/capabilities/test_execve.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/capabilities/test_execve.c b/tools/testing/selftests/capabilities/test_execve.c index 10a21a958aaf..763f37fecfb8 100644 --- a/tools/testing/selftests/capabilities/test_execve.c +++ b/tools/testing/selftests/capabilities/test_execve.c @@ -138,9 +138,6 @@ static void chdir_to_tmpfs(void) if (chdir(cwd) != 0) err(1, "chdir to private tmpfs"); - - if (umount2(".", MNT_DETACH) != 0) - err(1, "detach private tmpfs"); } static void copy_fromat_to(int fromfd, const char *fromname, const char *toname) @@ -248,7 +245,7 @@ static int do_tests(int uid, const char *our_path) err(1, "chown"); if (chmod("validate_cap_sgidnonroot", S_ISGID | 0710) != 0) err(1, "chmod"); -} + } capng_get_caps_process(); @@ -384,7 +381,7 @@ static int do_tests(int uid, const char *our_path) } else { printf("[RUN]\tNon-root +ia, sgidnonroot => i\n"); exec_other_validate_cap("./validate_cap_sgidnonroot", - false, false, true, false); + false, false, true, false); if (fork_wait()) { printf("[RUN]\tNon-root +ia, sgidroot => i\n"); -- cgit v1.2.3 From 151b2732111f0743e764a7bc62d4f580341a62f3 Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Wed, 28 Jun 2017 23:40:20 +0900 Subject: kselftest: make ksft_* output functions variadic Make the ksft_* output functions variadic to allow string formatting directly in these functions. Signed-off-by: Paul Elder Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest.h | 55 +++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h index be01f2d15472..a00844e4c915 100644 --- a/tools/testing/selftests/kselftest.h +++ b/tools/testing/selftests/kselftest.h @@ -12,6 +12,7 @@ #include #include +#include /* define kselftest exit codes */ #define KSFT_PASS 0 @@ -54,22 +55,40 @@ static inline void ksft_print_cnts(void) printf("1..%d\n", ksft_test_num()); } -static inline void ksft_test_result_pass(const char *msg) +static inline void ksft_test_result_pass(const char *msg, ...) { + va_list args; + ksft_cnt.ksft_pass++; - printf("ok %d %s\n", ksft_test_num(), msg); + + va_start(args, msg); + printf("ok %d ", ksft_test_num()); + vprintf(msg, args); + va_end(args); } -static inline void ksft_test_result_fail(const char *msg) +static inline void ksft_test_result_fail(const char *msg, ...) { + va_list args; + ksft_cnt.ksft_fail++; - printf("not ok %d %s\n", ksft_test_num(), msg); + + va_start(args, msg); + printf("not ok %d ", ksft_test_num()); + vprintf(msg, args); + va_end(args); } -static inline void ksft_test_result_skip(const char *msg) +static inline void ksft_test_result_skip(const char *msg, ...) { + va_list args; + ksft_cnt.ksft_xskip++; - printf("ok %d # skip %s\n", ksft_test_num(), msg); + + va_start(args, msg); + printf("ok %d # skip ", ksft_test_num()); + vprintf(msg, args); + va_end(args); } static inline int ksft_exit_pass(void) @@ -85,9 +104,15 @@ static inline int ksft_exit_fail(void) exit(KSFT_FAIL); } -static inline int ksft_exit_fail_msg(const char *msg) +static inline int ksft_exit_fail_msg(const char *msg, ...) { - printf("Bail out! %s\n", msg); + va_list args; + + va_start(args, msg); + printf("Bail out! "); + vprintf(msg, args); + va_end(args); + ksft_print_cnts(); exit(KSFT_FAIL); } @@ -104,12 +129,18 @@ static inline int ksft_exit_xpass(void) exit(KSFT_XPASS); } -static inline int ksft_exit_skip(const char *msg) +static inline int ksft_exit_skip(const char *msg, ...) { - if (msg) - printf("1..%d # Skipped: %s\n", ksft_test_num(), msg); - else + if (msg) { + va_list args; + + va_start(args, msg); + printf("1..%d # Skipped: ", ksft_test_num()); + vprintf(msg, args); + va_end(args); + } else { ksft_print_cnts(); + } exit(KSFT_SKIP); } -- cgit v1.2.3 From ab52a484455007b3c9c11e18f6d0eed6d8f2de4e Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Wed, 28 Jun 2017 23:40:21 +0900 Subject: kselftest: add ksft_print_msg() function to output general information Add a generic information output function: ksft_print_msg() Signed-off-by: Paul Elder Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h index a00844e4c915..08e90c2cc5cb 100644 --- a/tools/testing/selftests/kselftest.h +++ b/tools/testing/selftests/kselftest.h @@ -55,6 +55,16 @@ static inline void ksft_print_cnts(void) printf("1..%d\n", ksft_test_num()); } +static inline void ksft_print_msg(const char *msg, ...) +{ + va_list args; + + va_start(args, msg); + printf("# "); + vprintf(msg, args); + va_end(args); +} + static inline void ksft_test_result_pass(const char *msg, ...) { va_list args; -- cgit v1.2.3 From 4ca562878b907e34fdb652c3a8cb631fd5efe706 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 29 Jun 2017 15:19:47 -0600 Subject: selftests: breakpoint_test: use ksft_* var arg msg api Use ksft_* var arg msg to include strerror() info. in test output. Change output from child process to use ksft_print_msg() instead of ksft_exit_* to avoid double counting tests and ensure parent does the incrementing test counters. Also includes unused variable cleanup. Signed-off-by: Shuah Khan --- .../selftests/breakpoints/breakpoint_test.c | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/breakpoints/breakpoint_test.c b/tools/testing/selftests/breakpoints/breakpoint_test.c index c02fc9a0e228..f63356151ad4 100644 --- a/tools/testing/selftests/breakpoints/breakpoint_test.c +++ b/tools/testing/selftests/breakpoints/breakpoint_test.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "../kselftest.h" @@ -43,7 +45,8 @@ static void set_breakpoint_addr(void *addr, int n) ret = ptrace(PTRACE_POKEUSER, child_pid, offsetof(struct user, u_debugreg[n]), addr); if (ret) - ksft_exit_fail_msg("Can't set breakpoint addr"); + ksft_exit_fail_msg("Can't set breakpoint addr: %s\n", + strerror(errno)); } static void toggle_breakpoint(int n, int type, int len, @@ -103,8 +106,10 @@ static void toggle_breakpoint(int n, int type, int len, ret = ptrace(PTRACE_POKEUSER, child_pid, offsetof(struct user, u_debugreg[7]), dr7); - if (ret) - ksft_exit_fail_msg("Can't set dr7"); + if (ret) { + ksft_print_msg("Can't set dr7: %s\n", strerror(errno)); + exit(-1); + } } /* Dummy variables to test read/write accesses */ @@ -202,7 +207,7 @@ static void trigger_tests(void) ret = ptrace(PTRACE_TRACEME, 0, NULL, 0); if (ret) { - perror("Can't be traced?\n"); + ksft_print_msg("Can't be traced? %s\n", strerror(errno)); return; } @@ -257,7 +262,6 @@ static void trigger_tests(void) static void check_success(const char *msg) { - const char *msg2; int child_nr_tests; int status; int ret; @@ -265,7 +269,6 @@ static void check_success(const char *msg) /* Wait for the child to SIGTRAP */ wait(&status); - msg2 = "Failed"; ret = 0; if (WSTOPSIG(status) == SIGTRAP) { @@ -274,7 +277,7 @@ static void check_success(const char *msg) if (child_nr_tests == nr_tests) ret = 1; if (ptrace(PTRACE_POKEDATA, child_pid, &trapped, 1)) - ksft_exit_fail_msg("Can't poke"); + ksft_exit_fail_msg("Can't poke: %s\n", strerror(errno)); } nr_tests++; @@ -293,7 +296,7 @@ static void launch_instruction_breakpoints(char *buf, int local, int global) set_breakpoint_addr(dummy_funcs[i], i); toggle_breakpoint(i, BP_X, 1, local, global, 1); ptrace(PTRACE_CONT, child_pid, NULL, 0); - sprintf(buf, "Test breakpoint %d with local: %d global: %d", + sprintf(buf, "Test breakpoint %d with local: %d global: %d\n", i, local, global); check_success(buf); toggle_breakpoint(i, BP_X, 1, local, global, 0); @@ -315,8 +318,9 @@ static void launch_watchpoints(char *buf, int mode, int len, set_breakpoint_addr(&dummy_var[i], i); toggle_breakpoint(i, mode, len, local, global, 1); ptrace(PTRACE_CONT, child_pid, NULL, 0); - sprintf(buf, "Test %s watchpoint %d with len: %d local: " - "%d global: %d", mode_str, i, len, local, global); + sprintf(buf, + "Test %s watchpoint %d with len: %d local: %d global: %d\n", + mode_str, i, len, local, global); check_success(buf); toggle_breakpoint(i, mode, len, local, global, 0); } @@ -382,7 +386,7 @@ int main(int argc, char **argv) pid = fork(); if (!pid) { trigger_tests(); - return 0; + exit(0); } child_pid = pid; @@ -393,5 +397,5 @@ int main(int argc, char **argv) wait(NULL); - return ksft_exit_pass(); + ksft_exit_pass(); } -- cgit v1.2.3 From 3fa72f2c784b5c05f271ab8b34116d6a8e8d108d Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 29 Jun 2017 15:37:05 -0600 Subject: selftests: breakpoints: step_after_suspend_test use ksft_* var arg msg api Use ksft_* var arg msg to include strerror() info. in test output and simplify test_result and exit_* using var arg msg api. Signed-off-by: Shuah Khan --- .../breakpoints/step_after_suspend_test.c | 59 ++++++++++++---------- 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c index c60c2effb6bc..3fece06e9f64 100644 --- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c +++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c @@ -37,17 +37,19 @@ void child(int cpu) CPU_ZERO(&set); CPU_SET(cpu, &set); if (sched_setaffinity(0, sizeof(set), &set) != 0) { - perror("sched_setaffinity() failed"); + ksft_print_msg("sched_setaffinity() failed: %s\n", + strerror(errno)); _exit(1); } if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) != 0) { - perror("ptrace(PTRACE_TRACEME) failed"); + ksft_print_msg("ptrace(PTRACE_TRACEME) failed: %s\n", + strerror(errno)); _exit(1); } if (raise(SIGSTOP) != 0) { - perror("raise(SIGSTOP) failed"); + ksft_print_msg("raise(SIGSTOP) failed: %s\n", strerror(errno)); _exit(1); } @@ -61,7 +63,7 @@ bool run_test(int cpu) pid_t wpid; if (pid < 0) { - perror("fork() failed"); + ksft_print_msg("fork() failed: %s\n", strerror(errno)); return false; } if (pid == 0) @@ -69,57 +71,64 @@ bool run_test(int cpu) wpid = waitpid(pid, &status, __WALL); if (wpid != pid) { - perror("waitpid() failed"); + ksft_print_msg("waitpid() failed: %s\n", strerror(errno)); return false; } if (!WIFSTOPPED(status)) { - printf("child did not stop\n"); + ksft_print_msg("child did not stop: %s\n", strerror(errno)); return false; } if (WSTOPSIG(status) != SIGSTOP) { - printf("child did not stop with SIGSTOP\n"); + ksft_print_msg("child did not stop with SIGSTOP: %s\n", + strerror(errno)); return false; } if (ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) < 0) { if (errno == EIO) { - ksft_exit_skip("ptrace(PTRACE_SINGLESTEP) " - "not supported on this architecture"); + ksft_exit_skip( + "ptrace(PTRACE_SINGLESTEP) not supported on this architecture: %s\n", + strerror(errno)); } - perror("ptrace(PTRACE_SINGLESTEP) failed"); + ksft_print_msg("ptrace(PTRACE_SINGLESTEP) failed: %s\n", + strerror(errno)); return false; } wpid = waitpid(pid, &status, __WALL); if (wpid != pid) { - perror("waitpid() failed"); + ksft_print_msg("waitpid() failed: $s\n", strerror(errno)); return false; } if (WIFEXITED(status)) { - printf("child did not single-step\n"); + ksft_print_msg("child did not single-step: %s\n", + strerror(errno)); return false; } if (!WIFSTOPPED(status)) { - printf("child did not stop\n"); + ksft_print_msg("child did not stop: %s\n", strerror(errno)); return false; } if (WSTOPSIG(status) != SIGTRAP) { - printf("child did not stop with SIGTRAP\n"); + ksft_print_msg("child did not stop with SIGTRAP: %s\n", + strerror(errno)); return false; } if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) { - perror("ptrace(PTRACE_CONT) failed"); + ksft_print_msg("ptrace(PTRACE_CONT) failed: %s\n", + strerror(errno)); return false; } wpid = waitpid(pid, &status, __WALL); if (wpid != pid) { - perror("waitpid() failed"); + ksft_print_msg("waitpid() failed: %s\n", strerror(errno)); return false; } if (!WIFEXITED(status)) { - printf("child did not exit after PTRACE_CONT\n"); + ksft_print_msg("child did not exit after PTRACE_CONT: %s\n", + strerror(errno)); return false; } @@ -137,19 +146,19 @@ void suspend(void) power_state_fd = open("/sys/power/state", O_RDWR); if (power_state_fd < 0) ksft_exit_fail_msg( - "open(\"/sys/power/state\") failed (is this test running as root?)"); + "open(\"/sys/power/state\") failed (is this test running as root?)\n"); timerfd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0); if (timerfd < 0) - ksft_exit_fail_msg("timerfd_create() failed"); + ksft_exit_fail_msg("timerfd_create() failed\n"); spec.it_value.tv_sec = 5; err = timerfd_settime(timerfd, 0, &spec, NULL); if (err < 0) - ksft_exit_fail_msg("timerfd_settime() failed"); + ksft_exit_fail_msg("timerfd_settime() failed\n"); if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem")) - ksft_exit_fail_msg("entering suspend failed"); + ksft_exit_fail_msg("Failed to enter Suspend state\n"); close(timerfd); close(power_state_fd); @@ -163,7 +172,6 @@ int main(int argc, char **argv) cpu_set_t available_cpus; int err; int cpu; - char buf[10]; ksft_print_header(); @@ -184,7 +192,7 @@ int main(int argc, char **argv) err = sched_getaffinity(0, sizeof(available_cpus), &available_cpus); if (err < 0) - ksft_exit_fail_msg("sched_getaffinity() failed"); + ksft_exit_fail_msg("sched_getaffinity() failed\n"); for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { bool test_success; @@ -193,11 +201,10 @@ int main(int argc, char **argv) continue; test_success = run_test(cpu); - sprintf(buf, "CPU %d", cpu); if (test_success) { - ksft_test_result_pass(buf); + ksft_test_result_pass("CPU %d\n", cpu); } else { - ksft_test_result_fail(buf); + ksft_test_result_fail("CPU %d\n", cpu); succeeded = false; } } -- cgit v1.2.3 From 0732d06ee563bbcdf34ec889918baa62451b580d Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 29 Jun 2017 15:52:42 -0600 Subject: selftests: breakpoints: breakpoint_test_arm64: convert test to use TAP13 Convert breakpoint_test_arm64 output to TAP13 format. Use ksft_* var arg msg api to include strerror() info. in the output. Change output from child process to use ksft_print_msg() instead of ksft_exit_* to avoid double counting tests and ensure parent process does the test counter incrementing. Signed-off-by: Shuah Khan --- .../selftests/breakpoints/breakpoint_test_arm64.c | 94 +++++++++++++--------- 1 file changed, 58 insertions(+), 36 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c b/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c index fa6d57af5217..960d02100c26 100644 --- a/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c +++ b/tools/testing/selftests/breakpoints/breakpoint_test_arm64.c @@ -43,19 +43,25 @@ static void child(int size, int wr) volatile uint8_t *addr = &var[32 + wr]; if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) != 0) { - perror("ptrace(PTRACE_TRACEME) failed"); + ksft_print_msg( + "ptrace(PTRACE_TRACEME) failed: %s\n", + strerror(errno)); _exit(1); } if (raise(SIGSTOP) != 0) { - perror("raise(SIGSTOP) failed"); + ksft_print_msg( + "raise(SIGSTOP) failed: %s\n", strerror(errno)); _exit(1); } if ((uintptr_t) addr % size) { - perror("Wrong address write for the given size\n"); + ksft_print_msg( + "Wrong address write for the given size: %s\n", + strerror(errno)); _exit(1); } + switch (size) { case 1: *addr = 47; @@ -100,11 +106,14 @@ static bool set_watchpoint(pid_t pid, int size, int wp) if (ptrace(PTRACE_SETREGSET, pid, NT_ARM_HW_WATCH, &iov) == 0) return true; - if (errno == EIO) { - ksft_exit_skip("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) " - "not supported on this hardware\n"); - } - perror("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) failed"); + if (errno == EIO) + ksft_print_msg( + "ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) not supported on this hardware: %s\n", + strerror(errno)); + + ksft_print_msg( + "ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) failed: %s\n", + strerror(errno)); return false; } @@ -116,7 +125,8 @@ static bool run_test(int wr_size, int wp_size, int wr, int wp) pid_t wpid; if (pid < 0) { - perror("fork() failed"); + ksft_test_result_fail( + "fork() failed: %s\n", strerror(errno)); return false; } if (pid == 0) @@ -124,15 +134,17 @@ static bool run_test(int wr_size, int wp_size, int wr, int wp) wpid = waitpid(pid, &status, __WALL); if (wpid != pid) { - perror("waitpid() failed"); + ksft_print_msg( + "waitpid() failed: %s\n", strerror(errno)); return false; } if (!WIFSTOPPED(status)) { - printf("child did not stop\n"); + ksft_print_msg( + "child did not stop: %s\n", strerror(errno)); return false; } if (WSTOPSIG(status) != SIGSTOP) { - printf("child did not stop with SIGSTOP\n"); + ksft_print_msg("child did not stop with SIGSTOP\n"); return false; } @@ -140,42 +152,49 @@ static bool run_test(int wr_size, int wp_size, int wr, int wp) return false; if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) { - perror("ptrace(PTRACE_SINGLESTEP) failed"); + ksft_print_msg( + "ptrace(PTRACE_SINGLESTEP) failed: %s\n", + strerror(errno)); return false; } alarm(3); wpid = waitpid(pid, &status, __WALL); if (wpid != pid) { - perror("waitpid() failed"); + ksft_print_msg( + "waitpid() failed: %s\n", strerror(errno)); return false; } alarm(0); if (WIFEXITED(status)) { - printf("child did not single-step\t"); + ksft_print_msg("child did not single-step\n"); return false; } if (!WIFSTOPPED(status)) { - printf("child did not stop\n"); + ksft_print_msg("child did not stop\n"); return false; } if (WSTOPSIG(status) != SIGTRAP) { - printf("child did not stop with SIGTRAP\n"); + ksft_print_msg("child did not stop with SIGTRAP\n"); return false; } if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0) { - perror("ptrace(PTRACE_GETSIGINFO)"); + ksft_print_msg( + "ptrace(PTRACE_GETSIGINFO): %s\n", + strerror(errno)); return false; } if (siginfo.si_code != TRAP_HWBKPT) { - printf("Unexpected si_code %d\n", siginfo.si_code); + ksft_print_msg( + "Unexpected si_code %d\n", siginfo.si_code); return false; } kill(pid, SIGKILL); wpid = waitpid(pid, &status, 0); if (wpid != pid) { - perror("waitpid() failed"); + ksft_print_msg( + "waitpid() failed: %s\n", strerror(errno)); return false; } return true; @@ -193,6 +212,8 @@ int main(int argc, char **argv) int wr, wp, size; bool result; + ksft_print_header(); + act.sa_handler = sigalrm; sigemptyset(&act.sa_mask); act.sa_flags = 0; @@ -200,14 +221,16 @@ int main(int argc, char **argv) for (size = 1; size <= 32; size = size*2) { for (wr = 0; wr <= 32; wr = wr + size) { for (wp = wr - size; wp <= wr + size; wp = wp + size) { - printf("Test size = %d write offset = %d watchpoint offset = %d\t", size, wr, wp); result = run_test(size, MIN(size, 8), wr, wp); - if ((result && wr == wp) || (!result && wr != wp)) { - printf("[OK]\n"); - ksft_inc_pass_cnt(); - } else { - printf("[FAILED]\n"); - ksft_inc_fail_cnt(); + if ((result && wr == wp) || + (!result && wr != wp)) + ksft_test_result_pass( + "Test size = %d write offset = %d watchpoint offset = %d\n", + size, wr, wp); + else { + ksft_test_result_fail( + "Test size = %d write offset = %d watchpoint offset = %d\n", + size, wr, wp); succeeded = false; } } @@ -215,19 +238,18 @@ int main(int argc, char **argv) } for (size = 1; size <= 32; size = size*2) { - printf("Test size = %d write offset = %d watchpoint offset = -8\t", size, -size); - - if (run_test(size, 8, -size, -8)) { - printf("[OK]\n"); - ksft_inc_pass_cnt(); - } else { - printf("[FAILED]\n"); - ksft_inc_fail_cnt(); + if (run_test(size, 8, -size, -8)) + ksft_test_result_pass( + "Test size = %d write offset = %d watchpoint offset = -8\n", + size, -size); + else { + ksft_test_result_fail( + "Test size = %d write offset = %d watchpoint offset = -8\n", + size, -size); succeeded = false; } } - ksft_print_cnts(); if (succeeded) ksft_exit_pass(); else -- cgit v1.2.3 From e67f85fb96ca80e5a60ea69c536affed0affc77d Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 29 Jun 2017 16:54:57 -0600 Subject: selftests: membarrier: use ksft_* var arg msg api Use ksft_* var arg msg to include strerror() info. in test output. Remove redundant SKIP/FAIL/PASS logic as it is no longer needed with ksft_ api. Improve test output to be consistent and clear. Signed-off-by: Shuah Khan --- .../testing/selftests/membarrier/membarrier_test.c | 91 ++++++++++------------ 1 file changed, 41 insertions(+), 50 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c index 74a712eab2e6..21399fcf1a59 100644 --- a/tools/testing/selftests/membarrier/membarrier_test.c +++ b/tools/testing/selftests/membarrier/membarrier_test.c @@ -7,62 +7,63 @@ #include "../kselftest.h" -enum test_membarrier_status { - TEST_MEMBARRIER_PASS = 0, - TEST_MEMBARRIER_FAIL, - TEST_MEMBARRIER_SKIP, -}; - static int sys_membarrier(int cmd, int flags) { return syscall(__NR_membarrier, cmd, flags); } -static enum test_membarrier_status test_membarrier_cmd_fail(void) +static int test_membarrier_cmd_fail(void) { int cmd = -1, flags = 0; - const char *test_name = "membarrier command cmd=-1. Wrong command should fail"; if (sys_membarrier(cmd, flags) != -1) { - ksft_test_result_fail(test_name); - return TEST_MEMBARRIER_FAIL; + ksft_exit_fail_msg( + "sys membarrier invalid command test: command = %d, flags = %d. Should fail, but passed\n", + cmd, flags); } - ksft_test_result_pass(test_name); - return TEST_MEMBARRIER_PASS; + ksft_test_result_pass( + "sys membarrier invalid command test: command = %d, flags = %d. Failed as expected\n", + cmd, flags); + return 0; } -static enum test_membarrier_status test_membarrier_flags_fail(void) +static int test_membarrier_flags_fail(void) { int cmd = MEMBARRIER_CMD_QUERY, flags = 1; - const char *test_name = "MEMBARRIER_CMD_QUERY, flags=1, Wrong flags should fail"; if (sys_membarrier(cmd, flags) != -1) { - ksft_test_result_fail(test_name); - return TEST_MEMBARRIER_FAIL; + ksft_exit_fail_msg( + "sys membarrier MEMBARRIER_CMD_QUERY invalid flags test: flags = %d. Should fail, but passed\n", + flags); } - ksft_test_result_pass(test_name); - return TEST_MEMBARRIER_PASS; + ksft_test_result_pass( + "sys membarrier MEMBARRIER_CMD_QUERY invalid flags test: flags = %d. Failed as expected\n", + flags); + return 0; } -static enum test_membarrier_status test_membarrier_success(void) +static int test_membarrier_success(void) { int cmd = MEMBARRIER_CMD_SHARED, flags = 0; - const char *test_name = "execute MEMBARRIER_CMD_SHARED"; + const char *test_name = "sys membarrier MEMBARRIER_CMD_SHARED\n"; if (sys_membarrier(cmd, flags) != 0) { - ksft_test_result_fail(test_name); - return TEST_MEMBARRIER_FAIL; + ksft_exit_fail_msg( + "sys membarrier MEMBARRIER_CMD_SHARED test: flags = %d\n", + flags); } - ksft_test_result_pass(test_name); - return TEST_MEMBARRIER_PASS; + ksft_test_result_pass( + "sys membarrier MEMBARRIER_CMD_SHARED test: flags = %d\n", + flags); + return 0; } -static enum test_membarrier_status test_membarrier(void) +static int test_membarrier(void) { - enum test_membarrier_status status; + int status; status = test_membarrier_cmd_fail(); if (status) @@ -73,10 +74,10 @@ static enum test_membarrier_status test_membarrier(void) status = test_membarrier_success(); if (status) return status; - return TEST_MEMBARRIER_PASS; + return 0; } -static enum test_membarrier_status test_membarrier_query(void) +static int test_membarrier_query(void) { int flags = 0, ret; @@ -87,34 +88,24 @@ static enum test_membarrier_status test_membarrier_query(void) * It is valid to build a kernel with * CONFIG_MEMBARRIER=n. However, this skips the tests. */ - ksft_exit_skip("CONFIG_MEMBARRIER is not enabled\n"); + ksft_exit_skip( + "sys membarrier (CONFIG_MEMBARRIER) is disabled.\n"); } - ksft_test_result_fail("sys_membarrier() failed\n"); - return TEST_MEMBARRIER_FAIL; - } - if (!(ret & MEMBARRIER_CMD_SHARED)) { - ksft_test_result_fail("command MEMBARRIER_CMD_SHARED is not supported.\n"); - return TEST_MEMBARRIER_FAIL; + ksft_exit_fail_msg("sys_membarrier() failed\n"); } - ksft_test_result_pass("sys_membarrier available"); - return TEST_MEMBARRIER_PASS; + if (!(ret & MEMBARRIER_CMD_SHARED)) + ksft_exit_fail_msg("sys_membarrier is not supported.\n"); + + ksft_test_result_pass("sys_membarrier available\n"); + return 0; } int main(int argc, char **argv) { ksft_print_header(); - switch (test_membarrier_query()) { - case TEST_MEMBARRIER_FAIL: - return ksft_exit_fail(); - case TEST_MEMBARRIER_SKIP: - return ksft_exit_skip(NULL); - } - switch (test_membarrier()) { - case TEST_MEMBARRIER_FAIL: - return ksft_exit_fail(); - case TEST_MEMBARRIER_SKIP: - return ksft_exit_skip(NULL); - } - return ksft_exit_pass(); + test_membarrier_query(); + test_membarrier(); + + ksft_exit_pass(); } -- cgit v1.2.3