diff options
Diffstat (limited to 'test/validation/api')
-rw-r--r-- | test/validation/api/Makefile.am | 4 | ||||
-rw-r--r-- | test/validation/api/classification/odp_classification_tests.c | 80 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec.c | 4 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec_test_in.c | 58 | ||||
-rw-r--r-- | test/validation/api/ipsec/ipsec_test_out.c | 2 | ||||
-rw-r--r-- | test/validation/api/pktio/pktio.c | 182 | ||||
-rw-r--r-- | test/validation/api/pool/pool.c | 564 | ||||
-rw-r--r-- | test/validation/api/std/.gitignore | 1 | ||||
-rw-r--r-- | test/validation/api/std/Makefile.am | 4 | ||||
-rw-r--r-- | test/validation/api/std/std.c (renamed from test/validation/api/std_clib/std_clib.c) | 20 | ||||
-rw-r--r-- | test/validation/api/std_clib/.gitignore | 1 | ||||
-rw-r--r-- | test/validation/api/std_clib/Makefile.am | 4 | ||||
-rw-r--r-- | test/validation/api/system/system.c | 8 | ||||
-rw-r--r-- | test/validation/api/traffic_mngr/traffic_mngr.c | 449 |
14 files changed, 1199 insertions, 182 deletions
diff --git a/test/validation/api/Makefile.am b/test/validation/api/Makefile.am index ce29781d6..591fe8a82 100644 --- a/test/validation/api/Makefile.am +++ b/test/validation/api/Makefile.am @@ -19,7 +19,7 @@ ODP_MODULES = atomic \ random \ scheduler \ stash \ - std_clib \ + std \ thread \ time \ timer \ @@ -64,7 +64,7 @@ TESTS = \ scheduler/scheduler_main$(EXEEXT) \ scheduler/scheduler_no_predef_groups$(EXEEXT) \ stash/stash_main$(EXEEXT) \ - std_clib/std_clib_main$(EXEEXT) \ + std/std_main$(EXEEXT) \ thread/thread_main$(EXEEXT) \ time/time_main$(EXEEXT) \ timer/timer_main$(EXEEXT) \ diff --git a/test/validation/api/classification/odp_classification_tests.c b/test/validation/api/classification/odp_classification_tests.c index d9c44aea7..41b4ab02f 100644 --- a/test/validation/api/classification/odp_classification_tests.c +++ b/test/validation/api/classification/odp_classification_tests.c @@ -1,5 +1,5 @@ /* Copyright (c) 2015-2018, Linaro Limited - * Copyright (c) 2020, Nokia + * Copyright (c) 2020-2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -453,6 +453,80 @@ void test_pktio_default_cos(odp_bool_t enable_pktv) odp_packet_free(pkt); } +static int classification_check_queue_stats(void) +{ + odp_cls_capability_t capa; + + if (odp_cls_capability(&capa)) + return ODP_TEST_INACTIVE; + + if (capa.stats.queue.all_counters) + return ODP_TEST_ACTIVE; + + return ODP_TEST_INACTIVE; +} + +static void classification_test_queue_stats(odp_bool_t enable_pktv) +{ + odp_cls_capability_t capa; + odp_cls_queue_stats_t stats_start; + odp_cls_queue_stats_t stats_stop; + odp_cos_t cos; + odp_queue_t queue; + + /* Default CoS used for test packets */ + if (!tc.default_cos || !TEST_DEFAULT) { + printf("Default CoS not supported, skipping test\n"); + return; + } + + cos = cos_list[CLS_DEFAULT]; + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + queue = odp_cos_queue(cos); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + CU_ASSERT_FATAL(odp_cls_capability(&capa) == 0); + + CU_ASSERT(odp_cls_queue_stats(cos, queue, &stats_start) == 0); + + test_pktio_default_cos(enable_pktv); + + CU_ASSERT(odp_cls_queue_stats(cos, queue, &stats_stop) == 0); + + if (capa.stats.queue.counter.packets) + CU_ASSERT(stats_stop.packets > stats_start.packets); + if (capa.stats.queue.counter.octets) + CU_ASSERT(stats_stop.octets > stats_start.octets); + CU_ASSERT((stats_stop.discards - stats_start.discards) == 0); + CU_ASSERT((stats_stop.errors - stats_start.errors) == 0); + + printf("\nQueue statistics\n----------------\n"); + printf(" discards: %" PRIu64 "\n", stats_stop.discards); + printf(" errors: %" PRIu64 "\n", stats_stop.errors); + printf(" octets: %" PRIu64 "\n", stats_stop.octets); + printf(" packets: %" PRIu64 "\n", stats_stop.packets); + + /* Check that all unsupported counters are still zero */ + if (!capa.stats.queue.counter.discards) + CU_ASSERT(stats_stop.discards == 0); + if (!capa.stats.queue.counter.errors) + CU_ASSERT(stats_stop.errors == 0); + if (!capa.stats.queue.counter.octets) + CU_ASSERT(stats_stop.octets == 0); + if (!capa.stats.queue.counter.packets) + CU_ASSERT(stats_stop.packets == 0); +} + +static void classification_test_queue_stats_pkt(void) +{ + classification_test_queue_stats(false); +} + +static void classification_test_queue_stats_pktv(void) +{ + classification_test_queue_stats(true); +} + void configure_pktio_error_cos(odp_bool_t enable_pktv) { int retval; @@ -933,6 +1007,8 @@ odp_testinfo_t classification_suite[] = { ODP_TEST_INFO(classification_test_pktio_set_headroom), ODP_TEST_INFO(classification_test_pktio_configure), ODP_TEST_INFO(classification_test_pktio_test), + ODP_TEST_INFO_CONDITIONAL(classification_test_queue_stats_pkt, + classification_check_queue_stats), ODP_TEST_INFO_NULL, }; @@ -941,5 +1017,7 @@ odp_testinfo_t classification_suite_pktv[] = { classification_check_pktv), ODP_TEST_INFO_CONDITIONAL(classification_test_pktio_test_pktv, classification_check_pktv), + ODP_TEST_INFO_CONDITIONAL(classification_test_queue_stats_pktv, + classification_check_queue_stats), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c index 981bc9155..5bbc9c025 100644 --- a/test/validation/api/ipsec/ipsec.c +++ b/test/validation/api/ipsec/ipsec.c @@ -1175,7 +1175,7 @@ int ipsec_config(odp_instance_t ODP_UNUSED inst) if (ipsec_config.inbound.reassembly.max_wait_time > capa.reassembly.max_wait_time) ipsec_config.inbound.reassembly.max_wait_time = capa.reassembly.max_wait_time; - ipsec_config.inbound.reassembly.max_num_frags = capa.reassembly.max_num_frags; + ipsec_config.inbound.reassembly.max_num_frags = MAX_FRAGS; if (capa.reassembly.ip) { ipsec_config.inbound.reassembly.en_ipv4 = true; @@ -1205,7 +1205,7 @@ int ipsec_config(odp_instance_t ODP_UNUSED inst) ipsec_config.inbound.reassembly.en_ipv6 = false; } - if (ipsec_config.inbound.reassembly.max_num_frags > MAX_FRAGS) { + if (capa.reassembly.max_num_frags < MAX_FRAGS) { ipsec_config.inbound.reassembly.en_ipv4 = false; ipsec_config.inbound.reassembly.en_ipv6 = false; } diff --git a/test/validation/api/ipsec/ipsec_test_in.c b/test/validation/api/ipsec/ipsec_test_in.c index 08512c8fb..ef6996f1d 100644 --- a/test/validation/api/ipsec/ipsec_test_in.c +++ b/test/validation/api/ipsec/ipsec_test_in.c @@ -1782,7 +1782,7 @@ static void test_multi_out_in(odp_ipsec_sa_t out_sa, ipsec_test_part test_out; ipsec_test_part test_in; ipsec_test_packet test_pkt; - odp_packet_t pkt; + odp_packet_t pkt = ODP_PACKET_INVALID; /* * Convert plain text packet to IPsec packet through @@ -1875,27 +1875,15 @@ static void test_in_ipv4_esp_reass_success_four_frags_ooo(odp_ipsec_sa_t out_sa, static void test_in_ipv4_esp_reass_incomp_missing(odp_ipsec_sa_t out_sa, odp_ipsec_sa_t in_sa) { - ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; - ipsec_test_packet test_pkt; - odp_packet_t pkt; - - memset(test_in, 0, sizeof(test_in)); - - CU_ASSERT(MAX_FRAGS >= 1); - - part_prep_esp(test_out, 1, false); - - test_out[0].pkt_in = &pkt_ipv4_udp_p1_f1; - - part_prep_plain(&test_in[0], 1, false, true); - test_in[0].out[0].pkt_res = &pkt_ipv4_udp_p1_f1; - - CU_ASSERT_EQUAL(ipsec_check_out(&test_out[0], out_sa, &pkt), 1); - - ipsec_test_packet_from_pkt(&test_pkt, &pkt); - test_in[0].pkt_in = &test_pkt; + ipsec_test_packet *input_packets[] = { + &pkt_ipv4_udp_p1_f1, + }; + ipsec_test_packet *result_packet = &pkt_ipv4_udp_p1_f1; - ipsec_check_in_one(&test_in[0], in_sa); + test_multi_out_in(out_sa, in_sa, ODPH_IPV4, + ARRAY_SIZE(input_packets), + input_packets, + result_packet); } static void test_in_ipv4_esp_reass_success(void) @@ -2068,27 +2056,15 @@ static void test_in_ipv6_esp_reass_success_four_frags_ooo(odp_ipsec_sa_t out_sa, static void test_in_ipv6_esp_reass_incomp_missing(odp_ipsec_sa_t out_sa, odp_ipsec_sa_t in_sa) { - ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; - ipsec_test_packet test_pkt; - odp_packet_t pkt; - - memset(test_in, 0, sizeof(test_in)); - - CU_ASSERT(MAX_FRAGS >= 1); - - part_prep_esp(test_out, 1, true); - - test_out[0].pkt_in = &pkt_ipv6_udp_p1_f1; - - part_prep_plain(&test_in[0], 1, true, true); - test_in[0].out[0].pkt_res = &pkt_ipv6_udp_p1_f1; - - CU_ASSERT_EQUAL(ipsec_check_out(&test_out[0], out_sa, &pkt), 1); - - ipsec_test_packet_from_pkt(&test_pkt, &pkt); - test_in[0].pkt_in = &test_pkt; + ipsec_test_packet *input_packets[] = { + &pkt_ipv6_udp_p1_f1, + }; + ipsec_test_packet *result_packet = &pkt_ipv6_udp_p1_f1; - ipsec_check_in_one(&test_in[0], in_sa); + test_multi_out_in(out_sa, in_sa, ODPH_IPV6, + ARRAY_SIZE(input_packets), + input_packets, + result_packet); } static void test_in_ipv6_esp_reass_success(void) diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c index 3349ded99..733db10b9 100644 --- a/test/validation/api/ipsec/ipsec_test_out.c +++ b/test/validation/api/ipsec/ipsec_test_out.c @@ -68,6 +68,7 @@ static struct auth_param auths[] = { ALG(ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, NULL), ALG(ODP_AUTH_ALG_SHA384_HMAC, &key_5a_384, NULL), ALG(ODP_AUTH_ALG_SHA512_HMAC, &key_5a_512, NULL), + ALG(ODP_AUTH_ALG_AES_CMAC, &key_5a_128, NULL), ALG(ODP_AUTH_ALG_AES_XCBC_MAC, &key_5a_128, NULL) }; @@ -1583,6 +1584,7 @@ static void ipsec_test_default_values(void) CU_ASSERT(sa_param.proto == ODP_IPSEC_ESP); CU_ASSERT(sa_param.crypto.cipher_alg == ODP_CIPHER_ALG_NULL); CU_ASSERT(sa_param.crypto.auth_alg == ODP_AUTH_ALG_NULL); + CU_ASSERT(sa_param.crypto.icv_len == 0); CU_ASSERT(sa_param.opt.esn == 0); CU_ASSERT(sa_param.opt.udp_encap == 0); CU_ASSERT(sa_param.opt.copy_dscp == 0); diff --git a/test/validation/api/pktio/pktio.c b/test/validation/api/pktio/pktio.c index 838d50fd8..3b6cf52dd 100644 --- a/test/validation/api/pktio/pktio.c +++ b/test/validation/api/pktio/pktio.c @@ -2578,6 +2578,186 @@ static void pktio_test_extra_stats(void) CU_ASSERT(odp_pktio_close(pktio) == 0); } +static int pktio_check_proto_statistics_counters(void) +{ + odp_proto_stats_capability_t capa; + odp_pktio_param_t pktio_param; + odp_pktio_t pktio; + int ret; + + odp_pktio_param_init(&pktio_param); + pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; + + pktio = odp_pktio_open(iface_name[0], pool[0], &pktio_param); + if (pktio == ODP_PKTIO_INVALID) + return ODP_TEST_INACTIVE; + + ret = odp_proto_stats_capability(pktio, &capa); + (void)odp_pktio_close(pktio); + + if (ret < 0 || capa.tx.counters.all_bits == 0) + return ODP_TEST_INACTIVE; + + return ODP_TEST_ACTIVE; +} + +static void validate_proto_stats(odp_proto_stats_t stat, odp_packet_proto_stats_opt_t opt, + odp_proto_stats_capability_t capa, uint64_t pkts) +{ + odp_proto_stats_data_t data; + int ret; + + ret = odp_proto_stats(stat, &data); + CU_ASSERT(ret == 0); + + CU_ASSERT(!(capa.tx.counters.bit.tx_pkt_drops && (data.tx_pkt_drops > 0))); + CU_ASSERT(!(capa.tx.counters.bit.tx_oct_count0_drops && (data.tx_oct_count0_drops > 0))); + CU_ASSERT(!(capa.tx.counters.bit.tx_oct_count1_drops && (data.tx_oct_count1_drops > 0))); + CU_ASSERT(!(capa.tx.counters.bit.tx_pkts && (data.tx_pkts != pkts))); + + if (capa.tx.counters.bit.tx_oct_count0) { + int64_t counted_bytes = PKT_LEN_NORMAL; + + if (capa.tx.oct_count0_adj) + counted_bytes += opt.oct_count0_adj; + CU_ASSERT(data.tx_oct_count0 == counted_bytes * pkts); + } + + if (capa.tx.counters.bit.tx_oct_count1) { + int64_t counted_bytes = PKT_LEN_NORMAL; + + if (capa.tx.oct_count1_adj) + counted_bytes += opt.oct_count1_adj; + CU_ASSERT(data.tx_oct_count1 == counted_bytes * pkts); + } +} + +static void pktio_test_proto_statistics_counters(void) +{ + odp_pktio_t pktio_rx, pktio_tx; + odp_pktio_t pktio[MAX_NUM_IFACES] = { + ODP_PKTIO_INVALID, ODP_PKTIO_INVALID + }; + odp_packet_t pkt; + const uint32_t num_pkts = 10; + odp_packet_t tx_pkt[num_pkts]; + uint32_t pkt_seq[num_pkts]; + odp_event_t ev; + int i, pkts, tx_pkts, ret, alloc = 0; + odp_pktout_queue_t pktout; + uint64_t wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS); + uint64_t flow0_pkts = 0, flow1_pkts = 0; + odp_proto_stats_capability_t capa; + odp_packet_proto_stats_opt_t opt0; + odp_packet_proto_stats_opt_t opt1; + odp_proto_stats_param_t param; + odp_pktio_config_t config; + odp_proto_stats_t stat0; + odp_proto_stats_t stat1; + + memset(&pktout, 0, sizeof(pktout)); + + for (i = 0; i < num_ifaces; i++) { + pktio[i] = create_pktio(i, ODP_PKTIN_MODE_SCHED, + ODP_PKTOUT_MODE_DIRECT); + + CU_ASSERT_FATAL(pktio[i] != ODP_PKTIO_INVALID); + } + pktio_tx = pktio[0]; + pktio_rx = (num_ifaces > 1) ? pktio[1] : pktio_tx; + + /* Enable protocol stats on Tx interface */ + odp_pktio_config_init(&config); + config.pktout.bit.proto_stats_ena = 1; + ret = odp_pktio_config(pktio_tx, &config); + CU_ASSERT(ret == 0); + + CU_ASSERT_FATAL(odp_pktout_queue(pktio_tx, &pktout, 1) == 1); + + ret = odp_pktio_start(pktio_tx); + CU_ASSERT(ret == 0); + if (num_ifaces > 1) { + ret = odp_pktio_start(pktio_rx); + CU_ASSERT(ret == 0); + } + + odp_proto_stats_param_init(¶m); + odp_proto_stats_capability(pktio_tx, &capa); + CU_ASSERT(capa.tx.counters.all_bits != 0); + param.counters.all_bits = capa.tx.counters.all_bits; + /* Create statistics object with all supported counters */ + stat0 = odp_proto_stats_create("flow0_stat", ¶m); + CU_ASSERT_FATAL(stat0 != ODP_PROTO_STATS_INVALID); + stat1 = odp_proto_stats_create("flow1_stat", ¶m); + CU_ASSERT_FATAL(stat1 != ODP_PROTO_STATS_INVALID); + + /* Flow-0 options */ + opt0.stat = stat0; + opt0.oct_count0_adj = 0; + /* oct1 contains byte count of packets excluding Ethernet header */ + opt0.oct_count1_adj = -14; + + /* Flow-1 options */ + opt1.stat = stat1; + opt1.oct_count0_adj = -8; + opt1.oct_count1_adj = 14; + + alloc = create_packets(tx_pkt, pkt_seq, num_pkts, pktio_tx, pktio_rx); + + /* Attach statistics object to all Tx packets */ + for (pkts = 0; pkts < alloc; pkts++) { + if ((pkts % 2) == 0) { + odp_packet_proto_stats_request(tx_pkt[pkts], &opt0); + flow0_pkts++; + } else { + odp_packet_proto_stats_request(tx_pkt[pkts], &opt1); + flow1_pkts++; + } + } + + /* send */ + for (pkts = 0; pkts != alloc; ) { + ret = odp_pktout_send(pktout, &tx_pkt[pkts], alloc - pkts); + if (ret < 0) { + CU_FAIL("unable to send packet\n"); + break; + } + pkts += ret; + } + tx_pkts = pkts; + + /* get */ + for (i = 0, pkts = 0; i < (int)num_pkts && pkts != tx_pkts; i++) { + ev = odp_schedule(NULL, wait); + if (ev != ODP_EVENT_INVALID) { + if (odp_event_type(ev) == ODP_EVENT_PACKET) { + pkt = odp_packet_from_event(ev); + if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID) + pkts++; + } + odp_event_free(ev); + } + } + + CU_ASSERT(pkts == tx_pkts); + + /* Validate Flow-0 packet statistics */ + validate_proto_stats(stat0, opt0, capa, flow0_pkts); + + /* Validate Flow-1 packet statistics */ + validate_proto_stats(stat1, opt1, capa, flow1_pkts); + + for (i = 0; i < num_ifaces; i++) { + CU_ASSERT(odp_pktio_stop(pktio[i]) == 0); + flush_input_queue(pktio[i], ODP_PKTIN_MODE_SCHED); + CU_ASSERT(odp_pktio_close(pktio[i]) == 0); + } + + /* Destroy proto statistics object */ + CU_ASSERT(odp_proto_stats_destroy(stat0) == 0); + CU_ASSERT(odp_proto_stats_destroy(stat1) == 0); +} + static int pktio_check_start_stop(void) { if (getenv("ODP_PKTIO_TEST_DISABLE_START_STOP")) @@ -4617,6 +4797,8 @@ odp_testinfo_t pktio_suite_unsegmented[] = { ODP_TEST_INFO_CONDITIONAL(pktio_test_event_queue_statistics_counters, pktio_check_event_queue_statistics_counters), ODP_TEST_INFO(pktio_test_extra_stats), + ODP_TEST_INFO_CONDITIONAL(pktio_test_proto_statistics_counters, + pktio_check_proto_statistics_counters), ODP_TEST_INFO_CONDITIONAL(pktio_test_pktin_ts, pktio_check_pktin_ts), ODP_TEST_INFO_CONDITIONAL(pktio_test_pktout_ts, diff --git a/test/validation/api/pool/pool.c b/test/validation/api/pool/pool.c index 78037c65c..d791063e2 100644 --- a/test/validation/api/pool/pool.c +++ b/test/validation/api/pool/pool.c @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2018, Linaro Limited * Copyright (c) 2020, Marvell - * Copyright (c) 2020, Nokia + * Copyright (c) 2020-2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -8,6 +8,8 @@ #include <odp_api.h> #include "odp_cunit_common.h" +#include "test_common_macros.h" +#include <odp/helper/odph_api.h> #define BUF_SIZE 1500 #define BUF_NUM 1000 @@ -19,6 +21,14 @@ #define CACHE_SIZE 32 #define MAX_NUM_DEFAULT (10 * 1024 * 1024) +#define EXT_NUM_BUF 10 +#define EXT_BUF_SIZE 2048 +#define EXT_BUF_ALIGN 64 +#define EXT_APP_HDR_SIZE 128 +#define EXT_UAREA_SIZE 32 +#define EXT_HEADROOM 16 +#define MAGIC_U8 0x7a + typedef struct { odp_barrier_t init_barrier; odp_atomic_u32_t index; @@ -30,6 +40,7 @@ static global_shared_mem_t *global_mem; static odp_pool_capability_t global_pool_capa; static odp_pool_param_t default_pool_param; +static odp_pool_ext_capability_t global_pool_ext_capa; static void pool_create_destroy(odp_pool_param_t *param) { @@ -914,7 +925,7 @@ static int pool_check_timeout_pool_statistics(void) return ODP_TEST_ACTIVE; } -static void pool_test_pool_statistics(int pool_type) +static void pool_test_pool_statistics(odp_pool_type_t pool_type) { odp_pool_stats_t stats; odp_pool_param_t param; @@ -1121,6 +1132,504 @@ static void pool_test_timeout_pool_statistics(void) pool_test_pool_statistics(ODP_POOL_TIMEOUT); } +static void pool_ext_init_packet_pool_param(odp_pool_ext_param_t *param) +{ + odp_pool_ext_capability_t capa; + uint32_t head_offset, head_align, trailer_size; + odp_pool_type_t type = ODP_POOL_PACKET; + uint32_t num_buf = EXT_NUM_BUF; + uint32_t buf_size = EXT_BUF_SIZE; + uint32_t uarea_size = EXT_UAREA_SIZE; + uint32_t headroom = EXT_HEADROOM; + uint32_t app_hdr_size = EXT_APP_HDR_SIZE; + + CU_ASSERT_FATAL(odp_pool_ext_capability(type, &capa) == 0); + + odp_pool_ext_param_init(type, param); + + if (num_buf > capa.pkt.max_num_buf) + num_buf = capa.pkt.max_num_buf; + + if (buf_size > capa.pkt.max_buf_size) + buf_size = capa.pkt.max_buf_size; + + if (uarea_size > capa.pkt.max_uarea_size) + uarea_size = capa.pkt.max_uarea_size; + + if (headroom > capa.pkt.max_headroom) + headroom = capa.pkt.max_headroom; + + head_align = capa.pkt.min_head_align; + head_offset = capa.pkt.odp_header_size + app_hdr_size; + trailer_size = capa.pkt.odp_trailer_size; + + CU_ASSERT_FATAL(head_offset < buf_size); + CU_ASSERT_FATAL((head_offset + trailer_size) < buf_size); + + while (head_offset % head_align) { + app_hdr_size++; + head_offset = capa.pkt.odp_header_size + app_hdr_size; + + if (head_offset >= buf_size) { + ODPH_ERR("Head align too large (%u). No room for data.\n", head_align); + break; + } + } + + CU_ASSERT_FATAL(head_offset < buf_size); + CU_ASSERT_FATAL((head_offset + trailer_size) < buf_size); + CU_ASSERT_FATAL((head_offset % head_align) == 0); + + param->pkt.num_buf = num_buf; + param->pkt.buf_size = buf_size; + param->pkt.app_header_size = app_hdr_size; + param->pkt.uarea_size = uarea_size; + param->pkt.headroom = headroom; +} + +static void test_packet_pool_ext_capa(void) +{ + odp_pool_ext_capability_t capa; + odp_pool_type_t type = ODP_POOL_PACKET; + + CU_ASSERT_FATAL(odp_pool_ext_capability(type, &capa) == 0); + + CU_ASSERT(capa.type == type); + + /* External memory pools not supported */ + if (capa.max_pools == 0) + return; + + CU_ASSERT(capa.max_pools > 0); + CU_ASSERT(capa.min_cache_size <= capa.max_cache_size); + CU_ASSERT(capa.pkt.max_num_buf > 0); + CU_ASSERT(capa.pkt.max_buf_size > 0); + CU_ASSERT(capa.pkt.min_mem_align > 0); + CU_ASSERT(TEST_CHECK_POW2(capa.pkt.min_mem_align)); + CU_ASSERT(capa.pkt.min_buf_align > 0); + CU_ASSERT(capa.pkt.min_head_align > 0); + CU_ASSERT(capa.pkt.max_headroom > 0); + CU_ASSERT(capa.pkt.max_headroom_size > 0); + CU_ASSERT(capa.pkt.max_headroom_size >= capa.pkt.max_headroom); + CU_ASSERT(capa.pkt.max_segs_per_pkt > 0); + CU_ASSERT(capa.pkt.max_uarea_size > 0); +} + +static void test_packet_pool_ext_param_init(void) +{ + odp_pool_ext_param_t param; + + odp_pool_ext_param_init(ODP_POOL_PACKET, ¶m); + + CU_ASSERT(param.type == ODP_POOL_PACKET); + CU_ASSERT(param.cache_size >= global_pool_ext_capa.min_cache_size && + param.cache_size <= global_pool_ext_capa.max_cache_size); + CU_ASSERT(param.stats.all == 0); + CU_ASSERT(param.pkt.app_header_size == 0); + CU_ASSERT(param.pkt.uarea_size == 0); +} + +static void test_packet_pool_ext_create(void) +{ + odp_pool_t pool; + odp_pool_ext_param_t param; + + pool_ext_init_packet_pool_param(¶m); + + pool = odp_pool_ext_create("pool_ext_0", ¶m); + + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + CU_ASSERT(odp_pool_destroy(pool) == 0); +} + +static void test_packet_pool_ext_lookup(void) +{ + odp_pool_t pool, pool_1; + odp_pool_ext_param_t param; + const char *name = "pool_ext_0"; + + pool_ext_init_packet_pool_param(¶m); + + pool = odp_pool_ext_create(name, ¶m); + + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + pool_1 = odp_pool_lookup(name); + + CU_ASSERT_FATAL(pool_1 != ODP_POOL_INVALID); + CU_ASSERT(pool == pool_1); + + CU_ASSERT(odp_pool_destroy(pool) == 0); +} + +static void test_packet_pool_ext_info(void) +{ + odp_pool_t pool; + odp_pool_ext_param_t param; + odp_pool_info_t info; + const char *name = "pool_ext_0"; + + pool_ext_init_packet_pool_param(¶m); + + pool = odp_pool_ext_create(name, ¶m); + + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + memset(&info, 0, sizeof(odp_pool_info_t)); + CU_ASSERT_FATAL(odp_pool_info(pool, &info) == 0); + + CU_ASSERT(info.pool_ext); + CU_ASSERT(strncmp(name, info.name, strlen(name)) == 0); + + CU_ASSERT(odp_pool_destroy(pool) == 0); +} + +static odp_shm_t populate_pool(odp_pool_t pool, odp_pool_ext_capability_t *capa, + void *buf[], uint32_t num, uint32_t buf_size) +{ + odp_shm_t shm; + uint8_t *buf_ptr; + uint32_t i; + uint32_t shm_size, mem_align; + uint32_t flags = 0; + uint32_t buf_align = EXT_BUF_ALIGN; + uint32_t min_align = capa->pkt.min_buf_align; + + CU_ASSERT_FATAL(min_align > 0); + + if (min_align > buf_align) + buf_align = min_align; + + if (capa->pkt.buf_size_aligned) { + buf_align = buf_size; + CU_ASSERT_FATAL((buf_size % min_align) == 0); + } + + mem_align = buf_align; + if (capa->pkt.min_mem_align > mem_align) + mem_align = capa->pkt.min_mem_align; + + /* Prepare to align every buffer */ + shm_size = (num + 1) * (buf_size + buf_align); + + shm = odp_shm_reserve("test_pool_ext_populate", shm_size, mem_align, 0); + if (shm == ODP_SHM_INVALID) + return ODP_SHM_INVALID; + + buf_ptr = odp_shm_addr(shm); + CU_ASSERT_FATAL((uintptr_t)buf_ptr % mem_align == 0); + + /* initialize entire pool memory with a pattern */ + memset(buf_ptr, MAGIC_U8, shm_size); + + /* Move from mem_align to buf_align */ + while ((uintptr_t)buf_ptr % buf_align) + buf_ptr++; + + for (i = 0; i < num; i++) { + if (i == num - 1) + flags = ODP_POOL_POPULATE_DONE; + + buf[i] = buf_ptr; + CU_ASSERT_FATAL(odp_pool_ext_populate(pool, &buf[i], buf_size, 1, flags) == 0); + + buf_ptr += buf_size; + while ((uintptr_t)buf_ptr % buf_align) + buf_ptr++; + } + + return shm; +} + +static void test_packet_pool_ext_populate(void) +{ + odp_shm_t shm; + odp_pool_t pool; + odp_pool_ext_param_t param; + odp_pool_ext_capability_t capa; + uint32_t buf_size, num_buf; + void *buf[EXT_NUM_BUF]; + + CU_ASSERT_FATAL(odp_pool_ext_capability(ODP_POOL_PACKET, &capa) == 0); + + pool_ext_init_packet_pool_param(¶m); + num_buf = param.pkt.num_buf; + buf_size = param.pkt.buf_size; + + CU_ASSERT_FATAL(capa.pkt.min_head_align > 0); + + pool = odp_pool_ext_create("pool_ext_0", ¶m); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + shm = populate_pool(pool, &capa, buf, num_buf, buf_size); + CU_ASSERT_FATAL(shm != ODP_SHM_INVALID); + + CU_ASSERT(odp_pool_destroy(pool) == 0); + CU_ASSERT(odp_shm_free(shm) == 0); +} + +static uint32_t find_buf(odp_packet_t pkt, void *buf[], uint32_t num, uint32_t head_offset) +{ + uint32_t i; + uint8_t *ptr; + uint8_t *head = odp_packet_head(pkt); + + for (i = 0; i < num; i++) { + ptr = buf[i]; + ptr += head_offset; + + if (head == ptr) + break; + } + + return i; +} + +#define PKT_LEN_NORMAL 0 +#define PKT_LEN_MAX 1 +#define PKT_LEN_SEGMENTED 2 + +static void packet_pool_ext_alloc(int len_test) +{ + odp_shm_t shm; + odp_pool_t pool; + odp_pool_ext_param_t param; + odp_pool_ext_capability_t capa; + uint32_t i, j, buf_size, num_buf, num_pkt, num_alloc, buf_index; + uint32_t pkt_len, head_offset, trailer_size, headroom, max_headroom; + uint32_t hr, tr, uarea_size, max_payload, buf_data_size, app_hdr_size; + int num_seg; + uint8_t *app_hdr; + void *buf[EXT_NUM_BUF]; + odp_packet_t pkt[EXT_NUM_BUF]; + uint32_t seg_len = 0; + + CU_ASSERT_FATAL(odp_pool_ext_capability(ODP_POOL_PACKET, &capa) == 0); + + pool_ext_init_packet_pool_param(¶m); + num_buf = param.pkt.num_buf; + buf_size = param.pkt.buf_size; + uarea_size = param.pkt.uarea_size; + + pool = odp_pool_ext_create("pool_ext_0", ¶m); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + shm = populate_pool(pool, &capa, buf, num_buf, buf_size); + CU_ASSERT_FATAL(shm != ODP_SHM_INVALID); + + app_hdr_size = param.pkt.app_header_size; + head_offset = capa.pkt.odp_header_size + app_hdr_size; + max_headroom = capa.pkt.max_headroom_size; + headroom = param.pkt.headroom; + trailer_size = capa.pkt.odp_trailer_size; + buf_data_size = buf_size - head_offset - trailer_size; + max_payload = buf_data_size - max_headroom; + num_pkt = num_buf; + num_seg = 1; + + if (len_test == PKT_LEN_NORMAL) { + pkt_len = (buf_data_size - headroom) / 2; + } else if (len_test == PKT_LEN_MAX) { + pkt_len = max_payload; + } else { + CU_ASSERT_FATAL(capa.pkt.max_segs_per_pkt > 1); + /* length that results 2 segments */ + pkt_len = max_payload + (buf_size / 2); + num_seg = 2; + num_pkt = num_buf / num_seg; + } + + for (i = 0; i < num_pkt; i++) { + pkt[i] = odp_packet_alloc(pool, pkt_len); + CU_ASSERT(pkt[i] != ODP_PACKET_INVALID); + if (pkt[i] == ODP_PACKET_INVALID) + break; + + CU_ASSERT(odp_packet_len(pkt[i]) == pkt_len); + CU_ASSERT(odp_packet_headroom(pkt[i]) >= headroom); + buf_index = find_buf(pkt[i], buf, num_buf, head_offset); + CU_ASSERT(buf_index < num_buf); + hr = (uintptr_t)odp_packet_data(pkt[i]) - (uintptr_t)odp_packet_head(pkt[i]); + CU_ASSERT(hr == odp_packet_headroom(pkt[i])); + CU_ASSERT(num_seg == odp_packet_num_segs(pkt[i])); + CU_ASSERT(odp_packet_data(pkt[i]) == odp_packet_data_seg_len(pkt[i], &seg_len)); + CU_ASSERT(odp_packet_seg_len(pkt[i]) == seg_len); + + if (num_seg == 1) { + tr = buf_data_size - hr - pkt_len; + CU_ASSERT(tr == odp_packet_tailroom(pkt[i])); + CU_ASSERT(odp_packet_seg_len(pkt[i]) == pkt_len); + } else { + odp_packet_seg_t seg = odp_packet_last_seg(pkt[i]); + uint32_t last_seg_len = odp_packet_seg_data_len(pkt[i], seg); + uint32_t max_tr = buf_data_size - last_seg_len; + + CU_ASSERT(odp_packet_tailroom(pkt[i]) <= max_tr); + CU_ASSERT(pkt_len == (odp_packet_seg_len(pkt[i]) + last_seg_len)); + } + + CU_ASSERT(odp_packet_buf_len(pkt[i]) == num_seg * buf_data_size); + + if (uarea_size) { + CU_ASSERT(odp_packet_user_area(pkt[i]) != NULL); + CU_ASSERT(odp_packet_user_area_size(pkt[i]) == uarea_size); + } + + /* Check that application header content has not changed */ + app_hdr = (uint8_t *)odp_packet_head(pkt[i]) - app_hdr_size; + for (j = 0; j < app_hdr_size; j++) + CU_ASSERT(app_hdr[j] == MAGIC_U8); + } + + num_alloc = i; + CU_ASSERT(num_alloc == num_pkt); + + /* Pool is now empty */ + CU_ASSERT(odp_packet_alloc(pool, pkt_len) == ODP_PACKET_INVALID); + + for (i = 0; i < num_alloc; i++) + odp_packet_free(pkt[i]); + + CU_ASSERT(odp_pool_destroy(pool) == 0); + CU_ASSERT(odp_shm_free(shm) == 0); +} + +static void test_packet_pool_ext_alloc(void) +{ + packet_pool_ext_alloc(PKT_LEN_NORMAL); +} + +static void test_packet_pool_ext_alloc_max(void) +{ + packet_pool_ext_alloc(PKT_LEN_MAX); +} + +static void test_packet_pool_ext_alloc_seg(void) +{ + packet_pool_ext_alloc(PKT_LEN_SEGMENTED); +} + +static void test_packet_pool_ext_disassemble(void) +{ + odp_shm_t shm; + odp_pool_t pool; + odp_pool_ext_param_t param; + odp_pool_ext_capability_t capa; + uint32_t i, j, buf_size, num_buf, num_pkt, num_alloc, buf_index; + uint32_t pkt_len, head_offset, trailer_size, headroom, max_headroom; + uint32_t hr, max_payload, buf_data_size; + uint32_t num_seg; + void *buf[EXT_NUM_BUF]; + odp_packet_t pkt_tbl[EXT_NUM_BUF]; + + CU_ASSERT_FATAL(odp_pool_ext_capability(ODP_POOL_PACKET, &capa) == 0); + CU_ASSERT_FATAL(capa.pkt.max_segs_per_pkt > 1); + + pool_ext_init_packet_pool_param(¶m); + num_buf = param.pkt.num_buf; + buf_size = param.pkt.buf_size; + + pool = odp_pool_ext_create("pool_ext_0", ¶m); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + shm = populate_pool(pool, &capa, buf, num_buf, buf_size); + CU_ASSERT_FATAL(shm != ODP_SHM_INVALID); + + head_offset = capa.pkt.odp_header_size + param.pkt.app_header_size; + max_headroom = capa.pkt.max_headroom_size; + headroom = param.pkt.headroom; + trailer_size = capa.pkt.odp_trailer_size; + buf_data_size = buf_size - head_offset - trailer_size; + max_payload = buf_data_size - max_headroom; + + /* length that results 2 segments */ + pkt_len = max_payload + (buf_size / 2); + num_seg = 2; + num_pkt = num_buf / num_seg; + + for (i = 0; i < num_pkt; i++) { + odp_packet_t pkt; + odp_packet_seg_t seg; + uint32_t num_pkt_buf, data_offset, data_len; + void *head, *data, *pkt_head; + odp_packet_buf_t pkt_buf[num_seg]; + void *seg_data[num_seg]; + uint32_t seg_len[num_seg]; + + pkt = odp_packet_alloc(pool, pkt_len); + pkt_tbl[i] = pkt; + CU_ASSERT(pkt != ODP_PACKET_INVALID); + if (pkt == ODP_PACKET_INVALID) + break; + + CU_ASSERT(odp_packet_len(pkt) == pkt_len); + CU_ASSERT(odp_packet_headroom(pkt) >= headroom); + buf_index = find_buf(pkt, buf, num_buf, head_offset); + CU_ASSERT(buf_index < num_buf); + pkt_head = odp_packet_head(pkt); + hr = (uintptr_t)odp_packet_data(pkt) - (uintptr_t)pkt_head; + CU_ASSERT(hr == odp_packet_headroom(pkt)); + CU_ASSERT((int)num_seg == odp_packet_num_segs(pkt)); + + seg = odp_packet_first_seg(pkt); + for (j = 0; j < num_seg; j++) { + seg_data[j] = odp_packet_seg_data(pkt, seg); + seg_len[j] = odp_packet_seg_data_len(pkt, seg); + seg = odp_packet_next_seg(pkt, seg); + } + + CU_ASSERT(odp_packet_data(pkt) == seg_data[0]); + CU_ASSERT(odp_packet_seg_len(pkt) == seg_len[0]) + + /* Disassemble packet */ + num_pkt_buf = odp_packet_disassemble(pkt, pkt_buf, num_seg); + CU_ASSERT_FATAL(num_pkt_buf == num_seg); + + CU_ASSERT(odp_packet_buf_head(pkt_buf[0]) == pkt_head); + CU_ASSERT(odp_packet_buf_data_offset(pkt_buf[0]) == hr); + + for (j = 0; j < num_seg; j++) { + CU_ASSERT(odp_packet_buf_size(pkt_buf[j]) == buf_data_size); + + head = odp_packet_buf_head(pkt_buf[j]); + data_offset = odp_packet_buf_data_offset(pkt_buf[j]); + data = (uint8_t *)head + data_offset; + CU_ASSERT(seg_data[j] == data); + data_len = odp_packet_buf_data_len(pkt_buf[j]); + CU_ASSERT(seg_len[j] == data_len); + + CU_ASSERT(odp_packet_buf_from_head(pool, head) == pkt_buf[j]); + + /* Pull in head and tail by one byte */ + odp_packet_buf_data_set(pkt_buf[j], data_offset + 1, data_len - 2); + CU_ASSERT(odp_packet_buf_data_offset(pkt_buf[j]) == data_offset + 1); + CU_ASSERT(odp_packet_buf_data_len(pkt_buf[j]) == data_len - 2); + } + + /* Reassemble packet, each segment is now 2 bytes shorter */ + pkt = odp_packet_reassemble(pool, pkt_buf, num_seg); + + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_num_segs(pkt) == (int)num_seg); + pkt_tbl[i] = pkt; + + CU_ASSERT(odp_packet_len(pkt) == (pkt_len - (num_seg * 2))); + } + + num_alloc = i; + CU_ASSERT(num_alloc == num_pkt); + + /* Pool is now empty */ + CU_ASSERT(odp_packet_alloc(pool, pkt_len) == ODP_PACKET_INVALID); + + for (i = 0; i < num_alloc; i++) + odp_packet_free(pkt_tbl[i]); + + CU_ASSERT(odp_pool_destroy(pool) == 0); + CU_ASSERT(odp_shm_free(shm) == 0); +} + static int pool_suite_init(void) { memset(&global_pool_capa, 0, sizeof(odp_pool_capability_t)); @@ -1136,6 +1645,39 @@ static int pool_suite_init(void) return 0; } +static int pool_ext_suite_init(void) +{ + memset(&global_pool_ext_capa, 0, sizeof(odp_pool_ext_capability_t)); + + if (odp_pool_ext_capability(ODP_POOL_PACKET, &global_pool_ext_capa)) { + printf("Pool ext capa failed in suite init\n"); + return -1; + } + + if (global_pool_ext_capa.type != ODP_POOL_PACKET) { + printf("Bad type from pool ext capa in suite init\n"); + return -1; + } + + return 0; +} + +static int check_pool_ext_support(void) +{ + if (global_pool_ext_capa.max_pools == 0) + return ODP_TEST_INACTIVE; + + return ODP_TEST_ACTIVE; +} + +static int check_pool_ext_segment_support(void) +{ + if (global_pool_ext_capa.max_pools == 0 || global_pool_ext_capa.pkt.max_segs_per_pkt < 2) + return ODP_TEST_INACTIVE; + + return ODP_TEST_ACTIVE; +} + odp_testinfo_t pool_suite[] = { ODP_TEST_INFO(pool_test_create_destroy_buffer), ODP_TEST_INFO(pool_test_create_destroy_packet), @@ -1175,11 +1717,29 @@ odp_testinfo_t pool_suite[] = { ODP_TEST_INFO_NULL, }; +odp_testinfo_t pool_ext_suite[] = { + ODP_TEST_INFO(test_packet_pool_ext_capa), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_param_init, check_pool_ext_support), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_create, check_pool_ext_support), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_lookup, check_pool_ext_support), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_info, check_pool_ext_support), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_populate, check_pool_ext_support), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_alloc, check_pool_ext_support), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_alloc_max, check_pool_ext_support), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_alloc_seg, check_pool_ext_segment_support), + ODP_TEST_INFO_CONDITIONAL(test_packet_pool_ext_disassemble, check_pool_ext_segment_support), + ODP_TEST_INFO_NULL, +}; + odp_suiteinfo_t pool_suites[] = { { .name = "Pool tests", .testinfo_tbl = pool_suite, .init_func = pool_suite_init, }, + { .name = "Ext mem pool tests", + .testinfo_tbl = pool_ext_suite, + .init_func = pool_ext_suite_init, + }, ODP_SUITE_INFO_NULL, }; diff --git a/test/validation/api/std/.gitignore b/test/validation/api/std/.gitignore new file mode 100644 index 000000000..51fbc1d95 --- /dev/null +++ b/test/validation/api/std/.gitignore @@ -0,0 +1 @@ +std_main diff --git a/test/validation/api/std/Makefile.am b/test/validation/api/std/Makefile.am new file mode 100644 index 000000000..7cebadb83 --- /dev/null +++ b/test/validation/api/std/Makefile.am @@ -0,0 +1,4 @@ +include ../Makefile.inc + +test_PROGRAMS = std_main +std_main_SOURCES = std.c diff --git a/test/validation/api/std_clib/std_clib.c b/test/validation/api/std/std.c index 35ad6f92b..56d05a4b4 100644 --- a/test/validation/api/std_clib/std_clib.c +++ b/test/validation/api/std/std.c @@ -11,7 +11,7 @@ #define PATTERN 0x5e -static void std_clib_test_memcpy(void) +static void std_test_memcpy(void) { uint8_t src[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; @@ -27,7 +27,7 @@ static void std_clib_test_memcpy(void) CU_ASSERT(ret == 0); } -static void std_clib_test_memset(void) +static void std_test_memset(void) { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; @@ -43,7 +43,7 @@ static void std_clib_test_memset(void) CU_ASSERT(ret == 0); } -static void std_clib_test_memcmp(void) +static void std_test_memcmp(void) { uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; @@ -80,15 +80,15 @@ static void std_clib_test_memcmp(void) } } -odp_testinfo_t std_clib_suite[] = { - ODP_TEST_INFO(std_clib_test_memcpy), - ODP_TEST_INFO(std_clib_test_memset), - ODP_TEST_INFO(std_clib_test_memcmp), +odp_testinfo_t std_suite[] = { + ODP_TEST_INFO(std_test_memcpy), + ODP_TEST_INFO(std_test_memset), + ODP_TEST_INFO(std_test_memcmp), ODP_TEST_INFO_NULL, }; -odp_suiteinfo_t std_clib_suites[] = { - {"Std C library", NULL, NULL, std_clib_suite}, +odp_suiteinfo_t std_suites[] = { + {"Std", NULL, NULL, std_suite}, ODP_SUITE_INFO_NULL }; @@ -100,7 +100,7 @@ int main(int argc, char *argv[]) if (odp_cunit_parse_options(argc, argv)) return -1; - ret = odp_cunit_register(std_clib_suites); + ret = odp_cunit_register(std_suites); if (ret == 0) ret = odp_cunit_run(); diff --git a/test/validation/api/std_clib/.gitignore b/test/validation/api/std_clib/.gitignore deleted file mode 100644 index 37828330a..000000000 --- a/test/validation/api/std_clib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -std_clib_main diff --git a/test/validation/api/std_clib/Makefile.am b/test/validation/api/std_clib/Makefile.am deleted file mode 100644 index 9d3b32d3f..000000000 --- a/test/validation/api/std_clib/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -include ../Makefile.inc - -test_PROGRAMS = std_clib_main -std_clib_main_SOURCES = std_clib.c diff --git a/test/validation/api/system/system.c b/test/validation/api/system/system.c index e511582dc..de49c3a5a 100644 --- a/test/validation/api/system/system.c +++ b/test/validation/api/system/system.c @@ -9,6 +9,7 @@ #include <odp/helper/odph_api.h> #include "odp_cunit_common.h" +#include "test_common_macros.h" #define PERIODS_100_MSEC 160 #define RES_TRY_NUM 10 @@ -20,9 +21,6 @@ /* 10 usec wait time assumes >100kHz resolution on CPU cycles counter */ #define WAIT_TIME (10 * ODP_TIME_USEC_IN_NS) -/* Check if value is power of two */ -#define IS_POW2(x) ((((x) - 1) & (x)) == 0) - static void test_version_api_str(void) { int char_ok = 0; @@ -252,8 +250,8 @@ static void system_test_odp_sys_cache_line_size(void) cache_size = odp_sys_cache_line_size(); CU_ASSERT(0 < cache_size); CU_ASSERT(0 < ODP_CACHE_LINE_SIZE); - CU_ASSERT(IS_POW2(cache_size)); - CU_ASSERT(IS_POW2(ODP_CACHE_LINE_SIZE)); + CU_ASSERT(TEST_CHECK_POW2(cache_size)); + CU_ASSERT(TEST_CHECK_POW2(ODP_CACHE_LINE_SIZE)); if (ODP_CACHE_LINE_SIZE != cache_size) printf("WARNING: ODP_CACHE_LINE_SIZE and odp_sys_cache_line_size() not matching\n"); diff --git a/test/validation/api/traffic_mngr/traffic_mngr.c b/test/validation/api/traffic_mngr/traffic_mngr.c index 55004692d..2ba0d1c9d 100644 --- a/test/validation/api/traffic_mngr/traffic_mngr.c +++ b/test/validation/api/traffic_mngr/traffic_mngr.c @@ -20,7 +20,6 @@ #define TM_DEBUG 0 -#define MAX_CAPABILITIES 16 #define MAX_NUM_IFACES 2 #define MAX_TM_SYSTEMS 3 #define NUM_LEVELS 3 @@ -386,35 +385,30 @@ static odp_bool_t approx_eq64(uint64_t val, uint64_t correct) static int test_overall_capabilities(void) { odp_tm_level_capabilities_t *per_level; - odp_tm_capabilities_t capabilities_array[MAX_CAPABILITIES]; + odp_tm_capabilities_t capabilities_array[2]; odp_tm_capabilities_t *cap_ptr; + odp_tm_egress_t egress; + odp_bool_t *prio_modes; uint32_t num_records, idx, num_levels, level; int rc; - rc = odp_tm_capabilities(capabilities_array, MAX_CAPABILITIES); - if (rc < 0) { - CU_ASSERT(rc < 0); - return -1; - } + odp_tm_egress_init(&egress); + egress.egress_kind = ODP_TM_EGRESS_PKT_IO; + egress.pktio = xmt_pktio; - /* Now test the return code (which did not indicate a failure code) - * to make sure that there is at least ONE capabilities record - * returned */ - if (rc == 0) { - CU_ASSERT(rc != 0); - return -1; - } + rc = odp_tm_egress_capabilities(&capabilities_array[0], &egress); + CU_ASSERT_FATAL(rc == 0); + num_records = 1; - /* Now test the return code to see if there were more capabilities - * records than the call above allowed for. This is not an error, - * just an interesting fact. - */ - num_records = MAX_CAPABILITIES; - if (MAX_CAPABILITIES < rc) - ODPH_DBG("There were more than %u capabilities (%u)\n", - MAX_CAPABILITIES, rc); - else - num_records = rc; + /* Get capabilities for egress kind function. */ + odp_tm_egress_init(&egress); + egress.egress_kind = ODP_TM_EGRESS_FN; + rc = odp_tm_egress_capabilities(&capabilities_array[1], &egress); + CU_ASSERT_FATAL(rc == 0); + + /* Validate this record only if egress function is supported */ + if (capabilities_array[1].max_tm_queues) + num_records++; /* Loop through the returned capabilities (there MUST be at least one) * and do some basic checks to prove that it isn't just an empty @@ -450,6 +444,11 @@ static int test_overall_capabilities(void) return -1; } } + + /* At least one pkt priority mode needs to be supported */ + prio_modes = cap_ptr->pkt_prio_modes; + CU_ASSERT((prio_modes[ODP_TM_PKT_PRIO_MODE_PRESERVE] != 0) || + (prio_modes[ODP_TM_PKT_PRIO_MODE_OVERWRITE] != 0)) } return 0; @@ -1098,6 +1097,44 @@ static int make_pkts(uint32_t num_pkts, return 0; } +static uint32_t send_pkts_multi(odp_tm_queue_t tm_queue, uint32_t num_pkts) +{ + xmt_pkt_desc_t *xmt_pkt_desc; + odp_packet_t odp_pkt; + uint32_t xmt_pkt_idx, pkts_sent; + int64_t rc, i = 0; + + /* Now send the pkts as fast as we can. RED drops are internally + * consumed by odp_tm_enq_multi(). + */ + xmt_pkt_idx = num_pkts_sent; + rc = odp_tm_enq_multi(tm_queue, &xmt_pkts[xmt_pkt_idx], num_pkts); + CU_ASSERT(rc <= num_pkts); + + /* Record consumed packets */ + pkts_sent = 0; + for (i = 0; i < rc; i++) { + xmt_pkt_desc = &xmt_pkt_descs[xmt_pkt_idx + i]; + xmt_pkt_desc->xmt_idx = xmt_pkt_idx + i; + xmt_pkt_desc->xmt_time = odp_time_local(); + xmt_pkt_desc->tm_queue = tm_queue; + pkts_sent++; + } + + /* Free rejected pkts */ + for (; i < num_pkts; i++) { + xmt_pkt_desc = &xmt_pkt_descs[xmt_pkt_idx + i]; + xmt_pkt_desc->xmt_idx = xmt_pkt_idx + i; + + odp_pkt = xmt_pkts[xmt_pkt_idx + i]; + odp_packet_free(odp_pkt); + xmt_pkts[xmt_pkt_idx + i] = ODP_PACKET_INVALID; + } + num_pkts_sent += num_pkts; + + return pkts_sent; +} + static uint32_t send_pkts(odp_tm_queue_t tm_queue, uint32_t num_pkts) { xmt_pkt_desc_t *xmt_pkt_desc; @@ -1341,6 +1378,7 @@ static int create_tm_queue(odp_tm_t odp_tm, queue_params.wred_profile[PKT_GREEN] = green_profile; queue_params.wred_profile[PKT_YELLOW] = yellow_profile; queue_params.wred_profile[PKT_RED] = red_profile; + queue_params.ordered_enqueue = true; } tm_queue = odp_tm_queue_create(odp_tm, &queue_params); @@ -1404,6 +1442,9 @@ static tm_node_desc_t *create_tm_node(odp_tm_t odp_tm, node_params.max_fanin = FANIN_RATIO; node_params.level = level; + /* This is ignored when pkt priority mode is not overwrite */ + node_params.priority = 0; + if (parent_node_desc == NULL) snprintf(node_name, sizeof(node_name), "node_%" PRIu32, node_idx + 1); @@ -1610,12 +1651,60 @@ static uint32_t find_child_queues(uint8_t tm_system_idx, return num_queues; } +static void +set_reqs_based_on_capas(odp_tm_requirements_t *req) +{ + odp_packet_color_t color; + int j; + + /* Use tm capabilities identified based on egress capabilities + * to see what can be enabled. + */ + if (tm_capabilities.ecn_marking_supported) + req->ecn_marking_needed = true; + if (tm_capabilities.drop_prec_marking_supported) + req->drop_prec_marking_needed = true; + if (tm_capabilities.tm_queue_wred_supported) + req->tm_queue_wred_needed = true; + if (tm_capabilities.tm_queue_dual_slope_supported) + req->tm_queue_dual_slope_needed = true; + if (tm_capabilities.vlan_marking_supported) + req->vlan_marking_needed = true; + if (tm_capabilities.tm_queue_threshold) + req->tm_queue_threshold_needed = true; + + for (j = 0; j < tm_capabilities.max_levels; j++) { + if (tm_capabilities.per_level[j].tm_node_threshold) + req->per_level[j].tm_node_threshold_needed = true; + } + + /* Mark colors as needed if at least one of the marking + * feature is needed. + * */ + if (req->ecn_marking_needed || req->drop_prec_marking_needed) { + for (color = 0; color < ODP_NUM_PACKET_COLORS; color++) + req->marking_colors_needed[color] = true; + } + + if (tm_capabilities.tm_queue_shaper_supported) + req->tm_queue_shaper_needed = true; + + /* We can use any packet priority mode since it does not affect + * our tests. Our scheduler test tests scheduling only in a node + * directly connected to TM queues and such nodes see the original + * packet priority before it could have been overwritten by any node. + */ + req->pkt_prio_mode = ODP_TM_PKT_PRIO_MODE_PRESERVE; + if (!tm_capabilities.pkt_prio_modes[ODP_TM_PKT_PRIO_MODE_PRESERVE]) + req->pkt_prio_mode = ODP_TM_PKT_PRIO_MODE_OVERWRITE; + +} + static int create_tm_system(void) { odp_tm_level_requirements_t *per_level; odp_tm_requirements_t requirements; odp_tm_egress_t egress; - odp_packet_color_t color; tm_node_desc_t *root_node_desc; uint32_t level, max_nodes[ODP_TM_MAX_LEVELS]; odp_tm_t odp_tm, found_odp_tm; @@ -1625,16 +1714,10 @@ static int create_tm_system(void) odp_tm_requirements_init(&requirements); odp_tm_egress_init(&egress); - requirements.max_tm_queues = NUM_TM_QUEUES + 1; + requirements.max_tm_queues = NUM_TM_QUEUES; requirements.num_levels = NUM_LEVELS; - requirements.tm_queue_shaper_needed = true; - requirements.tm_queue_wred_needed = true; - requirements.tm_queue_dual_slope_needed = true; - requirements.vlan_marking_needed = false; - requirements.ecn_marking_needed = true; - requirements.drop_prec_marking_needed = true; - for (color = 0; color < ODP_NUM_PACKET_COLORS; color++) - requirements.marking_colors_needed[color] = true; + + set_reqs_based_on_capas(&requirements); /* Set the max_num_tm_nodes to be double the expected number of nodes * at that level */ @@ -1662,10 +1745,8 @@ static int create_tm_system(void) snprintf(tm_name, sizeof(tm_name), "TM_system_%" PRIu32, num_odp_tm_systems); odp_tm = odp_tm_create(tm_name, &requirements, &egress); - if (odp_tm == ODP_TM_INVALID) { - ODPH_ERR("odp_tm_create() failed\n"); - return -1; - } + CU_ASSERT_FATAL(odp_tm != ODP_TM_INVALID); + odp_tm_systems[num_odp_tm_systems] = odp_tm; @@ -2105,9 +2186,10 @@ static int destroy_tm_systems(void) static int traffic_mngr_suite_init(void) { - odp_tm_capabilities_t capabilities_array[MAX_CAPABILITIES]; + odp_tm_capabilities_t egress_capa; uint32_t payload_len, copy_len; - int ret, i; + odp_tm_egress_t egress; + int j, ret; /* Initialize some global variables. */ num_pkts_made = 0; @@ -2156,27 +2238,58 @@ static int traffic_mngr_suite_init(void) if (ret > 0) goto skip_tests; - /* Fetch initial dynamic update capabilities, it will be updated - * later after TM system is created. - */ - ret = odp_tm_capabilities(capabilities_array, MAX_CAPABILITIES); - if (ret <= 0) - return -1; + odp_tm_egress_init(&egress); + egress.egress_kind = ODP_TM_EGRESS_PKT_IO; + egress.pktio = xmt_pktio; - for (i = 0; i < ret; i++) { - if (!capabilities_array[i].dynamic_shaper_update) - dynamic_shaper_update = false; + /* Get TM capabilities */ + ret = odp_tm_egress_capabilities(&egress_capa, &egress); + if (ret) { + ODPH_ERR("Failed to retrieve tm capabilities"); + return ret; + } - if (!capabilities_array[i].dynamic_sched_update) - dynamic_sched_update = false; + /* Check for sufficient TM queues */ + if (egress_capa.max_tm_queues < NUM_TM_QUEUES) + goto skip_tests; - if (!capabilities_array[i].dynamic_threshold_update) - dynamic_threshold_update = false; + /* Check for sufficient TM levels */ + if (egress_capa.max_levels < NUM_LEVELS) + goto skip_tests; - if (!capabilities_array[i].dynamic_wred_update) - dynamic_wred_update = false; + for (j = 0; j < NUM_LEVELS; j++) { + /* Per node fanin */ + if (egress_capa.per_level[j].max_fanin_per_node < + FANIN_RATIO) + break; } + if (j != NUM_LEVELS) + goto skip_tests; + + if (egress_capa.pkt_prio_modes[ODP_TM_PKT_PRIO_MODE_PRESERVE] && + egress_capa.max_schedulers_per_node < NUM_QUEUES_PER_NODE) + goto skip_tests; + + if (!egress_capa.pkt_prio_modes[ODP_TM_PKT_PRIO_MODE_PRESERVE] && + egress_capa.max_schedulers_per_node < 1) + goto skip_tests; + + /* Init tm capabilities with matching egress capa until tm is created */ + tm_capabilities = egress_capa; + + if (!tm_capabilities.dynamic_shaper_update) + dynamic_shaper_update = false; + + if (!tm_capabilities.dynamic_sched_update) + dynamic_sched_update = false; + + if (!tm_capabilities.dynamic_threshold_update) + dynamic_threshold_update = false; + + if (!tm_capabilities.dynamic_wred_update) + dynamic_wred_update = false; + return 0; skip_tests: /* Mark all tests as inactive under this suite */ @@ -2820,13 +2933,13 @@ static int test_sched_queue_priority(const char *shaper_name, /* Send the low priority dummy pkts first. The arrival order of * these pkts will be ignored. */ - pkts_sent = send_pkts(tm_queues[NUM_PRIORITIES - 1], 4); + pkts_sent = send_pkts_multi(tm_queues[NUM_PRIORITIES - 1], 4); /* Now send "num_pkts" first at the lowest priority, then "num_pkts" * at the second lowest priority, etc until "num_pkts" are sent last * at the highest priority. */ for (priority = NUM_PRIORITIES - 1; 0 <= priority; priority--) - pkts_sent += send_pkts(tm_queues[priority], num_pkts); + pkts_sent += send_pkts_multi(tm_queues[priority], num_pkts); busy_wait(100 * ODP_TIME_MSEC_IN_NS); @@ -4108,6 +4221,17 @@ static void traffic_mngr_test_scheduler(void) INCREASING_WEIGHTS) == 0); } +static int traffic_mngr_check_thresholds(void) +{ + /* Check only for tm queue threshold support as + * we only test queue threshold. + */ + if (!tm_capabilities.tm_queue_threshold) + return ODP_TEST_INACTIVE; + + return ODP_TEST_ACTIVE; +} + static void traffic_mngr_test_thresholds(void) { CU_ASSERT(test_threshold("thresh_A", "shaper_A", "node_1_2_1", 0, @@ -4116,14 +4240,86 @@ static void traffic_mngr_test_thresholds(void) 0, 6400) == 0); } -static void traffic_mngr_test_byte_wred(void) +static int traffic_mngr_check_queue_stats(void) { - if (!tm_capabilities.tm_queue_wred_supported) { - ODPH_DBG("\nwas not run because tm_capabilities indicates" - " no WRED support\n"); - return; - } + if (tm_capabilities.queue_stats.all_counters == 0) + return ODP_TEST_INACTIVE; + + return ODP_TEST_ACTIVE; +} +static void traffic_mngr_test_queue_stats(void) +{ + odp_tm_queue_stats_t stats_start, stats_stop; + odp_tm_queue_t tm_queue; + odp_tm_capabilities_t capa; + pkt_info_t pkt_info; + uint32_t pkts_sent; + uint32_t num_pkts = MIN(50, MAX_PKTS); + uint32_t pkt_len = 256; + + CU_ASSERT_FATAL(odp_tm_capability(odp_tm_systems[0], &capa) == 0); + + /* Reuse threshold test node */ + tm_queue = find_tm_queue(0, "node_1_2_1", 0); + CU_ASSERT_FATAL(tm_queue != ODP_TM_INVALID); + + init_xmt_pkts(&pkt_info); + pkt_info.drop_eligible = false; + pkt_info.pkt_class = 1; + CU_ASSERT_FATAL(make_pkts(num_pkts, pkt_len, &pkt_info) == 0); + + CU_ASSERT(odp_tm_queue_stats(tm_queue, &stats_start) == 0); + + pkts_sent = send_pkts(tm_queue, num_pkts); + + num_rcv_pkts = receive_pkts(odp_tm_systems[0], rcv_pktin, pkts_sent, + 1 * GBPS); + + CU_ASSERT(odp_tm_queue_stats(tm_queue, &stats_stop) == 0); + + if (capa.queue_stats.counter.packets) + CU_ASSERT(stats_stop.packets >= stats_start.packets + num_rcv_pkts); + if (capa.queue_stats.counter.octets) + CU_ASSERT(stats_stop.octets >= stats_start.octets + (num_rcv_pkts * pkt_len)); + CU_ASSERT((stats_stop.discards - stats_start.discards) == 0); + CU_ASSERT((stats_stop.discard_octets - stats_start.discard_octets) == 0); + CU_ASSERT((stats_stop.errors - stats_start.errors) == 0); + + printf("\nTM queue statistics\n-------------------\n"); + printf(" discards: %" PRIu64 "\n", stats_stop.discards); + printf(" discard octets: %" PRIu64 "\n", stats_stop.discard_octets); + printf(" errors: %" PRIu64 "\n", stats_stop.errors); + printf(" octets: %" PRIu64 "\n", stats_stop.octets); + printf(" packets: %" PRIu64 "\n", stats_stop.packets); + + /* Check that all unsupported counters are still zero */ + if (!capa.queue_stats.counter.discards) + CU_ASSERT(stats_stop.discards == 0); + if (!capa.queue_stats.counter.discard_octets) + CU_ASSERT(stats_stop.discard_octets == 0); + if (!capa.queue_stats.counter.errors) + CU_ASSERT(stats_stop.errors == 0); + if (!capa.queue_stats.counter.octets) + CU_ASSERT(stats_stop.octets == 0); + if (!capa.queue_stats.counter.packets) + CU_ASSERT(stats_stop.packets == 0); + + flush_leftover_pkts(odp_tm_systems[0], rcv_pktin); + CU_ASSERT(odp_tm_is_idle(odp_tm_systems[0])); +} + +static int traffic_mngr_check_wred(void) +{ + /* Check if wred is part of created odp_tm_t capabilities */ + if (!tm_capabilities.tm_queue_wred_supported) + return ODP_TEST_INACTIVE; + + return ODP_TEST_ACTIVE; +} + +static void traffic_mngr_test_byte_wred(void) +{ CU_ASSERT(test_byte_wred("byte_wred_30G", "byte_bw_30G", "byte_thresh_30G", "node_1_3_1", 1, ODP_PACKET_GREEN, TM_PERCENT(30), true) == 0); @@ -4143,12 +4339,6 @@ static void traffic_mngr_test_pkt_wred(void) { int rc; - if (!tm_capabilities.tm_queue_wred_supported) { - ODPH_DBG("\ntest_pkt_wred was not run because tm_capabilities " - "indicates no WRED support\n"); - return; - } - rc = test_pkt_wred("pkt_wred_40G", "pkt_bw_40G", "pkt_thresh_40G", "node_1_3_2", 1, ODP_PACKET_GREEN, TM_PERCENT(30), false); @@ -4180,59 +4370,75 @@ static void traffic_mngr_test_pkt_wred(void) CU_FAIL("70Y test failed\n"); } +static int traffic_mngr_check_query(void) +{ + uint32_t query_flags = (ODP_TM_QUERY_PKT_CNT | ODP_TM_QUERY_BYTE_CNT); + + /* We need both pkt count and byte count query support */ + if ((tm_capabilities.tm_queue_query_flags & query_flags) != query_flags) + return ODP_TEST_INACTIVE; + + return ODP_TEST_ACTIVE; +} + static void traffic_mngr_test_query(void) { CU_ASSERT(test_query_functions("query_shaper", "node_1_3_3", 3, 10) == 0); } -static void traffic_mngr_test_marking(void) +static int traffic_mngr_check_vlan_marking(void) { - odp_packet_color_t color; - odp_bool_t test_ecn, test_drop_prec; - int rc; + if (!tm_capabilities.vlan_marking_supported) + return ODP_TEST_INACTIVE; + return ODP_TEST_ACTIVE; +} - if (tm_capabilities.vlan_marking_supported) { - for (color = 0; color < ODP_NUM_PKT_COLORS; color++) { - rc = test_vlan_marking("node_1_3_1", color); - CU_ASSERT(rc == 0); - } - } else { - ODPH_DBG("\ntest_vlan_marking was not run because " - "tm_capabilities indicates no vlan marking support\n"); - } +static int traffic_mngr_check_ecn_marking(void) +{ + if (!tm_capabilities.ecn_marking_supported) + return ODP_TEST_INACTIVE; + return ODP_TEST_ACTIVE; +} - if (tm_capabilities.ecn_marking_supported) { - test_ecn = true; - test_drop_prec = false; +static int traffic_mngr_check_drop_prec_marking(void) +{ + if (!tm_capabilities.drop_prec_marking_supported) + return ODP_TEST_INACTIVE; + return ODP_TEST_ACTIVE; +} - rc = ip_marking_tests("node_1_3_2", test_ecn, test_drop_prec); - CU_ASSERT(rc == 0); - } else { - ODPH_DBG("\necn_marking tests were not run because " - "tm_capabilities indicates no ecn marking support\n"); - } +static int traffic_mngr_check_ecn_drop_prec_marking(void) +{ + if (!tm_capabilities.ecn_marking_supported || + !tm_capabilities.drop_prec_marking_supported) + return ODP_TEST_INACTIVE; + return ODP_TEST_ACTIVE; +} - if (tm_capabilities.drop_prec_marking_supported) { - test_ecn = false; - test_drop_prec = true; +static void traffic_mngr_test_vlan_marking(void) +{ + odp_packet_color_t color; - rc = ip_marking_tests("node_1_4_2", test_ecn, test_drop_prec); - CU_ASSERT(rc == 0); - } else { - ODPH_DBG("\ndrop_prec marking tests were not run because " - "tm_capabilities indicates no drop precedence " - "marking support\n"); + for (color = 0; color < ODP_NUM_PKT_COLORS; color++) { + /* Tree is 3 level */ + CU_ASSERT(test_vlan_marking("node_1_3_1", color) == 0); } +} - if (tm_capabilities.ecn_marking_supported && - tm_capabilities.drop_prec_marking_supported) { - test_ecn = true; - test_drop_prec = true; +static void traffic_mngr_test_ecn_marking(void) +{ + CU_ASSERT(ip_marking_tests("node_1_3_2", true, false) == 0); +} - rc = ip_marking_tests("node_1_4_2", test_ecn, test_drop_prec); - CU_ASSERT(rc == 0); - } +static void traffic_mngr_test_drop_prec_marking(void) +{ + CU_ASSERT(ip_marking_tests("node_1_4_2", false, true) == 0); +} + +static void traffic_mngr_test_ecn_drop_prec_marking(void) +{ + CU_ASSERT(ip_marking_tests("node_1_4_2", true, true) == 0); } static void traffic_mngr_test_fanin_info(void) @@ -4252,17 +4458,32 @@ odp_testinfo_t traffic_mngr_suite[] = { ODP_TEST_INFO(traffic_mngr_test_tm_create), ODP_TEST_INFO(traffic_mngr_test_shaper_profile), ODP_TEST_INFO(traffic_mngr_test_sched_profile), - ODP_TEST_INFO(traffic_mngr_test_threshold_profile), - ODP_TEST_INFO(traffic_mngr_test_wred_profile), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_threshold_profile, + traffic_mngr_check_thresholds), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_wred_profile, + traffic_mngr_check_wred), ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_shaper, traffic_mngr_check_shaper), ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_scheduler, traffic_mngr_check_scheduler), - ODP_TEST_INFO(traffic_mngr_test_thresholds), - ODP_TEST_INFO(traffic_mngr_test_byte_wred), - ODP_TEST_INFO(traffic_mngr_test_pkt_wred), - ODP_TEST_INFO(traffic_mngr_test_query), - ODP_TEST_INFO(traffic_mngr_test_marking), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_thresholds, + traffic_mngr_check_thresholds), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_byte_wred, + traffic_mngr_check_wred), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_pkt_wred, + traffic_mngr_check_wred), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_query, + traffic_mngr_check_query), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_queue_stats, + traffic_mngr_check_queue_stats), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_vlan_marking, + traffic_mngr_check_vlan_marking), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_ecn_marking, + traffic_mngr_check_ecn_marking), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_drop_prec_marking, + traffic_mngr_check_drop_prec_marking), + ODP_TEST_INFO_CONDITIONAL(traffic_mngr_test_ecn_drop_prec_marking, + traffic_mngr_check_ecn_drop_prec_marking), ODP_TEST_INFO(traffic_mngr_test_fanin_info), ODP_TEST_INFO(traffic_mngr_test_destroy), ODP_TEST_INFO_NULL, |