c5a56c5897
Fix memory leaks reported by Coverity.
Fixes: 6b89650418
("test/graph: add functional tests")
Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
822 lines
19 KiB
C
822 lines
19 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright(C) 2020 Marvell International Ltd.
|
|
*/
|
|
#include <assert.h>
|
|
#include <inttypes.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <rte_errno.h>
|
|
#include <rte_graph.h>
|
|
#include <rte_graph_worker.h>
|
|
#include <rte_mbuf.h>
|
|
#include <rte_random.h>
|
|
|
|
#include "test.h"
|
|
|
|
static uint16_t test_node_worker_source(struct rte_graph *graph,
|
|
struct rte_node *node, void **objs,
|
|
uint16_t nb_objs);
|
|
|
|
static uint16_t test_node0_worker(struct rte_graph *graph,
|
|
struct rte_node *node, void **objs,
|
|
uint16_t nb_objs);
|
|
|
|
static uint16_t test_node1_worker(struct rte_graph *graph,
|
|
struct rte_node *node, void **objs,
|
|
uint16_t nb_objs);
|
|
|
|
static uint16_t test_node2_worker(struct rte_graph *graph,
|
|
struct rte_node *node, void **objs,
|
|
uint16_t nb_objs);
|
|
|
|
static uint16_t test_node3_worker(struct rte_graph *graph,
|
|
struct rte_node *node, void **objs,
|
|
uint16_t nb_objs);
|
|
|
|
#define MBUFF_SIZE 512
|
|
#define MAX_NODES 4
|
|
|
|
static struct rte_mbuf mbuf[MAX_NODES + 1][MBUFF_SIZE];
|
|
static void *mbuf_p[MAX_NODES + 1][MBUFF_SIZE];
|
|
static rte_graph_t graph_id;
|
|
static uint64_t obj_stats[MAX_NODES + 1];
|
|
static uint64_t fn_calls[MAX_NODES + 1];
|
|
|
|
const char *node_patterns[] = {
|
|
"test_node_source1", "test_node00",
|
|
"test_node00-test_node11", "test_node00-test_node22",
|
|
"test_node00-test_node33",
|
|
};
|
|
|
|
const char *node_names[] = {
|
|
"test_node00",
|
|
"test_node00-test_node11",
|
|
"test_node00-test_node22",
|
|
"test_node00-test_node33",
|
|
};
|
|
|
|
struct test_node_register {
|
|
char name[RTE_NODE_NAMESIZE];
|
|
rte_node_process_t process;
|
|
uint16_t nb_edges;
|
|
const char *next_nodes[MAX_NODES];
|
|
};
|
|
|
|
typedef struct {
|
|
uint32_t idx;
|
|
struct test_node_register node;
|
|
} test_node_t;
|
|
|
|
typedef struct {
|
|
test_node_t test_node[MAX_NODES];
|
|
} test_main_t;
|
|
|
|
static test_main_t test_main = {
|
|
.test_node = {
|
|
{
|
|
.node = {
|
|
.name = "test_node00",
|
|
.process = test_node0_worker,
|
|
.nb_edges = 2,
|
|
.next_nodes = {"test_node00-"
|
|
"test_node11",
|
|
"test_node00-"
|
|
"test_node22"},
|
|
},
|
|
},
|
|
{
|
|
.node = {
|
|
.name = "test_node11",
|
|
.process = test_node1_worker,
|
|
.nb_edges = 1,
|
|
.next_nodes = {"test_node00-"
|
|
"test_node22"},
|
|
},
|
|
},
|
|
{
|
|
.node = {
|
|
.name = "test_node22",
|
|
.process = test_node2_worker,
|
|
.nb_edges = 1,
|
|
.next_nodes = {"test_node00-"
|
|
"test_node33"},
|
|
},
|
|
},
|
|
{
|
|
.node = {
|
|
.name = "test_node33",
|
|
.process = test_node3_worker,
|
|
.nb_edges = 1,
|
|
.next_nodes = {"test_node00"},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
static int
|
|
node_init(const struct rte_graph *graph, struct rte_node *node)
|
|
{
|
|
RTE_SET_USED(graph);
|
|
*(uint32_t *)node->ctx = node->id;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct rte_node_register test_node_source = {
|
|
.name = "test_node_source1",
|
|
.process = test_node_worker_source,
|
|
.flags = RTE_NODE_SOURCE_F,
|
|
.nb_edges = 2,
|
|
.init = node_init,
|
|
.next_nodes = {"test_node00", "test_node00-test_node11"},
|
|
};
|
|
RTE_NODE_REGISTER(test_node_source);
|
|
|
|
static struct rte_node_register test_node0 = {
|
|
.name = "test_node00",
|
|
.process = test_node0_worker,
|
|
.init = node_init,
|
|
};
|
|
RTE_NODE_REGISTER(test_node0);
|
|
|
|
uint16_t
|
|
test_node_worker_source(struct rte_graph *graph, struct rte_node *node,
|
|
void **objs, uint16_t nb_objs)
|
|
{
|
|
uint32_t obj_node0 = rte_rand() % 100, obj_node1;
|
|
test_main_t *tm = &test_main;
|
|
struct rte_mbuf *data;
|
|
void **next_stream;
|
|
rte_node_t next;
|
|
uint32_t i;
|
|
|
|
RTE_SET_USED(objs);
|
|
nb_objs = RTE_GRAPH_BURST_SIZE;
|
|
|
|
/* Prepare stream for next node 0 */
|
|
obj_node0 = nb_objs * obj_node0 * 0.01;
|
|
next = 0;
|
|
next_stream = rte_node_next_stream_get(graph, node, next, obj_node0);
|
|
for (i = 0; i < obj_node0; i++) {
|
|
data = &mbuf[0][i];
|
|
data->udata64 = ((uint64_t)tm->test_node[0].idx << 32) | i;
|
|
if ((i + 1) == obj_node0)
|
|
data->udata64 |= (1 << 16);
|
|
next_stream[i] = &mbuf[0][i];
|
|
}
|
|
rte_node_next_stream_put(graph, node, next, obj_node0);
|
|
|
|
/* Prepare stream for next node 1 */
|
|
obj_node1 = nb_objs - obj_node0;
|
|
next = 1;
|
|
next_stream = rte_node_next_stream_get(graph, node, next, obj_node1);
|
|
for (i = 0; i < obj_node1; i++) {
|
|
data = &mbuf[0][obj_node0 + i];
|
|
data->udata64 = ((uint64_t)tm->test_node[1].idx << 32) | i;
|
|
if ((i + 1) == obj_node1)
|
|
data->udata64 |= (1 << 16);
|
|
next_stream[i] = &mbuf[0][obj_node0 + i];
|
|
}
|
|
|
|
rte_node_next_stream_put(graph, node, next, obj_node1);
|
|
obj_stats[0] += nb_objs;
|
|
fn_calls[0] += 1;
|
|
return nb_objs;
|
|
}
|
|
|
|
uint16_t
|
|
test_node0_worker(struct rte_graph *graph, struct rte_node *node, void **objs,
|
|
uint16_t nb_objs)
|
|
{
|
|
test_main_t *tm = &test_main;
|
|
|
|
if (*(uint32_t *)node->ctx == test_node0.id) {
|
|
uint32_t obj_node0 = rte_rand() % 100, obj_node1;
|
|
struct rte_mbuf *data;
|
|
uint8_t second_pass = 0;
|
|
uint32_t count = 0;
|
|
uint32_t i;
|
|
|
|
obj_stats[1] += nb_objs;
|
|
fn_calls[1] += 1;
|
|
|
|
for (i = 0; i < nb_objs; i++) {
|
|
data = (struct rte_mbuf *)objs[i];
|
|
if ((data->udata64 >> 32) != tm->test_node[0].idx) {
|
|
printf("Data idx miss match at node 0, expected"
|
|
" = %u got = %u\n",
|
|
tm->test_node[0].idx,
|
|
(uint32_t)(data->udata64 >> 32));
|
|
goto end;
|
|
}
|
|
|
|
if ((data->udata64 & 0xffff) != (i - count)) {
|
|
printf("Expected buff count miss match at "
|
|
"node 0\n");
|
|
goto end;
|
|
}
|
|
|
|
if (data->udata64 & (0x1 << 16))
|
|
count = i + 1;
|
|
if (data->udata64 & (0x1 << 17))
|
|
second_pass = 1;
|
|
}
|
|
|
|
if (count != i) {
|
|
printf("Count mismatch at node 0\n");
|
|
goto end;
|
|
}
|
|
|
|
obj_node0 = nb_objs * obj_node0 * 0.01;
|
|
for (i = 0; i < obj_node0; i++) {
|
|
data = &mbuf[1][i];
|
|
data->udata64 =
|
|
((uint64_t)tm->test_node[1].idx << 32) | i;
|
|
if ((i + 1) == obj_node0)
|
|
data->udata64 |= (1 << 16);
|
|
if (second_pass)
|
|
data->udata64 |= (1 << 17);
|
|
}
|
|
rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[1][0],
|
|
obj_node0);
|
|
|
|
obj_node1 = nb_objs - obj_node0;
|
|
for (i = 0; i < obj_node1; i++) {
|
|
data = &mbuf[1][obj_node0 + i];
|
|
data->udata64 =
|
|
((uint64_t)tm->test_node[2].idx << 32) | i;
|
|
if ((i + 1) == obj_node1)
|
|
data->udata64 |= (1 << 16);
|
|
if (second_pass)
|
|
data->udata64 |= (1 << 17);
|
|
}
|
|
rte_node_enqueue(graph, node, 1, (void **)&mbuf_p[1][obj_node0],
|
|
obj_node1);
|
|
|
|
} else if (*(uint32_t *)node->ctx == tm->test_node[1].idx) {
|
|
test_node1_worker(graph, node, objs, nb_objs);
|
|
} else if (*(uint32_t *)node->ctx == tm->test_node[2].idx) {
|
|
test_node2_worker(graph, node, objs, nb_objs);
|
|
} else if (*(uint32_t *)node->ctx == tm->test_node[3].idx) {
|
|
test_node3_worker(graph, node, objs, nb_objs);
|
|
} else {
|
|
printf("Unexpected node context\n");
|
|
}
|
|
|
|
end:
|
|
return nb_objs;
|
|
}
|
|
|
|
uint16_t
|
|
test_node1_worker(struct rte_graph *graph, struct rte_node *node, void **objs,
|
|
uint16_t nb_objs)
|
|
{
|
|
test_main_t *tm = &test_main;
|
|
uint8_t second_pass = 0;
|
|
uint32_t obj_node0 = 0;
|
|
struct rte_mbuf *data;
|
|
uint32_t count = 0;
|
|
uint32_t i;
|
|
|
|
obj_stats[2] += nb_objs;
|
|
fn_calls[2] += 1;
|
|
for (i = 0; i < nb_objs; i++) {
|
|
data = (struct rte_mbuf *)objs[i];
|
|
if ((data->udata64 >> 32) != tm->test_node[1].idx) {
|
|
printf("Data idx miss match at node 1, expected = %u"
|
|
" got = %u\n",
|
|
tm->test_node[1].idx,
|
|
(uint32_t)(data->udata64 >> 32));
|
|
goto end;
|
|
}
|
|
|
|
if ((data->udata64 & 0xffff) != (i - count)) {
|
|
printf("Expected buff count miss match at node 1\n");
|
|
goto end;
|
|
}
|
|
|
|
if (data->udata64 & (0x1 << 16))
|
|
count = i + 1;
|
|
if (data->udata64 & (0x1 << 17))
|
|
second_pass = 1;
|
|
}
|
|
|
|
if (count != i) {
|
|
printf("Count mismatch at node 1\n");
|
|
goto end;
|
|
}
|
|
|
|
obj_node0 = nb_objs;
|
|
for (i = 0; i < obj_node0; i++) {
|
|
data = &mbuf[2][i];
|
|
data->udata64 = ((uint64_t)tm->test_node[2].idx << 32) | i;
|
|
if ((i + 1) == obj_node0)
|
|
data->udata64 |= (1 << 16);
|
|
if (second_pass)
|
|
data->udata64 |= (1 << 17);
|
|
}
|
|
rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[2][0], obj_node0);
|
|
|
|
end:
|
|
return nb_objs;
|
|
}
|
|
|
|
uint16_t
|
|
test_node2_worker(struct rte_graph *graph, struct rte_node *node, void **objs,
|
|
uint16_t nb_objs)
|
|
{
|
|
test_main_t *tm = &test_main;
|
|
uint8_t second_pass = 0;
|
|
struct rte_mbuf *data;
|
|
uint32_t count = 0;
|
|
uint32_t obj_node0;
|
|
uint32_t i;
|
|
|
|
obj_stats[3] += nb_objs;
|
|
fn_calls[3] += 1;
|
|
for (i = 0; i < nb_objs; i++) {
|
|
data = (struct rte_mbuf *)objs[i];
|
|
if ((data->udata64 >> 32) != tm->test_node[2].idx) {
|
|
printf("Data idx miss match at node 2, expected = %u"
|
|
" got = %u\n",
|
|
tm->test_node[2].idx,
|
|
(uint32_t)(data->udata64 >> 32));
|
|
goto end;
|
|
}
|
|
|
|
if ((data->udata64 & 0xffff) != (i - count)) {
|
|
printf("Expected buff count miss match at node 2\n");
|
|
goto end;
|
|
}
|
|
|
|
if (data->udata64 & (0x1 << 16))
|
|
count = i + 1;
|
|
if (data->udata64 & (0x1 << 17))
|
|
second_pass = 1;
|
|
}
|
|
|
|
if (count != i) {
|
|
printf("Count mismatch at node 2\n");
|
|
goto end;
|
|
}
|
|
|
|
if (!second_pass) {
|
|
obj_node0 = nb_objs;
|
|
for (i = 0; i < obj_node0; i++) {
|
|
data = &mbuf[3][i];
|
|
data->udata64 =
|
|
((uint64_t)tm->test_node[3].idx << 32) | i;
|
|
if ((i + 1) == obj_node0)
|
|
data->udata64 |= (1 << 16);
|
|
}
|
|
rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[3][0],
|
|
obj_node0);
|
|
}
|
|
|
|
end:
|
|
return nb_objs;
|
|
}
|
|
|
|
uint16_t
|
|
test_node3_worker(struct rte_graph *graph, struct rte_node *node, void **objs,
|
|
uint16_t nb_objs)
|
|
{
|
|
test_main_t *tm = &test_main;
|
|
uint8_t second_pass = 0;
|
|
struct rte_mbuf *data;
|
|
uint32_t count = 0;
|
|
uint32_t obj_node0;
|
|
uint32_t i;
|
|
|
|
obj_stats[4] += nb_objs;
|
|
fn_calls[4] += 1;
|
|
for (i = 0; i < nb_objs; i++) {
|
|
data = (struct rte_mbuf *)objs[i];
|
|
if ((data->udata64 >> 32) != tm->test_node[3].idx) {
|
|
printf("Data idx miss match at node 3, expected = %u"
|
|
" got = %u\n",
|
|
tm->test_node[3].idx,
|
|
(uint32_t)(data->udata64 >> 32));
|
|
goto end;
|
|
}
|
|
|
|
if ((data->udata64 & 0xffff) != (i - count)) {
|
|
printf("Expected buff count miss match at node 3\n");
|
|
goto end;
|
|
}
|
|
|
|
if (data->udata64 & (0x1 << 16))
|
|
count = i + 1;
|
|
if (data->udata64 & (0x1 << 17))
|
|
second_pass = 1;
|
|
}
|
|
|
|
if (count != i) {
|
|
printf("Count mismatch at node 3\n");
|
|
goto end;
|
|
}
|
|
|
|
if (second_pass) {
|
|
printf("Unexpected buffers are at node 3\n");
|
|
goto end;
|
|
} else {
|
|
obj_node0 = nb_objs * 2;
|
|
for (i = 0; i < obj_node0; i++) {
|
|
data = &mbuf[4][i];
|
|
data->udata64 =
|
|
((uint64_t)tm->test_node[0].idx << 32) | i;
|
|
data->udata64 |= (1 << 17);
|
|
if ((i + 1) == obj_node0)
|
|
data->udata64 |= (1 << 16);
|
|
}
|
|
rte_node_enqueue(graph, node, 0, (void **)&mbuf_p[4][0],
|
|
obj_node0);
|
|
}
|
|
|
|
end:
|
|
return nb_objs;
|
|
}
|
|
|
|
static int
|
|
test_lookup_functions(void)
|
|
{
|
|
test_main_t *tm = &test_main;
|
|
int i;
|
|
|
|
/* Verify the name with ID */
|
|
for (i = 1; i < MAX_NODES; i++) {
|
|
char *name = rte_node_id_to_name(tm->test_node[i].idx);
|
|
if (strcmp(name, node_names[i]) != 0) {
|
|
printf("Test node name verify by ID = %d failed "
|
|
"Expected = %s, got %s\n",
|
|
i, node_names[i], name);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* Verify by name */
|
|
for (i = 1; i < MAX_NODES; i++) {
|
|
uint32_t idx = rte_node_from_name(node_names[i]);
|
|
if (idx != tm->test_node[i].idx) {
|
|
printf("Test node ID verify by name = %s failed "
|
|
"Expected = %d, got %d\n",
|
|
node_names[i], tm->test_node[i].idx, idx);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* Verify edge count */
|
|
for (i = 1; i < MAX_NODES; i++) {
|
|
uint32_t count = rte_node_edge_count(tm->test_node[i].idx);
|
|
if (count != tm->test_node[i].node.nb_edges) {
|
|
printf("Test number of edges for node = %s failed Expected = %d, got = %d\n",
|
|
tm->test_node[i].node.name,
|
|
tm->test_node[i].node.nb_edges, count);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* Verify edge names */
|
|
for (i = 1; i < MAX_NODES; i++) {
|
|
uint32_t j, count;
|
|
char **next_edges;
|
|
|
|
count = rte_node_edge_get(tm->test_node[i].idx, NULL);
|
|
if (count != tm->test_node[i].node.nb_edges * sizeof(char *)) {
|
|
printf("Test number of edge count for node = %s failed Expected = %d, got = %d\n",
|
|
tm->test_node[i].node.name,
|
|
tm->test_node[i].node.nb_edges, count);
|
|
return -1;
|
|
}
|
|
next_edges = malloc(count);
|
|
count = rte_node_edge_get(tm->test_node[i].idx, next_edges);
|
|
if (count != tm->test_node[i].node.nb_edges) {
|
|
printf("Test number of edges for node = %s failed Expected = %d, got %d\n",
|
|
tm->test_node[i].node.name,
|
|
tm->test_node[i].node.nb_edges, count);
|
|
free(next_edges);
|
|
return -1;
|
|
}
|
|
|
|
for (j = 0; j < count; j++) {
|
|
if (strcmp(next_edges[j],
|
|
tm->test_node[i].node.next_nodes[j]) != 0) {
|
|
printf("Edge name miss match, expected = %s got = %s\n",
|
|
tm->test_node[i].node.next_nodes[j],
|
|
next_edges[j]);
|
|
free(next_edges);
|
|
return -1;
|
|
}
|
|
}
|
|
free(next_edges);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_node_clone(void)
|
|
{
|
|
test_main_t *tm = &test_main;
|
|
uint32_t node_id, dummy_id;
|
|
int i;
|
|
|
|
node_id = rte_node_from_name("test_node00");
|
|
tm->test_node[0].idx = node_id;
|
|
|
|
/* Clone with same name, should fail */
|
|
dummy_id = rte_node_clone(node_id, "test_node00");
|
|
if (!rte_node_is_invalid(dummy_id)) {
|
|
printf("Got valid id when clone with same name, Expecting fail\n");
|
|
return -1;
|
|
}
|
|
|
|
for (i = 1; i < MAX_NODES; i++) {
|
|
tm->test_node[i].idx =
|
|
rte_node_clone(node_id, tm->test_node[i].node.name);
|
|
if (rte_node_is_invalid(tm->test_node[i].idx)) {
|
|
printf("Got invalid node id\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* Clone from cloned node should fail */
|
|
dummy_id = rte_node_clone(tm->test_node[1].idx, "dummy_node");
|
|
if (!rte_node_is_invalid(dummy_id)) {
|
|
printf("Got valid node id when cloning from cloned node, expected fail\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_update_edges(void)
|
|
{
|
|
test_main_t *tm = &test_main;
|
|
uint32_t node_id;
|
|
uint16_t count;
|
|
int i;
|
|
|
|
node_id = rte_node_from_name("test_node00");
|
|
count = rte_node_edge_update(node_id, 0,
|
|
tm->test_node[0].node.next_nodes,
|
|
tm->test_node[0].node.nb_edges);
|
|
if (count != tm->test_node[0].node.nb_edges) {
|
|
printf("Update edges failed expected: %d got = %d\n",
|
|
tm->test_node[0].node.nb_edges, count);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 1; i < MAX_NODES; i++) {
|
|
count = rte_node_edge_update(tm->test_node[i].idx, 0,
|
|
tm->test_node[i].node.next_nodes,
|
|
tm->test_node[i].node.nb_edges);
|
|
if (count != tm->test_node[i].node.nb_edges) {
|
|
printf("Update edges failed expected: %d got = %d\n",
|
|
tm->test_node[i].node.nb_edges, count);
|
|
return -1;
|
|
}
|
|
|
|
count = rte_node_edge_shrink(tm->test_node[i].idx,
|
|
tm->test_node[i].node.nb_edges);
|
|
if (count != tm->test_node[i].node.nb_edges) {
|
|
printf("Shrink edges failed\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_create_graph(void)
|
|
{
|
|
static const char *node_patterns_dummy[] = {
|
|
"test_node_source1", "test_node00",
|
|
"test_node00-test_node11", "test_node00-test_node22",
|
|
"test_node00-test_node33", "test_node00-dummy_node",
|
|
};
|
|
struct rte_graph_param gconf = {
|
|
.socket_id = SOCKET_ID_ANY,
|
|
.nb_node_patterns = 6,
|
|
.node_patterns = node_patterns_dummy,
|
|
};
|
|
uint32_t dummy_node_id;
|
|
uint32_t node_id;
|
|
|
|
node_id = rte_node_from_name("test_node00");
|
|
dummy_node_id = rte_node_clone(node_id, "dummy_node");
|
|
if (rte_node_is_invalid(dummy_node_id)) {
|
|
printf("Got invalid node id\n");
|
|
return -1;
|
|
}
|
|
|
|
graph_id = rte_graph_create("worker0", &gconf);
|
|
if (graph_id != RTE_GRAPH_ID_INVALID) {
|
|
printf("Graph creation success with isolated node, expected graph creation fail\n");
|
|
return -1;
|
|
}
|
|
|
|
gconf.nb_node_patterns = 5;
|
|
gconf.node_patterns = node_patterns;
|
|
graph_id = rte_graph_create("worker0", &gconf);
|
|
if (graph_id == RTE_GRAPH_ID_INVALID) {
|
|
printf("Graph creation failed with error = %d\n", rte_errno);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_graph_walk(void)
|
|
{
|
|
struct rte_graph *graph = rte_graph_lookup("worker0");
|
|
int i;
|
|
|
|
if (!graph) {
|
|
printf("Graph lookup failed\n");
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < 5; i++)
|
|
rte_graph_walk(graph);
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_graph_lookup_functions(void)
|
|
{
|
|
test_main_t *tm = &test_main;
|
|
struct rte_node *node;
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_NODES; i++) {
|
|
node = rte_graph_node_get(graph_id, tm->test_node[i].idx);
|
|
if (!node) {
|
|
printf("rte_graph_node_get, failed for node = %d\n",
|
|
tm->test_node[i].idx);
|
|
return -1;
|
|
}
|
|
|
|
if (tm->test_node[i].idx != node->id) {
|
|
printf("Node id didn't match, expected = %d got = %d\n",
|
|
tm->test_node[i].idx, node->id);
|
|
return 0;
|
|
}
|
|
|
|
if (strncmp(node->name, node_names[i], RTE_NODE_NAMESIZE)) {
|
|
printf("Node name didn't match, expected = %s got %s\n",
|
|
node_names[i], node->name);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < MAX_NODES; i++) {
|
|
node = rte_graph_node_get_by_name("worker0", node_names[i]);
|
|
if (!node) {
|
|
printf("rte_graph_node_get, failed for node = %d\n",
|
|
tm->test_node[i].idx);
|
|
return -1;
|
|
}
|
|
|
|
if (tm->test_node[i].idx != node->id) {
|
|
printf("Node id didn't match, expected = %d got = %d\n",
|
|
tm->test_node[i].idx, node->id);
|
|
return 0;
|
|
}
|
|
|
|
if (strncmp(node->name, node_names[i], RTE_NODE_NAMESIZE)) {
|
|
printf("Node name didn't match, expected = %s got %s\n",
|
|
node_names[i], node->name);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
graph_cluster_stats_cb_t(bool is_first, bool is_last, void *cookie,
|
|
const struct rte_graph_cluster_node_stats *st)
|
|
{
|
|
int i;
|
|
|
|
RTE_SET_USED(is_first);
|
|
RTE_SET_USED(is_last);
|
|
RTE_SET_USED(cookie);
|
|
|
|
for (i = 0; i < MAX_NODES + 1; i++) {
|
|
rte_node_t id = rte_node_from_name(node_patterns[i]);
|
|
if (id == st->id) {
|
|
if (obj_stats[i] != st->objs) {
|
|
printf("Obj count miss match for node = %s expected = %"PRId64", got=%"PRId64"\n",
|
|
node_patterns[i], obj_stats[i],
|
|
st->objs);
|
|
return -1;
|
|
}
|
|
|
|
if (fn_calls[i] != st->calls) {
|
|
printf("Func call miss match for node = %s expected = %"PRId64", got = %"PRId64"\n",
|
|
node_patterns[i], fn_calls[i],
|
|
st->calls);
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_print_stats(void)
|
|
{
|
|
struct rte_graph_cluster_stats_param s_param;
|
|
struct rte_graph_cluster_stats *stats;
|
|
const char *pattern = "worker0";
|
|
|
|
if (!rte_graph_has_stats_feature())
|
|
return 0;
|
|
|
|
/* Prepare stats object */
|
|
memset(&s_param, 0, sizeof(s_param));
|
|
s_param.f = stdout;
|
|
s_param.socket_id = SOCKET_ID_ANY;
|
|
s_param.graph_patterns = &pattern;
|
|
s_param.nb_graph_patterns = 1;
|
|
s_param.fn = graph_cluster_stats_cb_t;
|
|
|
|
stats = rte_graph_cluster_stats_create(&s_param);
|
|
if (stats == NULL) {
|
|
printf("Unable to get stats\n");
|
|
return -1;
|
|
}
|
|
/* Clear screen and move to top left */
|
|
rte_graph_cluster_stats_get(stats, 0);
|
|
rte_graph_cluster_stats_destroy(stats);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
graph_setup(void)
|
|
{
|
|
int i, j;
|
|
|
|
for (i = 0; i <= MAX_NODES; i++) {
|
|
for (j = 0; j < MBUFF_SIZE; j++)
|
|
mbuf_p[i][j] = &mbuf[i][j];
|
|
}
|
|
if (test_node_clone()) {
|
|
printf("test_node_clone: fail\n");
|
|
return -1;
|
|
}
|
|
printf("test_node_clone: pass\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
graph_teardown(void)
|
|
{
|
|
int id;
|
|
|
|
id = rte_graph_destroy(rte_graph_from_name("worker0"));
|
|
if (id)
|
|
printf("Graph Destroy failed\n");
|
|
}
|
|
|
|
static struct unit_test_suite graph_testsuite = {
|
|
.suite_name = "Graph library test suite",
|
|
.setup = graph_setup,
|
|
.teardown = graph_teardown,
|
|
.unit_test_cases = {
|
|
TEST_CASE(test_update_edges),
|
|
TEST_CASE(test_lookup_functions),
|
|
TEST_CASE(test_create_graph),
|
|
TEST_CASE(test_graph_lookup_functions),
|
|
TEST_CASE(test_graph_walk),
|
|
TEST_CASE(test_print_stats),
|
|
TEST_CASES_END(), /**< NULL terminate unit test array */
|
|
},
|
|
};
|
|
|
|
static int
|
|
graph_autotest_fn(void)
|
|
{
|
|
return unit_test_suite_runner(&graph_testsuite);
|
|
}
|
|
|
|
REGISTER_TEST_COMMAND(graph_autotest, graph_autotest_fn);
|
|
|
|
static int
|
|
test_node_list_dump(void)
|
|
{
|
|
rte_node_list_dump(stdout);
|
|
|
|
return TEST_SUCCESS;
|
|
}
|
|
REGISTER_TEST_COMMAND(node_list_dump, test_node_list_dump);
|