1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2020 Marvell International Ltd. 3 */ 4 #include <assert.h> 5 #include <inttypes.h> 6 #include <signal.h> 7 #include <stdio.h> 8 #include <string.h> 9 #include <unistd.h> 10 11 #include <rte_errno.h> 12 #include <rte_graph.h> 13 #include <rte_graph_worker.h> 14 #include <rte_mbuf.h> 15 16 #include "test.h" 17 18 static uint16_t test_node_worker_source(struct rte_graph *graph, 19 struct rte_node *node, void **objs, 20 uint16_t nb_objs); 21 22 static uint16_t test_node0_worker(struct rte_graph *graph, 23 struct rte_node *node, void **objs, 24 uint16_t nb_objs); 25 26 static uint16_t test_node1_worker(struct rte_graph *graph, 27 struct rte_node *node, void **objs, 28 uint16_t nb_objs); 29 30 static uint16_t test_node2_worker(struct rte_graph *graph, 31 struct rte_node *node, void **objs, 32 uint16_t nb_objs); 33 34 static uint16_t test_node3_worker(struct rte_graph *graph, 35 struct rte_node *node, void **objs, 36 uint16_t nb_objs); 37 38 #define MBUFF_SIZE 512 39 #define MAX_NODES 4 40 41 static struct rte_mbuf mbuf[MAX_NODES + 1][MBUFF_SIZE]; 42 static void *mbuf_p[MAX_NODES + 1][MBUFF_SIZE]; 43 static rte_graph_t graph_id; 44 static uint64_t obj_stats[MAX_NODES + 1]; 45 static uint64_t fn_calls[MAX_NODES + 1]; 46 47 const char *node_patterns[] = { 48 "test_node_source1", "test_node00", 49 "test_node00-test_node11", "test_node00-test_node22", 50 "test_node00-test_node33", 51 }; 52 53 const char *node_names[] = { 54 "test_node00", 55 "test_node00-test_node11", 56 "test_node00-test_node22", 57 "test_node00-test_node33", 58 }; 59 60 struct test_node_register { 61 char name[RTE_NODE_NAMESIZE]; 62 rte_node_process_t process; 63 uint16_t nb_edges; 64 const char *next_nodes[MAX_NODES]; 65 }; 66 67 typedef struct { 68 uint32_t idx; 69 struct test_node_register node; 70 } test_node_t; 71 72 typedef struct { 73 test_node_t test_node[MAX_NODES]; 74 } test_main_t; 75 76 static test_main_t test_main = { 77 .test_node = { 78 { 79 .node = { 80 .name = "test_node00", 81 .process = test_node0_worker, 82 .nb_edges = 2, 83 .next_nodes = {"test_node00-" 84 "test_node11", 85 "test_node00-" 86 "test_node22"}, 87 }, 88 }, 89 { 90 .node = { 91 .name = "test_node11", 92 .process = test_node1_worker, 93 .nb_edges = 1, 94 .next_nodes = {"test_node00-" 95 "test_node22"}, 96 }, 97 }, 98 { 99 .node = { 100 .name = "test_node22", 101 .process = test_node2_worker, 102 .nb_edges = 1, 103 .next_nodes = {"test_node00-" 104 "test_node33"}, 105 }, 106 }, 107 { 108 .node = { 109 .name = "test_node33", 110 .process = test_node3_worker, 111 .nb_edges = 1, 112 .next_nodes = {"test_node00"}, 113 }, 114 }, 115 }, 116 }; 117 118 static int 119 node_init(const struct rte_graph *graph, struct rte_node *node) 120 { 121 RTE_SET_USED(graph); 122 *(uint32_t *)node->ctx = node->id; 123 124 return 0; 125 } 126 127 static struct rte_node_register test_node_source = { 128 .name = "test_node_source1", 129 .process = test_node_worker_source, 130 .flags = RTE_NODE_SOURCE_F, 131 .nb_edges = 2, 132 .init = node_init, 133 .next_nodes = {"test_node00", "test_node00-test_node11"}, 134 }; 135 RTE_NODE_REGISTER(test_node_source); 136 137 static struct rte_node_register test_node0 = { 138 .name = "test_node00", 139 .process = test_node0_worker, 140 .init = node_init, 141 }; 142 RTE_NODE_REGISTER(test_node0); 143 144 uint16_t 145 test_node_worker_source(struct rte_graph *graph, struct rte_node *node, 146 void **objs, uint16_t nb_objs) 147 { 148 uint32_t obj_node0 = rand() % 100, obj_node1; 149 test_main_t *tm = &test_main; 150 struct rte_mbuf *data; 151 void **next_stream; 152 rte_node_t next; 153 uint32_t i; 154 155 RTE_SET_USED(objs); 156 nb_objs = RTE_GRAPH_BURST_SIZE; 157 158 /* Prepare stream for next node 0 */ 159 obj_node0 = nb_objs * obj_node0 * 0.01; 160 next = 0; 161 next_stream = rte_node_next_stream_get(graph, node, next, obj_node0); 162 for (i = 0; i < obj_node0; i++) { 163 data = &mbuf[0][i]; 164 data->udata64 = ((uint64_t)tm->test_node[0].idx << 32) | i; 165 if ((i + 1) == obj_node0) 166 data->udata64 |= (1 << 16); 167 next_stream[i] = &mbuf[0][i]; 168 } 169 rte_node_next_stream_put(graph, node, next, obj_node0); 170 171 /* Prepare stream for next node 1 */ 172 obj_node1 = nb_objs - obj_node0; 173 next = 1; 174 next_stream = rte_node_next_stream_get(graph, node, next, obj_node1); 175 for (i = 0; i < obj_node1; i++) { 176 data = &mbuf[0][obj_node0 + i]; 177 data->udata64 = ((uint64_t)tm->test_node[1].idx << 32) | i; 178 if ((i + 1) == obj_node1) 179 data->udata64 |= (1 << 16); 180 next_stream[i] = &mbuf[0][obj_node0 + i]; 181 } 182 183 rte_node_next_stream_put(graph, node, next, obj_node1); 184 obj_stats[0] += nb_objs; 185 fn_calls[0] += 1; 186 return nb_objs; 187 } 188 189 uint16_t 190 test_node0_worker(struct rte_graph *graph, struct rte_node *node, void **objs, 191 uint16_t nb_objs) 192 { 193 test_main_t *tm = &test_main; 194 195 if (*(uint32_t *)node->ctx == test_node0.id) { 196 uint32_t obj_node0 = rand() % 100, obj_node1; 197 struct rte_mbuf *data; 198 uint8_t second_pass = 0; 199 uint32_t count = 0; 200 uint32_t i; 201 202 obj_stats[1] += nb_objs; 203 fn_calls[1] += 1; 204 205 for (i = 0; i < nb_objs; i++) { 206 data = (struct rte_mbuf *)objs[i]; 207 if ((data->udata64 >> 32) != tm->test_node[0].idx) { 208 printf("Data idx miss match at node 0, expected" 209 " = %u got = %u\n", 210 tm->test_node[0].idx, 211 (uint32_t)(data->udata64 >> 32)); 212 goto end; 213 } 214 215 if ((data->udata64 & 0xffff) != (i - count)) { 216 printf("Expected buff count miss match at " 217 "node 0\n"); 218 goto end; 219 } 220 221 if (data->udata64 & (0x1 << 16)) 222 count = i + 1; 223 if (data->udata64 & (0x1 << 17)) 224 second_pass = 1; 225 } 226 227 if (count != i) { 228 printf("Count mismatch at node 0\n"); 229 goto end; 230 } 231 232 obj_node0 = nb_objs * obj_node0 * 0.01; 233 for (i = 0; i < obj_node0; i++) { 234 data = &mbuf[1][i]; 235 data->udata64 = 236 ((uint64_t)tm->test_node[1].idx << 32) | i; 237 if ((i + 1) == obj_node0) 238 data->udata64 |= (1 << 16); 239 if (second_pass) 240 data->udata64 |= (1 << 17); 241 } 242 rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[1][0], 243 obj_node0); 244 245 obj_node1 = nb_objs - obj_node0; 246 for (i = 0; i < obj_node1; i++) { 247 data = &mbuf[1][obj_node0 + i]; 248 data->udata64 = 249 ((uint64_t)tm->test_node[2].idx << 32) | i; 250 if ((i + 1) == obj_node1) 251 data->udata64 |= (1 << 16); 252 if (second_pass) 253 data->udata64 |= (1 << 17); 254 } 255 rte_node_enqueue(graph, node, 1, (void **)&mbuf_p[1][obj_node0], 256 obj_node1); 257 258 } else if (*(uint32_t *)node->ctx == tm->test_node[1].idx) { 259 test_node1_worker(graph, node, objs, nb_objs); 260 } else if (*(uint32_t *)node->ctx == tm->test_node[2].idx) { 261 test_node2_worker(graph, node, objs, nb_objs); 262 } else if (*(uint32_t *)node->ctx == tm->test_node[3].idx) { 263 test_node3_worker(graph, node, objs, nb_objs); 264 } else { 265 printf("Unexpected node context\n"); 266 } 267 268 end: 269 return nb_objs; 270 } 271 272 uint16_t 273 test_node1_worker(struct rte_graph *graph, struct rte_node *node, void **objs, 274 uint16_t nb_objs) 275 { 276 test_main_t *tm = &test_main; 277 uint8_t second_pass = 0; 278 uint32_t obj_node0 = 0; 279 struct rte_mbuf *data; 280 uint32_t count = 0; 281 uint32_t i; 282 283 obj_stats[2] += nb_objs; 284 fn_calls[2] += 1; 285 for (i = 0; i < nb_objs; i++) { 286 data = (struct rte_mbuf *)objs[i]; 287 if ((data->udata64 >> 32) != tm->test_node[1].idx) { 288 printf("Data idx miss match at node 1, expected = %u" 289 " got = %u\n", 290 tm->test_node[1].idx, 291 (uint32_t)(data->udata64 >> 32)); 292 goto end; 293 } 294 295 if ((data->udata64 & 0xffff) != (i - count)) { 296 printf("Expected buff count miss match at node 1\n"); 297 goto end; 298 } 299 300 if (data->udata64 & (0x1 << 16)) 301 count = i + 1; 302 if (data->udata64 & (0x1 << 17)) 303 second_pass = 1; 304 } 305 306 if (count != i) { 307 printf("Count mismatch at node 1\n"); 308 goto end; 309 } 310 311 obj_node0 = nb_objs; 312 for (i = 0; i < obj_node0; i++) { 313 data = &mbuf[2][i]; 314 data->udata64 = ((uint64_t)tm->test_node[2].idx << 32) | i; 315 if ((i + 1) == obj_node0) 316 data->udata64 |= (1 << 16); 317 if (second_pass) 318 data->udata64 |= (1 << 17); 319 } 320 rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[2][0], obj_node0); 321 322 end: 323 return nb_objs; 324 } 325 326 uint16_t 327 test_node2_worker(struct rte_graph *graph, struct rte_node *node, void **objs, 328 uint16_t nb_objs) 329 { 330 test_main_t *tm = &test_main; 331 uint8_t second_pass = 0; 332 struct rte_mbuf *data; 333 uint32_t count = 0; 334 uint32_t obj_node0; 335 uint32_t i; 336 337 obj_stats[3] += nb_objs; 338 fn_calls[3] += 1; 339 for (i = 0; i < nb_objs; i++) { 340 data = (struct rte_mbuf *)objs[i]; 341 if ((data->udata64 >> 32) != tm->test_node[2].idx) { 342 printf("Data idx miss match at node 2, expected = %u" 343 " got = %u\n", 344 tm->test_node[2].idx, 345 (uint32_t)(data->udata64 >> 32)); 346 goto end; 347 } 348 349 if ((data->udata64 & 0xffff) != (i - count)) { 350 printf("Expected buff count miss match at node 2\n"); 351 goto end; 352 } 353 354 if (data->udata64 & (0x1 << 16)) 355 count = i + 1; 356 if (data->udata64 & (0x1 << 17)) 357 second_pass = 1; 358 } 359 360 if (count != i) { 361 printf("Count mismatch at node 2\n"); 362 goto end; 363 } 364 365 if (!second_pass) { 366 obj_node0 = nb_objs; 367 for (i = 0; i < obj_node0; i++) { 368 data = &mbuf[3][i]; 369 data->udata64 = 370 ((uint64_t)tm->test_node[3].idx << 32) | i; 371 if ((i + 1) == obj_node0) 372 data->udata64 |= (1 << 16); 373 } 374 rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[3][0], 375 obj_node0); 376 } 377 378 end: 379 return nb_objs; 380 } 381 382 uint16_t 383 test_node3_worker(struct rte_graph *graph, struct rte_node *node, void **objs, 384 uint16_t nb_objs) 385 { 386 test_main_t *tm = &test_main; 387 uint8_t second_pass = 0; 388 struct rte_mbuf *data; 389 uint32_t count = 0; 390 uint32_t obj_node0; 391 uint32_t i; 392 393 obj_stats[4] += nb_objs; 394 fn_calls[4] += 1; 395 for (i = 0; i < nb_objs; i++) { 396 data = (struct rte_mbuf *)objs[i]; 397 if ((data->udata64 >> 32) != tm->test_node[3].idx) { 398 printf("Data idx miss match at node 3, expected = %u" 399 " got = %u\n", 400 tm->test_node[3].idx, 401 (uint32_t)(data->udata64 >> 32)); 402 goto end; 403 } 404 405 if ((data->udata64 & 0xffff) != (i - count)) { 406 printf("Expected buff count miss match at node 3\n"); 407 goto end; 408 } 409 410 if (data->udata64 & (0x1 << 16)) 411 count = i + 1; 412 if (data->udata64 & (0x1 << 17)) 413 second_pass = 1; 414 } 415 416 if (count != i) { 417 printf("Count mismatch at node 3\n"); 418 goto end; 419 } 420 421 if (second_pass) { 422 printf("Unexpected buffers are at node 3\n"); 423 goto end; 424 } else { 425 obj_node0 = nb_objs * 2; 426 for (i = 0; i < obj_node0; i++) { 427 data = &mbuf[4][i]; 428 data->udata64 = 429 ((uint64_t)tm->test_node[0].idx << 32) | i; 430 data->udata64 |= (1 << 17); 431 if ((i + 1) == obj_node0) 432 data->udata64 |= (1 << 16); 433 } 434 rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[4][0], 435 obj_node0); 436 } 437 438 end: 439 return nb_objs; 440 } 441 442 static int 443 test_lookup_functions(void) 444 { 445 test_main_t *tm = &test_main; 446 int i; 447 448 /* Verify the name with ID */ 449 for (i = 1; i < MAX_NODES; i++) { 450 char *name = rte_node_id_to_name(tm->test_node[i].idx); 451 if (strcmp(name, node_names[i]) != 0) { 452 printf("Test node name verify by ID = %d failed " 453 "Expected = %s, got %s\n", 454 i, node_names[i], name); 455 return -1; 456 } 457 } 458 459 /* Verify by name */ 460 for (i = 1; i < MAX_NODES; i++) { 461 uint32_t idx = rte_node_from_name(node_names[i]); 462 if (idx != tm->test_node[i].idx) { 463 printf("Test node ID verify by name = %s failed " 464 "Expected = %d, got %d\n", 465 node_names[i], tm->test_node[i].idx, idx); 466 return -1; 467 } 468 } 469 470 /* Verify edge count */ 471 for (i = 1; i < MAX_NODES; i++) { 472 uint32_t count = rte_node_edge_count(tm->test_node[i].idx); 473 if (count != tm->test_node[i].node.nb_edges) { 474 printf("Test number of edges for node = %s failed Expected = %d, got = %d\n", 475 tm->test_node[i].node.name, 476 tm->test_node[i].node.nb_edges, count); 477 return -1; 478 } 479 } 480 481 /* Verify edge names */ 482 for (i = 1; i < MAX_NODES; i++) { 483 uint32_t j, count; 484 char **next_edges; 485 486 count = rte_node_edge_get(tm->test_node[i].idx, NULL); 487 if (count != tm->test_node[i].node.nb_edges * sizeof(char *)) { 488 printf("Test number of edge count for node = %s failed Expected = %d, got = %d\n", 489 tm->test_node[i].node.name, 490 tm->test_node[i].node.nb_edges, count); 491 return -1; 492 } 493 next_edges = malloc(count); 494 count = rte_node_edge_get(tm->test_node[i].idx, next_edges); 495 if (count != tm->test_node[i].node.nb_edges) { 496 printf("Test number of edges for node = %s failed Expected = %d, got %d\n", 497 tm->test_node[i].node.name, 498 tm->test_node[i].node.nb_edges, count); 499 return -1; 500 } 501 502 for (j = 0; j < count; j++) { 503 if (strcmp(next_edges[j], 504 tm->test_node[i].node.next_nodes[j]) != 0) { 505 printf("Edge name miss match, expected = %s got = %s\n", 506 tm->test_node[i].node.next_nodes[j], 507 next_edges[j]); 508 return -1; 509 } 510 } 511 free(next_edges); 512 } 513 514 return 0; 515 } 516 517 static int 518 test_node_clone(void) 519 { 520 test_main_t *tm = &test_main; 521 uint32_t node_id, dummy_id; 522 int i; 523 524 node_id = rte_node_from_name("test_node00"); 525 tm->test_node[0].idx = node_id; 526 527 /* Clone with same name, should fail */ 528 dummy_id = rte_node_clone(node_id, "test_node00"); 529 if (!rte_node_is_invalid(dummy_id)) { 530 printf("Got valid id when clone with same name, Expecting fail\n"); 531 return -1; 532 } 533 534 for (i = 1; i < MAX_NODES; i++) { 535 tm->test_node[i].idx = 536 rte_node_clone(node_id, tm->test_node[i].node.name); 537 if (rte_node_is_invalid(tm->test_node[i].idx)) { 538 printf("Got invalid node id\n"); 539 return -1; 540 } 541 } 542 543 /* Clone from cloned node should fail */ 544 dummy_id = rte_node_clone(tm->test_node[1].idx, "dummy_node"); 545 if (!rte_node_is_invalid(dummy_id)) { 546 printf("Got valid node id when cloning from cloned node, expected fail\n"); 547 return -1; 548 } 549 550 return 0; 551 } 552 553 static int 554 test_update_edges(void) 555 { 556 test_main_t *tm = &test_main; 557 uint32_t node_id; 558 uint16_t count; 559 int i; 560 561 node_id = rte_node_from_name("test_node00"); 562 count = rte_node_edge_update(node_id, 0, 563 tm->test_node[0].node.next_nodes, 564 tm->test_node[0].node.nb_edges); 565 if (count != tm->test_node[0].node.nb_edges) { 566 printf("Update edges failed expected: %d got = %d\n", 567 tm->test_node[0].node.nb_edges, count); 568 return -1; 569 } 570 571 for (i = 1; i < MAX_NODES; i++) { 572 count = rte_node_edge_update(tm->test_node[i].idx, 0, 573 tm->test_node[i].node.next_nodes, 574 tm->test_node[i].node.nb_edges); 575 if (count != tm->test_node[i].node.nb_edges) { 576 printf("Update edges failed expected: %d got = %d\n", 577 tm->test_node[i].node.nb_edges, count); 578 return -1; 579 } 580 581 count = rte_node_edge_shrink(tm->test_node[i].idx, 582 tm->test_node[i].node.nb_edges); 583 if (count != tm->test_node[i].node.nb_edges) { 584 printf("Shrink edges failed\n"); 585 return -1; 586 } 587 } 588 589 return 0; 590 } 591 592 static int 593 test_create_graph(void) 594 { 595 static const char *node_patterns_dummy[] = { 596 "test_node_source1", "test_node00", 597 "test_node00-test_node11", "test_node00-test_node22", 598 "test_node00-test_node33", "test_node00-dummy_node", 599 }; 600 struct rte_graph_param gconf = { 601 .socket_id = SOCKET_ID_ANY, 602 .nb_node_patterns = 6, 603 .node_patterns = node_patterns_dummy, 604 }; 605 uint32_t dummy_node_id; 606 uint32_t node_id; 607 608 node_id = rte_node_from_name("test_node00"); 609 dummy_node_id = rte_node_clone(node_id, "dummy_node"); 610 if (rte_node_is_invalid(dummy_node_id)) { 611 printf("Got invalid node id\n"); 612 return -1; 613 } 614 615 graph_id = rte_graph_create("worker0", &gconf); 616 if (graph_id != RTE_GRAPH_ID_INVALID) { 617 printf("Graph creation success with isolated node, expected graph creation fail\n"); 618 return -1; 619 } 620 621 gconf.nb_node_patterns = 5; 622 gconf.node_patterns = node_patterns; 623 graph_id = rte_graph_create("worker0", &gconf); 624 if (graph_id == RTE_GRAPH_ID_INVALID) { 625 printf("Graph creation failed with error = %d\n", rte_errno); 626 return -1; 627 } 628 return 0; 629 } 630 631 static int 632 test_graph_walk(void) 633 { 634 struct rte_graph *graph = rte_graph_lookup("worker0"); 635 int i; 636 637 if (!graph) { 638 printf("Graph lookup failed\n"); 639 return -1; 640 } 641 642 for (i = 0; i < 5; i++) 643 rte_graph_walk(graph); 644 return 0; 645 } 646 647 static int 648 test_graph_lookup_functions(void) 649 { 650 test_main_t *tm = &test_main; 651 struct rte_node *node; 652 int i; 653 654 for (i = 0; i < MAX_NODES; i++) { 655 node = rte_graph_node_get(graph_id, tm->test_node[i].idx); 656 if (!node) { 657 printf("rte_graph_node_get, failed for node = %d\n", 658 tm->test_node[i].idx); 659 return -1; 660 } 661 662 if (tm->test_node[i].idx != node->id) { 663 printf("Node id didn't match, expected = %d got = %d\n", 664 tm->test_node[i].idx, node->id); 665 return 0; 666 } 667 668 if (strncmp(node->name, node_names[i], RTE_NODE_NAMESIZE)) { 669 printf("Node name didn't match, expected = %s got %s\n", 670 node_names[i], node->name); 671 return -1; 672 } 673 } 674 675 for (i = 0; i < MAX_NODES; i++) { 676 node = rte_graph_node_get_by_name("worker0", node_names[i]); 677 if (!node) { 678 printf("rte_graph_node_get, failed for node = %d\n", 679 tm->test_node[i].idx); 680 return -1; 681 } 682 683 if (tm->test_node[i].idx != node->id) { 684 printf("Node id didn't match, expected = %d got = %d\n", 685 tm->test_node[i].idx, node->id); 686 return 0; 687 } 688 689 if (strncmp(node->name, node_names[i], RTE_NODE_NAMESIZE)) { 690 printf("Node name didn't match, expected = %s got %s\n", 691 node_names[i], node->name); 692 return -1; 693 } 694 } 695 696 return 0; 697 } 698 699 static int 700 graph_cluster_stats_cb_t(bool is_first, bool is_last, void *cookie, 701 const struct rte_graph_cluster_node_stats *st) 702 { 703 int i; 704 705 RTE_SET_USED(is_first); 706 RTE_SET_USED(is_last); 707 RTE_SET_USED(cookie); 708 709 for (i = 0; i < MAX_NODES + 1; i++) { 710 rte_node_t id = rte_node_from_name(node_patterns[i]); 711 if (id == st->id) { 712 if (obj_stats[i] != st->objs) { 713 printf("Obj count miss match for node = %s expected = %"PRId64", got=%"PRId64"\n", 714 node_patterns[i], obj_stats[i], 715 st->objs); 716 return -1; 717 } 718 719 if (fn_calls[i] != st->calls) { 720 printf("Func call miss match for node = %s expected = %"PRId64", got = %"PRId64"\n", 721 node_patterns[i], fn_calls[i], 722 st->calls); 723 return -1; 724 } 725 } 726 } 727 return 0; 728 } 729 730 static int 731 test_print_stats(void) 732 { 733 struct rte_graph_cluster_stats_param s_param; 734 struct rte_graph_cluster_stats *stats; 735 const char *pattern = "worker0"; 736 737 if (!rte_graph_has_stats_feature()) 738 return 0; 739 740 /* Prepare stats object */ 741 memset(&s_param, 0, sizeof(s_param)); 742 s_param.f = stdout; 743 s_param.socket_id = SOCKET_ID_ANY; 744 s_param.graph_patterns = &pattern; 745 s_param.nb_graph_patterns = 1; 746 s_param.fn = graph_cluster_stats_cb_t; 747 748 stats = rte_graph_cluster_stats_create(&s_param); 749 if (stats == NULL) { 750 printf("Unable to get stats\n"); 751 return -1; 752 } 753 /* Clear screen and move to top left */ 754 rte_graph_cluster_stats_get(stats, 0); 755 rte_graph_cluster_stats_destroy(stats); 756 757 return 0; 758 } 759 760 static int 761 graph_setup(void) 762 { 763 int i, j; 764 765 for (i = 0; i <= MAX_NODES; i++) { 766 for (j = 0; j < MBUFF_SIZE; j++) 767 mbuf_p[i][j] = &mbuf[i][j]; 768 } 769 if (test_node_clone()) { 770 printf("test_node_clone: fail\n"); 771 return -1; 772 } 773 printf("test_node_clone: pass\n"); 774 775 return 0; 776 } 777 778 static void 779 graph_teardown(void) 780 { 781 int id; 782 783 id = rte_graph_destroy(rte_graph_from_name("worker0")); 784 if (id) 785 printf("Graph Destroy failed\n"); 786 } 787 788 static struct unit_test_suite graph_testsuite = { 789 .suite_name = "Graph library test suite", 790 .setup = graph_setup, 791 .teardown = graph_teardown, 792 .unit_test_cases = { 793 TEST_CASE(test_update_edges), 794 TEST_CASE(test_lookup_functions), 795 TEST_CASE(test_create_graph), 796 TEST_CASE(test_graph_lookup_functions), 797 TEST_CASE(test_graph_walk), 798 TEST_CASE(test_print_stats), 799 TEST_CASES_END(), /**< NULL terminate unit test array */ 800 }, 801 }; 802 803 static int 804 graph_autotest_fn(void) 805 { 806 return unit_test_suite_runner(&graph_testsuite); 807 } 808 809 REGISTER_TEST_COMMAND(graph_autotest, graph_autotest_fn); 810 811 static int 812 test_node_list_dump(void) 813 { 814 rte_node_list_dump(stdout); 815 816 return TEST_SUCCESS; 817 } 818 REGISTER_TEST_COMMAND(node_list_dump, test_node_list_dump); 819