1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 3a9de470cSBruce Richardson */ 4a9de470cSBruce Richardson 5a9de470cSBruce Richardson #ifndef _TEST_H_ 6a9de470cSBruce Richardson #define _TEST_H_ 7a9de470cSBruce Richardson 872b452c5SDmitry Kozlyuk #include <errno.h> 9a9de470cSBruce Richardson #include <stddef.h> 1072b452c5SDmitry Kozlyuk #include <stdlib.h> 11a9de470cSBruce Richardson #include <sys/queue.h> 12a9de470cSBruce Richardson 13a9de470cSBruce Richardson #include <rte_hexdump.h> 14a9de470cSBruce Richardson #include <rte_common.h> 151f48a7d2SBruce Richardson #include <rte_os_shim.h> 16a9de470cSBruce Richardson 17a9de470cSBruce Richardson #define TEST_SUCCESS EXIT_SUCCESS 18a9de470cSBruce Richardson #define TEST_FAILED -1 19a9de470cSBruce Richardson #define TEST_SKIPPED 77 20a9de470cSBruce Richardson 21a9de470cSBruce Richardson /* Before including test.h file you can define 22a9de470cSBruce Richardson * TEST_TRACE_FAILURE(_file, _line, _func) macro to better trace/debug test 23a9de470cSBruce Richardson * failures. Mostly useful in test development phase. */ 24a9de470cSBruce Richardson #ifndef TEST_TRACE_FAILURE 25a9de470cSBruce Richardson # define TEST_TRACE_FAILURE(_file, _line, _func) 26a9de470cSBruce Richardson #endif 27a9de470cSBruce Richardson 28a9de470cSBruce Richardson #include <rte_test.h> 29a9de470cSBruce Richardson 30a9de470cSBruce Richardson #define TEST_ASSERT RTE_TEST_ASSERT 31a9de470cSBruce Richardson 32a9de470cSBruce Richardson #define TEST_ASSERT_EQUAL RTE_TEST_ASSERT_EQUAL 33a9de470cSBruce Richardson 34a9de470cSBruce Richardson /* Compare two buffers (length in bytes) */ 35a9de470cSBruce Richardson #define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...) do { \ 36a9de470cSBruce Richardson if (memcmp(a, b, len)) { \ 37a9de470cSBruce Richardson printf("TestCase %s() line %d failed: " \ 38a9de470cSBruce Richardson msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 39a9de470cSBruce Richardson TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 40a9de470cSBruce Richardson return TEST_FAILED; \ 41a9de470cSBruce Richardson } \ 42a9de470cSBruce Richardson } while (0) 43a9de470cSBruce Richardson 44a9de470cSBruce Richardson /* Compare two buffers with offset (length and offset in bytes) */ 45a9de470cSBruce Richardson #define TEST_ASSERT_BUFFERS_ARE_EQUAL_OFFSET(a, b, len, off, msg, ...) do { \ 46a9de470cSBruce Richardson const uint8_t *_a_with_off = (const uint8_t *)a + off; \ 47a9de470cSBruce Richardson const uint8_t *_b_with_off = (const uint8_t *)b + off; \ 48a9de470cSBruce Richardson TEST_ASSERT_BUFFERS_ARE_EQUAL(_a_with_off, _b_with_off, len, msg); \ 49a9de470cSBruce Richardson } while (0) 50a9de470cSBruce Richardson 51a9de470cSBruce Richardson /* Compare two buffers (length in bits) */ 52a9de470cSBruce Richardson #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(a, b, len, msg, ...) do { \ 53a9de470cSBruce Richardson uint8_t _last_byte_a, _last_byte_b; \ 54a9de470cSBruce Richardson uint8_t _last_byte_mask, _last_byte_bits; \ 55a9de470cSBruce Richardson TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, (len >> 3), msg); \ 56a9de470cSBruce Richardson if (len % 8) { \ 57a9de470cSBruce Richardson _last_byte_bits = len % 8; \ 58a9de470cSBruce Richardson _last_byte_mask = ~((1 << (8 - _last_byte_bits)) - 1); \ 59a9de470cSBruce Richardson _last_byte_a = ((const uint8_t *)a)[len >> 3]; \ 60a9de470cSBruce Richardson _last_byte_b = ((const uint8_t *)b)[len >> 3]; \ 61a9de470cSBruce Richardson _last_byte_a &= _last_byte_mask; \ 62a9de470cSBruce Richardson _last_byte_b &= _last_byte_mask; \ 63a9de470cSBruce Richardson if (_last_byte_a != _last_byte_b) { \ 64a9de470cSBruce Richardson printf("TestCase %s() line %d failed: " \ 65a9de470cSBruce Richardson msg "\n", __func__, __LINE__, ##__VA_ARGS__);\ 66a9de470cSBruce Richardson TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 67a9de470cSBruce Richardson return TEST_FAILED; \ 68a9de470cSBruce Richardson } \ 69a9de470cSBruce Richardson } \ 70a9de470cSBruce Richardson } while (0) 71a9de470cSBruce Richardson 72a9de470cSBruce Richardson /* Compare two buffers with offset (length and offset in bits) */ 73a9de470cSBruce Richardson #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET(a, b, len, off, msg, ...) do { \ 74a9de470cSBruce Richardson uint8_t _first_byte_a, _first_byte_b; \ 75a9de470cSBruce Richardson uint8_t _first_byte_mask, _first_byte_bits; \ 76a9de470cSBruce Richardson uint32_t _len_without_first_byte = (off % 8) ? \ 77a9de470cSBruce Richardson len - (8 - (off % 8)) : \ 78a9de470cSBruce Richardson len; \ 79a9de470cSBruce Richardson uint32_t _off_in_bytes = (off % 8) ? (off >> 3) + 1 : (off >> 3); \ 80a9de470cSBruce Richardson const uint8_t *_a_with_off = (const uint8_t *)a + _off_in_bytes; \ 81a9de470cSBruce Richardson const uint8_t *_b_with_off = (const uint8_t *)b + _off_in_bytes; \ 82a9de470cSBruce Richardson TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(_a_with_off, _b_with_off, \ 83a9de470cSBruce Richardson _len_without_first_byte, msg); \ 84a9de470cSBruce Richardson if (off % 8) { \ 85a9de470cSBruce Richardson _first_byte_bits = 8 - (off % 8); \ 86a9de470cSBruce Richardson _first_byte_mask = (1 << _first_byte_bits) - 1; \ 87a9de470cSBruce Richardson _first_byte_a = *(_a_with_off - 1); \ 88a9de470cSBruce Richardson _first_byte_b = *(_b_with_off - 1); \ 89a9de470cSBruce Richardson _first_byte_a &= _first_byte_mask; \ 90a9de470cSBruce Richardson _first_byte_b &= _first_byte_mask; \ 91a9de470cSBruce Richardson if (_first_byte_a != _first_byte_b) { \ 92a9de470cSBruce Richardson printf("TestCase %s() line %d failed: " \ 93a9de470cSBruce Richardson msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 94a9de470cSBruce Richardson TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 95a9de470cSBruce Richardson return TEST_FAILED; \ 96a9de470cSBruce Richardson } \ 97a9de470cSBruce Richardson } \ 98a9de470cSBruce Richardson } while (0) 99a9de470cSBruce Richardson 100a9de470cSBruce Richardson #define TEST_ASSERT_NOT_EQUAL RTE_TEST_ASSERT_NOT_EQUAL 101a9de470cSBruce Richardson 102a9de470cSBruce Richardson #define TEST_ASSERT_SUCCESS RTE_TEST_ASSERT_SUCCESS 103a9de470cSBruce Richardson 104a9de470cSBruce Richardson #define TEST_ASSERT_FAIL RTE_TEST_ASSERT_FAIL 105a9de470cSBruce Richardson 106a9de470cSBruce Richardson #define TEST_ASSERT_NULL RTE_TEST_ASSERT_NULL 107a9de470cSBruce Richardson 108a9de470cSBruce Richardson #define TEST_ASSERT_NOT_NULL RTE_TEST_ASSERT_NOT_NULL 109a9de470cSBruce Richardson 110a9de470cSBruce Richardson struct unit_test_case { 111a9de470cSBruce Richardson int (*setup)(void); 112a9de470cSBruce Richardson void (*teardown)(void); 113a9de470cSBruce Richardson int (*testcase)(void); 114e65da89cSCiara Power int (*testcase_with_data)(const void *data); 115a9de470cSBruce Richardson const char *name; 116a9de470cSBruce Richardson unsigned enabled; 117e65da89cSCiara Power const void *data; 118a9de470cSBruce Richardson }; 119a9de470cSBruce Richardson 120e65da89cSCiara Power #define TEST_CASE(fn) { NULL, NULL, fn, NULL, #fn, 1, NULL } 121a9de470cSBruce Richardson 122e65da89cSCiara Power #define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, NULL, name, 1, NULL } 123a9de470cSBruce Richardson 124a9de470cSBruce Richardson #define TEST_CASE_ST(setup, teardown, testcase) \ 125e65da89cSCiara Power { setup, teardown, testcase, NULL, #testcase, 1, NULL } 126a9de470cSBruce Richardson 127e65da89cSCiara Power #define TEST_CASE_WITH_DATA(setup, teardown, testcase, data) \ 128e65da89cSCiara Power { setup, teardown, NULL, testcase, #testcase, 1, data } 129a9de470cSBruce Richardson 130474f1202SAnoob Joseph #define TEST_CASE_NAMED_ST(name, setup, teardown, testcase) \ 13163bf81a6SAnatoly Burakov { setup, teardown, testcase, NULL, name, 1, NULL } 132474f1202SAnoob Joseph 133474f1202SAnoob Joseph #define TEST_CASE_NAMED_WITH_DATA(name, setup, teardown, testcase, data) \ 134474f1202SAnoob Joseph { setup, teardown, NULL, testcase, name, 1, data } 135474f1202SAnoob Joseph 136e65da89cSCiara Power #define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, NULL, #fn, 0, NULL } 137a9de470cSBruce Richardson 138a9de470cSBruce Richardson #define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \ 139e65da89cSCiara Power { setup, teardown, testcase, NULL, #testcase, 0, NULL } 140a9de470cSBruce Richardson 141e65da89cSCiara Power #define TEST_CASES_END() { NULL, NULL, NULL, NULL, NULL, 0, NULL } 142a9de470cSBruce Richardson 143a9de470cSBruce Richardson static inline void 144a9de470cSBruce Richardson debug_hexdump(FILE *file, const char *title, const void *buf, size_t len) 145a9de470cSBruce Richardson { 146a9de470cSBruce Richardson if (rte_log_get_global_level() == RTE_LOG_DEBUG) 147a9de470cSBruce Richardson rte_hexdump(file, title, buf, len); 148a9de470cSBruce Richardson } 149a9de470cSBruce Richardson 150a9de470cSBruce Richardson struct unit_test_suite { 151a9de470cSBruce Richardson const char *suite_name; 152a9de470cSBruce Richardson int (*setup)(void); 153a9de470cSBruce Richardson void (*teardown)(void); 154caa817f0SCiara Power unsigned int total; 155caa817f0SCiara Power unsigned int executed; 156caa817f0SCiara Power unsigned int succeeded; 157caa817f0SCiara Power unsigned int skipped; 158caa817f0SCiara Power unsigned int failed; 159caa817f0SCiara Power unsigned int unsupported; 160fbc53675SCiara Power struct unit_test_suite **unit_test_suites; 161a9de470cSBruce Richardson struct unit_test_case unit_test_cases[]; 162a9de470cSBruce Richardson }; 163a9de470cSBruce Richardson 164a9de470cSBruce Richardson int unit_test_suite_runner(struct unit_test_suite *suite); 165a9de470cSBruce Richardson extern int last_test_result; 166a9de470cSBruce Richardson 167a9de470cSBruce Richardson #define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE" 168a9de470cSBruce Richardson 169a9de470cSBruce Richardson #include <cmdline_parse.h> 170a9de470cSBruce Richardson #include <cmdline_parse_string.h> 171a9de470cSBruce Richardson 172a9de470cSBruce Richardson extern const char *prgname; 173a9de470cSBruce Richardson 174a9de470cSBruce Richardson int commands_init(void); 175ace2f054SBruce Richardson int command_valid(const char *cmd); 176a9de470cSBruce Richardson 177a9de470cSBruce Richardson int test_mp_secondary(void); 17850247fe0SErik Gabriel Carrillo int test_timer_secondary(void); 179a9de470cSBruce Richardson 180a9de470cSBruce Richardson int test_set_rxtx_conf(cmdline_fixed_string_t mode); 181a9de470cSBruce Richardson int test_set_rxtx_anchor(cmdline_fixed_string_t type); 182a9de470cSBruce Richardson int test_set_rxtx_sc(cmdline_fixed_string_t type); 183a9de470cSBruce Richardson 184a9de470cSBruce Richardson typedef int (test_callback)(void); 185a9de470cSBruce Richardson TAILQ_HEAD(test_commands_list, test_command); 186a9de470cSBruce Richardson struct test_command { 187a9de470cSBruce Richardson TAILQ_ENTRY(test_command) next; 188a9de470cSBruce Richardson const char *command; 189a9de470cSBruce Richardson test_callback *callback; 190a9de470cSBruce Richardson }; 191a9de470cSBruce Richardson 192a9de470cSBruce Richardson void add_test_command(struct test_command *t); 193a9de470cSBruce Richardson 194c118fbc9SBruce Richardson /* Register a test function with its command string. Should not be used directly */ 195a9de470cSBruce Richardson #define REGISTER_TEST_COMMAND(cmd, func) \ 196a9de470cSBruce Richardson static struct test_command test_struct_##cmd = { \ 197a9de470cSBruce Richardson .command = RTE_STR(cmd), \ 198a9de470cSBruce Richardson .callback = func, \ 199a9de470cSBruce Richardson }; \ 20055878866SJerin Jacob RTE_INIT(test_register_##cmd) \ 201a9de470cSBruce Richardson { \ 202a9de470cSBruce Richardson add_test_command(&test_struct_##cmd); \ 203a9de470cSBruce Richardson } 204a9de470cSBruce Richardson 205c118fbc9SBruce Richardson /* Register a test function as a particular type. 206c118fbc9SBruce Richardson * These can be used to build up test suites automatically 207c118fbc9SBruce Richardson */ 208c118fbc9SBruce Richardson #define REGISTER_FAST_TEST(cmd, no_huge, ASan, func) REGISTER_TEST_COMMAND(cmd, func) 209c118fbc9SBruce Richardson #define REGISTER_PERF_TEST REGISTER_TEST_COMMAND 210c118fbc9SBruce Richardson #define REGISTER_DRIVER_TEST REGISTER_TEST_COMMAND 211*06e28566SKonstantin Ananyev #define REGISTER_STRESS_TEST REGISTER_TEST_COMMAND 212c118fbc9SBruce Richardson 213a9de470cSBruce Richardson #endif 214