1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2 3 #define _GNU_SOURCE 4 5 #ifdef NDEBUG 6 #undef NDEBUG 7 #endif 8 9 #if HAVE_CONFIG_H 10 #include "config.h" 11 #endif 12 13 #include <assert.h> 14 #include <fcntl.h> 15 #include <stdbool.h> 16 #include <stdint.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <unistd.h> 21 22 #include "compiler.h" 23 #include "libmctp-alloc.h" 24 #include "libmctp-log.h" 25 #include "range.h" 26 #include "test-utils.h" 27 28 #define TEST_DEST_EID 9 29 #define TEST_SRC_EID 10 30 31 #ifndef ARRAY_SIZE 32 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 33 #endif 34 35 #define MAX_PAYLOAD_SIZE 50000 36 37 struct pktbuf { 38 struct mctp_hdr hdr; 39 uint8_t *payload; 40 }; 41 42 struct test_params { 43 bool seen; 44 size_t message_size; 45 uint8_t msg_tag; 46 bool tag_owner; 47 }; 48 49 static void rx_message(uint8_t eid __unused, bool tag_owner, uint8_t msg_tag, 50 void *data, void *msg __unused, size_t len) 51 { 52 struct test_params *param = (struct test_params *)data; 53 54 mctp_prdebug("MCTP message received: len %zd, tag %u", len, msg_tag); 55 56 param->seen = true; 57 param->message_size = len; 58 param->msg_tag = msg_tag; 59 param->tag_owner = tag_owner; 60 } 61 62 static uint8_t get_sequence() 63 { 64 static uint8_t pkt_seq = 0; 65 66 return (pkt_seq++ % 4); 67 } 68 69 static uint8_t get_tag() 70 { 71 static uint8_t tag = 0; 72 73 return (tag++ % 8); 74 } 75 76 /* 77 * receive_pktbuf bypasses all bindings and directly invokes mctp_bus_rx. 78 * This is necessary in order invoke test cases on the core functionality. 79 * The memory allocated for the mctp packet is capped at MCTP_BTU 80 * size, however, the mimiced rx pkt still retains the len parameter. 81 * This allows to mimic packets larger than a sane memory allocator can 82 * provide. 83 */ 84 static void receive_ptkbuf(struct mctp_binding_test *binding, 85 const struct pktbuf *pktbuf, size_t len) 86 { 87 size_t alloc_size = MIN((size_t)MCTP_BTU, len); 88 struct mctp_pktbuf *rx_pkt; 89 90 rx_pkt = __mctp_alloc(sizeof(*rx_pkt) + MCTP_PACKET_SIZE(alloc_size)); 91 assert(rx_pkt); 92 93 /* Preserve passed len parameter */ 94 rx_pkt->size = MCTP_PACKET_SIZE(len); 95 rx_pkt->start = 0; 96 rx_pkt->end = MCTP_PACKET_SIZE(len); 97 rx_pkt->mctp_hdr_off = 0; 98 rx_pkt->next = NULL; 99 memcpy(rx_pkt->data, &pktbuf->hdr, sizeof(pktbuf->hdr)); 100 memcpy(rx_pkt->data + sizeof(pktbuf->hdr), pktbuf->payload, alloc_size); 101 102 mctp_bus_rx((struct mctp_binding *)binding, rx_pkt); 103 } 104 105 static void receive_one_fragment(struct mctp_binding_test *binding, 106 uint8_t *payload, size_t fragment_size, 107 uint8_t flags_seq_tag, struct pktbuf *pktbuf) 108 { 109 pktbuf->hdr.flags_seq_tag = flags_seq_tag; 110 pktbuf->payload = payload; 111 receive_ptkbuf(binding, pktbuf, fragment_size); 112 } 113 114 static void receive_two_fragment_message(struct mctp_binding_test *binding, 115 uint8_t *payload, 116 size_t fragment1_size, 117 size_t fragment2_size, 118 struct pktbuf *pktbuf) 119 { 120 uint8_t tag = MCTP_HDR_FLAG_TO | get_tag(); 121 uint8_t flags_seq_tag; 122 123 flags_seq_tag = MCTP_HDR_FLAG_SOM | 124 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 125 receive_one_fragment(binding, payload, fragment1_size, flags_seq_tag, 126 pktbuf); 127 128 flags_seq_tag = MCTP_HDR_FLAG_EOM | 129 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 130 receive_one_fragment(binding, payload + fragment1_size, fragment2_size, 131 flags_seq_tag, pktbuf); 132 } 133 134 static void mctp_core_test_simple_rx() 135 { 136 struct mctp *mctp = NULL; 137 struct mctp_binding_test *binding = NULL; 138 struct test_params test_param; 139 uint8_t test_payload[2 * MCTP_BTU]; 140 struct pktbuf pktbuf; 141 142 memset(test_payload, 0, sizeof(test_payload)); 143 test_param.seen = false; 144 test_param.message_size = 0; 145 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 146 mctp_set_rx_all(mctp, rx_message, &test_param); 147 memset(&pktbuf, 0, sizeof(pktbuf)); 148 pktbuf.hdr.dest = TEST_DEST_EID; 149 pktbuf.hdr.src = TEST_SRC_EID; 150 151 /* Receive 2 fragments of equal size */ 152 receive_two_fragment_message(binding, test_payload, MCTP_BTU, MCTP_BTU, 153 &pktbuf); 154 155 assert(test_param.seen); 156 assert(test_param.message_size == 2 * MCTP_BTU); 157 158 mctp_binding_test_destroy(binding); 159 mctp_destroy(mctp); 160 } 161 162 static void mctp_core_test_receive_equal_length_fragments() 163 { 164 struct mctp *mctp = NULL; 165 struct mctp_binding_test *binding = NULL; 166 struct test_params test_param; 167 static uint8_t test_payload[MAX_PAYLOAD_SIZE]; 168 uint8_t tag = MCTP_HDR_FLAG_TO | get_tag(); 169 struct pktbuf pktbuf; 170 uint8_t flags_seq_tag; 171 172 memset(test_payload, 0, sizeof(test_payload)); 173 test_param.seen = false; 174 test_param.message_size = 0; 175 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 176 mctp_set_rx_all(mctp, rx_message, &test_param); 177 memset(&pktbuf, 0, sizeof(pktbuf)); 178 pktbuf.hdr.dest = TEST_DEST_EID; 179 pktbuf.hdr.src = TEST_SRC_EID; 180 181 /* Receive 3 fragments, each of size MCTP_BTU */ 182 flags_seq_tag = MCTP_HDR_FLAG_SOM | 183 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 184 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 185 &pktbuf); 186 187 flags_seq_tag = (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 188 receive_one_fragment(binding, test_payload + MCTP_BTU, MCTP_BTU, 189 flags_seq_tag, &pktbuf); 190 191 flags_seq_tag = MCTP_HDR_FLAG_EOM | 192 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 193 receive_one_fragment(binding, test_payload + (2 * MCTP_BTU), MCTP_BTU, 194 flags_seq_tag, &pktbuf); 195 196 assert(test_param.seen); 197 assert(test_param.message_size == 3 * MCTP_BTU); 198 199 mctp_binding_test_destroy(binding); 200 mctp_destroy(mctp); 201 } 202 203 static void mctp_core_test_receive_unexpected_smaller_middle_fragment() 204 { 205 struct mctp *mctp = NULL; 206 struct mctp_binding_test *binding = NULL; 207 struct test_params test_param; 208 static uint8_t test_payload[MAX_PAYLOAD_SIZE]; 209 uint8_t tag = MCTP_HDR_FLAG_TO | get_tag(); 210 struct pktbuf pktbuf; 211 uint8_t flags_seq_tag; 212 213 memset(test_payload, 0, sizeof(test_payload)); 214 test_param.seen = false; 215 test_param.message_size = 0; 216 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 217 mctp_set_rx_all(mctp, rx_message, &test_param); 218 memset(&pktbuf, 0, sizeof(pktbuf)); 219 pktbuf.hdr.dest = TEST_DEST_EID; 220 pktbuf.hdr.src = TEST_SRC_EID; 221 222 /* Middle fragment with size MCTP_BTU - 1 */ 223 flags_seq_tag = MCTP_HDR_FLAG_SOM | 224 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 225 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 226 &pktbuf); 227 228 flags_seq_tag = (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 229 receive_one_fragment(binding, test_payload + MCTP_BTU, MCTP_BTU - 1, 230 flags_seq_tag, &pktbuf); 231 232 flags_seq_tag = MCTP_HDR_FLAG_EOM | 233 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 234 receive_one_fragment(binding, test_payload + (2 * MCTP_BTU), MCTP_BTU, 235 flags_seq_tag, &pktbuf); 236 237 assert(!test_param.seen); 238 239 mctp_binding_test_destroy(binding); 240 mctp_destroy(mctp); 241 } 242 243 static void mctp_core_test_receive_unexpected_bigger_middle_fragment() 244 { 245 struct mctp *mctp = NULL; 246 struct mctp_binding_test *binding = NULL; 247 struct test_params test_param; 248 static uint8_t test_payload[MAX_PAYLOAD_SIZE]; 249 uint8_t tag = MCTP_HDR_FLAG_TO | get_tag(); 250 struct pktbuf pktbuf; 251 uint8_t flags_seq_tag; 252 253 memset(test_payload, 0, sizeof(test_payload)); 254 test_param.seen = false; 255 test_param.message_size = 0; 256 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 257 mctp_set_rx_all(mctp, rx_message, &test_param); 258 memset(&pktbuf, 0, sizeof(pktbuf)); 259 pktbuf.hdr.dest = TEST_DEST_EID; 260 pktbuf.hdr.src = TEST_SRC_EID; 261 262 /* Middle fragment with size MCTP_BTU + 1 */ 263 flags_seq_tag = MCTP_HDR_FLAG_SOM | 264 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 265 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 266 &pktbuf); 267 268 flags_seq_tag = (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 269 receive_one_fragment(binding, test_payload + MCTP_BTU, MCTP_BTU + 1, 270 flags_seq_tag, &pktbuf); 271 272 flags_seq_tag = MCTP_HDR_FLAG_EOM | 273 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 274 receive_one_fragment(binding, test_payload + (2 * MCTP_BTU), MCTP_BTU, 275 flags_seq_tag, &pktbuf); 276 277 assert(!test_param.seen); 278 279 mctp_binding_test_destroy(binding); 280 mctp_destroy(mctp); 281 } 282 283 static void mctp_core_test_receive_smaller_end_fragment() 284 { 285 struct mctp *mctp = NULL; 286 struct mctp_binding_test *binding = NULL; 287 struct test_params test_param; 288 static uint8_t test_payload[MAX_PAYLOAD_SIZE]; 289 uint8_t tag = MCTP_HDR_FLAG_TO | get_tag(); 290 uint8_t end_frag_size = MCTP_BTU - 10; 291 struct pktbuf pktbuf; 292 uint8_t flags_seq_tag; 293 294 memset(test_payload, 0, sizeof(test_payload)); 295 test_param.seen = false; 296 test_param.message_size = 0; 297 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 298 mctp_set_rx_all(mctp, rx_message, &test_param); 299 memset(&pktbuf, 0, sizeof(pktbuf)); 300 pktbuf.hdr.dest = TEST_DEST_EID; 301 pktbuf.hdr.src = TEST_SRC_EID; 302 303 flags_seq_tag = MCTP_HDR_FLAG_SOM | 304 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 305 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 306 &pktbuf); 307 308 flags_seq_tag = (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 309 receive_one_fragment(binding, test_payload + MCTP_BTU, MCTP_BTU, 310 flags_seq_tag, &pktbuf); 311 312 flags_seq_tag = MCTP_HDR_FLAG_EOM | 313 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 314 receive_one_fragment(binding, test_payload + (2 * MCTP_BTU), 315 end_frag_size, flags_seq_tag, &pktbuf); 316 317 assert(test_param.seen); 318 assert(test_param.message_size == 319 (size_t)(2 * MCTP_BTU + end_frag_size)); 320 321 mctp_binding_test_destroy(binding); 322 mctp_destroy(mctp); 323 } 324 325 static void mctp_core_test_receive_bigger_end_fragment() 326 { 327 struct mctp *mctp = NULL; 328 struct mctp_binding_test *binding = NULL; 329 struct test_params test_param; 330 static uint8_t test_payload[MAX_PAYLOAD_SIZE]; 331 uint8_t tag = MCTP_HDR_FLAG_TO | get_tag(); 332 uint8_t end_frag_size = MCTP_BTU + 10; 333 struct pktbuf pktbuf; 334 uint8_t flags_seq_tag; 335 336 memset(test_payload, 0, sizeof(test_payload)); 337 test_param.seen = false; 338 test_param.message_size = 0; 339 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 340 mctp_set_rx_all(mctp, rx_message, &test_param); 341 memset(&pktbuf, 0, sizeof(pktbuf)); 342 pktbuf.hdr.dest = TEST_DEST_EID; 343 pktbuf.hdr.src = TEST_SRC_EID; 344 345 flags_seq_tag = MCTP_HDR_FLAG_SOM | 346 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 347 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 348 &pktbuf); 349 350 flags_seq_tag = (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 351 receive_one_fragment(binding, test_payload + MCTP_BTU, MCTP_BTU, 352 flags_seq_tag, &pktbuf); 353 354 flags_seq_tag = MCTP_HDR_FLAG_EOM | 355 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 356 receive_one_fragment(binding, test_payload + (2 * MCTP_BTU), 357 end_frag_size, flags_seq_tag, &pktbuf); 358 359 assert(!test_param.seen); 360 361 mctp_binding_test_destroy(binding); 362 mctp_destroy(mctp); 363 } 364 365 static void mctp_core_test_drop_large_fragments() 366 { 367 struct mctp *mctp = NULL; 368 struct mctp_binding_test *binding = NULL; 369 struct test_params test_param; 370 static uint8_t test_payload[MAX_PAYLOAD_SIZE]; 371 struct pktbuf pktbuf; 372 373 memset(test_payload, 0, sizeof(test_payload)); 374 test_param.seen = false; 375 test_param.message_size = 0; 376 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 377 mctp_set_rx_all(mctp, rx_message, &test_param); 378 memset(&pktbuf, 0, sizeof(pktbuf)); 379 pktbuf.hdr.dest = TEST_DEST_EID; 380 pktbuf.hdr.src = TEST_SRC_EID; 381 382 /* Receive a large payload - first fragment with MCTP_BTU bytes, 383 * 2nd fragment of SIZE_MAX */ 384 385 receive_two_fragment_message(binding, test_payload, MCTP_BTU, 386 SIZE_MAX - sizeof(struct mctp_hdr), &pktbuf); 387 388 assert(!test_param.seen); 389 390 mctp_binding_test_destroy(binding); 391 mctp_destroy(mctp); 392 } 393 394 static void mctp_core_test_exhaust_context_buffers() 395 { 396 struct mctp *mctp = NULL; 397 struct mctp_binding_test *binding = NULL; 398 struct test_params test_param; 399 static uint8_t test_payload[MAX_PAYLOAD_SIZE]; 400 uint8_t tag = MCTP_HDR_FLAG_TO | get_tag(); 401 uint8_t i = 0; 402 const uint8_t max_context_buffers = 16; 403 struct pktbuf pktbuf; 404 uint8_t flags_seq_tag; 405 406 memset(test_payload, 0, sizeof(test_payload)); 407 test_param.seen = false; 408 test_param.message_size = 0; 409 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 410 mctp_set_rx_all(mctp, rx_message, &test_param); 411 memset(&pktbuf, 0, sizeof(pktbuf)); 412 pktbuf.hdr.dest = TEST_DEST_EID; 413 pktbuf.hdr.src = TEST_SRC_EID; 414 415 /* Exhaust all 16 context buffers*/ 416 for (i = 0; i < max_context_buffers; i++) { 417 flags_seq_tag = MCTP_HDR_FLAG_SOM | 418 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 419 receive_one_fragment(binding, test_payload, MCTP_BTU, 420 flags_seq_tag, &pktbuf); 421 422 /* Change source EID so that different contexts are created */ 423 pktbuf.hdr.src++; 424 } 425 426 /* Send a full message from a different EID */ 427 pktbuf.hdr.src++; 428 receive_two_fragment_message(binding, test_payload, MCTP_BTU, MCTP_BTU, 429 &pktbuf); 430 431 /* Message assembly should fail */ 432 assert(!test_param.seen); 433 434 /* Complete message assembly for one of the messages */ 435 pktbuf.hdr.src -= max_context_buffers; 436 flags_seq_tag = MCTP_HDR_FLAG_EOM | 437 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | tag; 438 receive_one_fragment(binding, test_payload, MCTP_BTU, 439 flags_seq_tag, &pktbuf); 440 441 assert(test_param.seen); 442 assert(test_param.message_size == (2 * MCTP_BTU)); 443 444 mctp_binding_test_destroy(binding); 445 mctp_destroy(mctp); 446 } 447 448 static void mctp_core_test_rx_with_tag() 449 { 450 struct mctp *mctp = NULL; 451 struct mctp_binding_test *binding = NULL; 452 struct test_params test_param; 453 static uint8_t test_payload[MCTP_BTU]; 454 uint8_t tag = get_tag(); 455 struct pktbuf pktbuf; 456 uint8_t flags_seq_tag; 457 458 memset(test_payload, 0, sizeof(test_payload)); 459 test_param.seen = false; 460 test_param.message_size = 0; 461 test_param.msg_tag = 0; 462 test_param.tag_owner = false; 463 464 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 465 mctp_set_rx_all(mctp, rx_message, &test_param); 466 memset(&pktbuf, 0, sizeof(pktbuf)); 467 pktbuf.hdr.dest = TEST_DEST_EID; 468 pktbuf.hdr.src = TEST_SRC_EID; 469 470 /* Set tag and tag owner fields for a recieve packet */ 471 flags_seq_tag = MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM | 472 (1 << MCTP_HDR_TO_SHIFT) | tag; 473 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 474 &pktbuf); 475 476 assert(test_param.seen); 477 assert(test_param.message_size == (MCTP_BTU)); 478 assert(test_param.msg_tag == tag); 479 assert(test_param.tag_owner); 480 481 mctp_binding_test_destroy(binding); 482 mctp_destroy(mctp); 483 } 484 485 static void mctp_core_test_rx_with_tag_multifragment() 486 { 487 struct mctp *mctp = NULL; 488 struct mctp_binding_test *binding = NULL; 489 struct test_params test_param; 490 static uint8_t test_payload[MCTP_BTU]; 491 uint8_t tag = get_tag(); 492 struct pktbuf pktbuf; 493 uint8_t flags_seq_tag; 494 495 memset(test_payload, 0, sizeof(test_payload)); 496 test_param.seen = false; 497 test_param.message_size = 0; 498 test_param.msg_tag = 0; 499 test_param.tag_owner = false; 500 501 mctp_test_stack_init(&mctp, &binding, TEST_DEST_EID); 502 mctp_set_rx_all(mctp, rx_message, &test_param); 503 memset(&pktbuf, 0, sizeof(pktbuf)); 504 pktbuf.hdr.dest = TEST_DEST_EID; 505 pktbuf.hdr.src = TEST_SRC_EID; 506 507 /* Set tag and tag owner fields for a 3 fragment packet */ 508 flags_seq_tag = MCTP_HDR_FLAG_SOM | 509 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | 510 (1 << MCTP_HDR_TO_SHIFT) | tag; 511 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 512 &pktbuf); 513 514 flags_seq_tag = (get_sequence() << MCTP_HDR_SEQ_SHIFT) | 515 (1 << MCTP_HDR_TO_SHIFT) | tag; 516 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 517 &pktbuf); 518 519 flags_seq_tag = MCTP_HDR_FLAG_EOM | 520 (get_sequence() << MCTP_HDR_SEQ_SHIFT) | 521 (1 << MCTP_HDR_TO_SHIFT) | tag; 522 receive_one_fragment(binding, test_payload, MCTP_BTU, flags_seq_tag, 523 &pktbuf); 524 525 assert(test_param.seen); 526 assert(test_param.message_size == (3 * MCTP_BTU)); 527 assert(test_param.msg_tag == tag); 528 assert(test_param.tag_owner); 529 530 mctp_binding_test_destroy(binding); 531 mctp_destroy(mctp); 532 } 533 534 /* clang-format off */ 535 #define TEST_CASE(test) { #test, test } 536 static const struct { 537 const char *name; 538 void (*test)(void); 539 } mctp_core_tests[] = { 540 TEST_CASE(mctp_core_test_simple_rx), 541 TEST_CASE(mctp_core_test_receive_equal_length_fragments), 542 TEST_CASE(mctp_core_test_receive_unexpected_smaller_middle_fragment), 543 TEST_CASE(mctp_core_test_receive_unexpected_bigger_middle_fragment), 544 TEST_CASE(mctp_core_test_receive_smaller_end_fragment), 545 TEST_CASE(mctp_core_test_receive_bigger_end_fragment), 546 TEST_CASE(mctp_core_test_drop_large_fragments), 547 TEST_CASE(mctp_core_test_exhaust_context_buffers), 548 TEST_CASE(mctp_core_test_rx_with_tag), 549 TEST_CASE(mctp_core_test_rx_with_tag_multifragment), 550 }; 551 /* clang-format on */ 552 553 #ifndef BUILD_ASSERT 554 #define BUILD_ASSERT(x) \ 555 do { \ 556 (void)sizeof(char[0 - (!(x))]); \ 557 } while (0) 558 #endif 559 560 int main(void) 561 { 562 uint8_t i; 563 564 mctp_set_log_stdio(MCTP_LOG_DEBUG); 565 566 BUILD_ASSERT(ARRAY_SIZE(mctp_core_tests) < SIZE_MAX); 567 for (i = 0; i < ARRAY_SIZE(mctp_core_tests); i++) { 568 mctp_prlog(MCTP_LOG_DEBUG, "begin: %s", 569 mctp_core_tests[i].name); 570 mctp_core_tests[i].test(); 571 mctp_prlog(MCTP_LOG_DEBUG, "end: %s\n", 572 mctp_core_tests[i].name); 573 } 574 575 return 0; 576 } 577