1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #ifndef _TEST_H_ 35 #define _TEST_H_ 36 37 #include <stddef.h> 38 #include <sys/queue.h> 39 40 #include <rte_common.h> 41 #include <rte_log.h> 42 43 #define TEST_SUCCESS (0) 44 #define TEST_FAILED (-1) 45 46 /* Before including test.h file you can define 47 * TEST_TRACE_FAILURE(_file, _line, _func) macro to better trace/debug test 48 * failures. Mostly useful in test development phase. */ 49 #ifndef TEST_TRACE_FAILURE 50 # define TEST_TRACE_FAILURE(_file, _line, _func) 51 #endif 52 53 #define TEST_ASSERT(cond, msg, ...) do { \ 54 if (!(cond)) { \ 55 printf("TestCase %s() line %d failed: " \ 56 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 57 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 58 return TEST_FAILED; \ 59 } \ 60 } while (0) 61 62 #define TEST_ASSERT_EQUAL(a, b, msg, ...) do { \ 63 if (!(a == b)) { \ 64 printf("TestCase %s() line %d failed: " \ 65 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 66 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 67 return TEST_FAILED; \ 68 } \ 69 } while (0) 70 71 /* Compare two buffers (length in bytes) */ 72 #define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...) do { \ 73 if (memcmp(a, b, len)) { \ 74 printf("TestCase %s() line %d failed: " \ 75 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 76 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 77 return TEST_FAILED; \ 78 } \ 79 } while (0) 80 81 /* Compare two buffers with offset (length and offset in bytes) */ 82 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_OFFSET(a, b, len, off, msg, ...) do { \ 83 const uint8_t *_a_with_off = (const uint8_t *)a + off; \ 84 const uint8_t *_b_with_off = (const uint8_t *)b + off; \ 85 TEST_ASSERT_BUFFERS_ARE_EQUAL(_a_with_off, _b_with_off, len, msg); \ 86 } while (0) 87 88 /* Compare two buffers (length in bits) */ 89 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(a, b, len, msg, ...) do { \ 90 uint8_t _last_byte_a, _last_byte_b; \ 91 uint8_t _last_byte_mask, _last_byte_bits; \ 92 TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, (len >> 3), msg); \ 93 if (len % 8) { \ 94 _last_byte_bits = len % 8; \ 95 _last_byte_mask = ~((1 << (8 - _last_byte_bits)) - 1); \ 96 _last_byte_a = ((const uint8_t *)a)[len >> 3]; \ 97 _last_byte_b = ((const uint8_t *)b)[len >> 3]; \ 98 _last_byte_a &= _last_byte_mask; \ 99 _last_byte_b &= _last_byte_mask; \ 100 if (_last_byte_a != _last_byte_b) { \ 101 printf("TestCase %s() line %d failed: " \ 102 msg "\n", __func__, __LINE__, ##__VA_ARGS__);\ 103 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 104 return TEST_FAILED; \ 105 } \ 106 } \ 107 } while (0) 108 109 /* Compare two buffers with offset (length and offset in bits) */ 110 #define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET(a, b, len, off, msg, ...) do { \ 111 uint8_t _first_byte_a, _first_byte_b; \ 112 uint8_t _first_byte_mask, _first_byte_bits; \ 113 uint32_t _len_without_first_byte = (off % 8) ? \ 114 len - (8 - (off % 8)) : \ 115 len; \ 116 uint32_t _off_in_bytes = (off % 8) ? (off >> 3) + 1 : (off >> 3); \ 117 const uint8_t *_a_with_off = (const uint8_t *)a + _off_in_bytes; \ 118 const uint8_t *_b_with_off = (const uint8_t *)b + _off_in_bytes; \ 119 TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(_a_with_off, _b_with_off, \ 120 _len_without_first_byte, msg); \ 121 if (off % 8) { \ 122 _first_byte_bits = 8 - (off % 8); \ 123 _first_byte_mask = (1 << _first_byte_bits) - 1; \ 124 _first_byte_a = *(_a_with_off - 1); \ 125 _first_byte_b = *(_b_with_off - 1); \ 126 _first_byte_a &= _first_byte_mask; \ 127 _first_byte_b &= _first_byte_mask; \ 128 if (_first_byte_a != _first_byte_b) { \ 129 printf("TestCase %s() line %d failed: " \ 130 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 131 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 132 return TEST_FAILED; \ 133 } \ 134 } \ 135 } while (0) 136 137 #define TEST_ASSERT_NOT_EQUAL(a, b, msg, ...) do { \ 138 if (!(a != b)) { \ 139 printf("TestCase %s() line %d failed: " \ 140 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 141 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 142 return TEST_FAILED; \ 143 } \ 144 } while (0) 145 146 #define TEST_ASSERT_SUCCESS(val, msg, ...) do { \ 147 typeof(val) _val = (val); \ 148 if (!(_val == 0)) { \ 149 printf("TestCase %s() line %d failed (err %d): " \ 150 msg "\n", __func__, __LINE__, _val, \ 151 ##__VA_ARGS__); \ 152 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 153 return TEST_FAILED; \ 154 } \ 155 } while (0) 156 157 #define TEST_ASSERT_FAIL(val, msg, ...) do { \ 158 if (!(val != 0)) { \ 159 printf("TestCase %s() line %d failed: " \ 160 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 161 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 162 return TEST_FAILED; \ 163 } \ 164 } while (0) 165 166 #define TEST_ASSERT_NULL(val, msg, ...) do { \ 167 if (!(val == NULL)) { \ 168 printf("TestCase %s() line %d failed: " \ 169 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 170 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 171 return TEST_FAILED; \ 172 } \ 173 } while (0) 174 175 #define TEST_ASSERT_NOT_NULL(val, msg, ...) do { \ 176 if (!(val != NULL)) { \ 177 printf("TestCase %s() line %d failed: " \ 178 msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ 179 TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ 180 return TEST_FAILED; \ 181 } \ 182 } while (0) 183 184 struct unit_test_case { 185 int (*setup)(void); 186 void (*teardown)(void); 187 int (*testcase)(void); 188 const char *success_msg; 189 const char *fail_msg; 190 unsigned enabled; 191 }; 192 193 #define TEST_CASE(fn) { NULL, NULL, fn, #fn " succeeded", #fn " failed", 1 } 194 195 #define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, name " succeeded", \ 196 name " failed", 1 } 197 198 #define TEST_CASE_ST(setup, teardown, testcase) \ 199 { setup, teardown, testcase, #testcase " succeeded", \ 200 #testcase " failed ", 1 } 201 202 203 #define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, #fn " succeeded", \ 204 #fn " failed", 0 } 205 206 #define TEST_CASE_ST_DISABLED(setup, teardown, testcase) \ 207 { setup, teardown, testcase, #testcase " succeeded", \ 208 #testcase " failed ", 0 } 209 210 #define TEST_CASES_END() { NULL, NULL, NULL, NULL, NULL, 0 } 211 212 #if RTE_LOG_LEVEL >= RTE_LOG_DEBUG 213 #define TEST_HEXDUMP(file, title, buf, len) rte_hexdump(file, title, buf, len) 214 #else 215 #define TEST_HEXDUMP(file, title, buf, len) do {} while (0) 216 #endif 217 218 struct unit_test_suite { 219 const char *suite_name; 220 int (*setup)(void); 221 void (*teardown)(void); 222 struct unit_test_case unit_test_cases[]; 223 }; 224 225 int unit_test_suite_runner(struct unit_test_suite *suite); 226 227 #define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE" 228 229 #include <cmdline_parse.h> 230 #include <cmdline_parse_string.h> 231 232 extern const char *prgname; 233 234 int commands_init(void); 235 236 int test_pci(void); 237 int test_pci_run; 238 239 int test_mp_secondary(void); 240 241 int test_set_rxtx_conf(cmdline_fixed_string_t mode); 242 int test_set_rxtx_anchor(cmdline_fixed_string_t type); 243 int test_set_rxtx_sc(cmdline_fixed_string_t type); 244 245 typedef int (test_callback)(void); 246 TAILQ_HEAD(test_commands_list, test_command); 247 struct test_command { 248 TAILQ_ENTRY(test_command) next; 249 const char *command; 250 test_callback *callback; 251 }; 252 253 void add_test_command(struct test_command *t); 254 255 /* Register a test function with its command string */ 256 #define REGISTER_TEST_COMMAND(cmd, func) \ 257 static struct test_command test_struct_##cmd = { \ 258 .command = RTE_STR(cmd), \ 259 .callback = func, \ 260 }; \ 261 static void __attribute__((constructor, used)) \ 262 test_register_##cmd(void) \ 263 { \ 264 add_test_command(&test_struct_##cmd); \ 265 } 266 267 #endif 268