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