4 * Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <cmdline_parse.h>
40 #include <rte_string_fns.h>
45 #ifdef RTE_LIBRTE_PMAC
49 #include "test_pmac_pm.h"
56 struct rte_pm_param good_param = {
58 .socket_id = SOCKET_ID_ANY,
59 .max_pattern_num = 0x20000,
60 .max_pattern_len = 0x20000,
64 * this switches between clean (ASCII-only), mixed (those needing conversion
65 * from ASCII to binary) and P1 (a list of only 1 pattern, for use with P1
66 * algorithm) pattern sets. each pattern set is attempted to be tested with all
67 * algorithms, thus maximizing coverage.
78 #define BUFSIZE 0x1000000
80 #define OPT_CASE_SENSE 0x1
81 #define OPT_OUT_OF_ORDER 0x2
84 /* keep track of which algorithms were tested */
85 uint8_t tested_algorithms[RTE_PM_SEARCH_NUM];
87 /* pointer to an array with one of the test buffers from test_pmac_pm.h */
88 static struct pm_test_buffer * pm_test_buf;
89 /* length of the list (since we can't use sizeof on a pointer) */
90 int pm_test_buf_len = 0;
93 /* store pattern-match buffer */
95 pm_store(void *arg, const void *buf,
96 uint64_t offset, uint64_t size)
98 struct pm_store_buf * dst = (struct pm_store_buf *) arg;
99 if (size + offset > dst->len) {
100 printf("Line %i: Not enough space in PM store buffer!\n", __LINE__);
103 memcpy((char*) dst->buf + offset, buf, size);
108 /* load pattern-match buffer */
110 pm_load(void *arg, void *buf,
111 uint64_t offset, uint64_t size)
113 struct pm_store_buf * src = (struct pm_store_buf *) arg;
114 if (size + offset > src->len) {
115 printf("Line %i: Not enough space in PM load buffer!\n", __LINE__);
118 memcpy(buf, (char*) src->buf + offset, size);
124 * perform bulk search
126 * Due to the way bulk works, we can only look for <=1 results per buffer
129 bulk_search(struct rte_pm_ctx * pmx, struct rte_pm_build_opt * bopt)
131 struct rte_pm_match res[pm_test_buf_len];
132 struct rte_pm_inbuf in_buf[pm_test_buf_len];
135 int num_matches, total_matches;
137 if (pm_test_buf_len <= 0) {
138 printf("Line %i: Error at %s invalid value for "
139 "pm_test_buf_len: %d\n",
140 __LINE__, __func__, pm_test_buf_len);
144 memset(res, 0, sizeof(res));
145 memset(in_buf, 0, sizeof(in_buf));
147 /* prepare buffers */
148 for (i = 0; i < pm_test_buf_len; i++) {
150 /* prepare PM buffer */
151 len = strnlen(pm_test_buf[i].string, sizeof(pm_test_buf[i].string));
153 in_buf[i].buf = (const uint8_t*) pm_test_buf[i].string;
159 /* get number of total matches we're supposed to get */
160 /* we can only get up to 1 results because of bulk search */
161 if (bopt->case_sense) {
162 for (i = 0; i < pm_test_buf_len; i++)
163 num_matches += pm_test_buf[i].n_matches_with_case_sense > 0;
166 for (i = 0; i < pm_test_buf_len; i++)
167 num_matches += pm_test_buf[i].n_matches > 0;
170 /* run bulk search */
171 total_matches = rte_pm_search_bulk(pmx, in_buf, res, pm_test_buf_len);
173 /* check if we have a different number of total matches */
174 if (total_matches != num_matches) {
176 printf("Line %i: Error bulk matching (ret=%i num_matches=%i)!\n",
177 __LINE__, total_matches, num_matches);
180 /* cycle through each result and check first match, if any */
182 for (i = 0; i < pm_test_buf_len; i++) {
184 /* get supposed number of matches */
185 if (bopt->case_sense)
186 tmp = pm_test_buf[i].n_matches_with_case_sense > 0;
188 tmp = pm_test_buf[i].n_matches > 0;
190 /* check if we have a match when we shouldn't (and vice versa) */
191 if (((const char *)(uintptr_t)res[i].userdata !=
192 NULL) == (tmp == 0)) {
193 printf("Line %i: Should have %i matches!\n", __LINE__, tmp);
197 /* skip null results */
201 /* compare result string */
202 if ((const char*)(uintptr_t)res[i].userdata !=
203 pm_test_buf[i].matched_str[0]) {
205 printf("Line %i: Wrong match at bulk search %i!\n",
207 printf("Matched: %s\n",
208 (const char *)(uintptr_t)
210 printf("Should have matched: %s\n",
211 pm_test_buf[i].matched_str[0]);
220 * perform multiple searches on a split single buffer
223 split_buffer_search(struct rte_pm_ctx * pmx, struct rte_pm_build_opt * bopt)
225 /* works with any reasonable segment count */
227 struct rte_pm_match res_seg[NUM_SEG][MAX_MATCH_COUNT];
228 struct rte_pm_inbuf in_seg[NUM_SEG];
229 struct rte_pm_match * res;
230 struct rte_pm_state state;
232 int len, seg_len, total_len;
234 int cur_match, num_matches, total_matches = 0;
237 for (i = 0; i < pm_test_buf_len; i++) {
239 memset(res_seg, 0, sizeof(res_seg));
240 memset(&state, 0, sizeof(struct rte_pm_state));
242 /* prepare PM buffer */
243 len = strnlen(pm_test_buf[i].string, sizeof(pm_test_buf[i].string));
247 /* create segments out of one string */
248 for (n_seg = 0; n_seg < NUM_SEG; n_seg++) {
249 /* if last segment */
250 if (n_seg == NUM_SEG - 1)
251 seg_len = len - total_len;
253 seg_len = len / NUM_SEG;
254 in_seg[n_seg].len = seg_len;
256 (const uint8_t*) (pm_test_buf[i].string + total_len);
257 total_len += seg_len;
261 /* number of matches we are supposed to find */
262 if (bopt->case_sense)
263 num_matches = pm_test_buf[i].n_matches_with_case_sense;
265 num_matches = pm_test_buf[i].n_matches;
267 /* search in segments */
268 for (n_seg = 0; n_seg < NUM_SEG; n_seg++) {
269 /* if first segment */
271 total_matches = rte_pm_search_chain_start(pmx, &in_seg[n_seg],
272 res_seg[n_seg], MAX_MATCH_COUNT, &state);
274 total_matches += rte_pm_search_chain_next(pmx, &in_seg[n_seg],
275 res_seg[n_seg], MAX_MATCH_COUNT - total_matches,
279 if (total_matches != num_matches) {
281 printf("Line %i: Error matching %s%s (ret=%i num_matches=%i)!\n",
282 __LINE__, in_seg[0].buf, in_seg[1].buf, total_matches,
286 /* check if match was correct */
289 for (j = 0; j < MAX_MATCH_COUNT * NUM_SEG; j++) {
291 /* check if we have reached our maximum */
292 if (cur_match == num_matches || cur_match == MAX_MATCH_COUNT)
295 n_seg = j / MAX_MATCH_COUNT;
297 /* get current result pointer */
298 res = &res_seg[n_seg][j % MAX_MATCH_COUNT];
300 /* skip uninitialized results */
304 /* compare result string */
305 if ((const char*)(uintptr_t)res->userdata !=
306 pm_test_buf[i].matched_str[cur_match]) {
308 printf("Line %i: Wrong match at split buffer search %i!\n",
310 printf("Matched: %s\n",
311 (const char *)(uintptr_t)
313 printf("Should have matched: %s\n",
314 pm_test_buf[i].matched_str[cur_match]);
317 /* we got ourselves a match! */
327 * perform multiple searches on a single buffer
330 single_buffer_search(struct rte_pm_ctx * pmx, struct rte_pm_build_opt * bopt)
332 struct rte_pm_match res[MAX_MATCH_COUNT];
333 struct rte_pm_state state;
334 struct rte_pm_inbuf in_buf;
337 int match, num_matches, total_matches = 0;
339 /* look at same segment three times */
340 for (i = 0; i < pm_test_buf_len; i++) {
342 memset(&res, 0, sizeof(res));
343 memset(&state, 0, sizeof(struct rte_pm_state));
345 /* prepare PM buffer */
346 len = strnlen(pm_test_buf[i].string, sizeof(pm_test_buf[i].string));
348 in_buf.buf = (const uint8_t*) pm_test_buf[i].string;
351 /* number of matches we are supposed to find */
352 if (bopt->case_sense)
353 num_matches = pm_test_buf[i].n_matches_with_case_sense;
355 num_matches = pm_test_buf[i].n_matches;
357 /* run through a buffer multiple times, looking for 1 match */
358 for (j = 0; j < MAX_MATCH_COUNT; j++) {
359 /* start search chain */
361 total_matches = rte_pm_search_chain_start(pmx, &in_buf,
363 /* continue search */
365 total_matches += rte_pm_search_chain(pmx, &res[j], 1, &state);
368 if (total_matches != num_matches) {
370 printf("Line %i: Error matching %s (ret=%i num_matches=%i)!\n",
371 __LINE__, in_buf.buf, total_matches, num_matches);
374 /* check if match was correct */
376 for (match = 0; match < num_matches; match++) {
377 if ((const char*)(uintptr_t)
378 res[match].userdata !=
379 pm_test_buf[i].matched_str[match]) {
381 printf("Line %i: Wrong match at single buffer search %i!\n",
383 printf("Matched: %s\n",
384 (const char *)(uintptr_t)
385 res[match].userdata);
386 printf("Should have matched: %s\n",
387 pm_test_buf[i].matched_str[match]);
398 * perform basic searches
401 simple_search(struct rte_pm_ctx * pmx, struct rte_pm_build_opt * bopt)
403 struct rte_pm_match res[MAX_MATCH_COUNT];
404 struct rte_pm_state state;
405 struct rte_pm_inbuf in_buf;
408 int match, num_matches;
410 /* simple matching */
411 for (i = 0; i < pm_test_buf_len; i++) {
413 memset(&res, 0, sizeof(res));
414 memset(&state, 0, sizeof(struct rte_pm_state));
416 /* prepare PM buffer */
417 len = strnlen(pm_test_buf[i].string, sizeof(pm_test_buf[i].string));
419 in_buf.buf = (const uint8_t*) pm_test_buf[i].string;
422 /* number of matches we are supposed to find */
423 if (bopt->case_sense)
424 num_matches = pm_test_buf[i].n_matches_with_case_sense;
426 num_matches = pm_test_buf[i].n_matches;
428 ret = rte_pm_search_chain_start(pmx, &in_buf, res,
429 MAX_MATCH_COUNT, &state);
431 if (ret != num_matches) {
433 printf("Line %i: Error matching %s (ret=%i num_matches=%i)!\n",
434 __LINE__, in_buf.buf, ret, num_matches);
437 /* check if match was correct */
439 for (match = 0; match < num_matches; match++) {
440 if ((const char *)(uintptr_t)
441 res[match].userdata !=
442 pm_test_buf[i].matched_str[match]) {
444 printf("Line %i: Wrong match at simple search %i!\n",
446 printf("Matched: %s\n",
447 (const char *)(uintptr_t)
448 res[match].userdata);
449 printf("Should have matched: %s\n",
450 pm_test_buf[i].matched_str[match]);
461 * build PM context and call search function
464 build_and_search(struct rte_pm_ctx * pmx,
465 struct rte_pm_search_avail * avail,
466 struct rte_pm_build_opt * bopt, enum pattern_set p_set)
468 struct rte_pm_param param;
469 struct rte_pm_ctx * pmx2;
470 struct pm_store_buf buffer;
471 enum rte_pm_search search_type;
474 /* allocate load/store buffer */
475 if ((buffer.buf = malloc(BUFSIZE)) == NULL) {
476 printf("%s at line %i: failed to allocate load/store buffer!\n",
480 buffer.len = BUFSIZE;
482 /* prepare data for second context */
483 memcpy(¶m, &good_param, sizeof(param));
486 /* cycle through all search algorithms */
487 for (search_type = RTE_PM_SEARCH_UNDEF; search_type < RTE_PM_SEARCH_NUM;
490 /* skip unavailable search types, but include RTE_PM_SEARCH_UNDEF
491 * as it should work */
492 if (search_type == RTE_PM_SEARCH_UNDEF ||
493 RTE_PM_GET_BIT(avail->avail, search_type) > 0) {
495 /* make a note that we tested this algorithm */
496 tested_algorithms[search_type] = 1;
499 bopt->search_type = search_type;
501 ret = rte_pm_build(pmx, bopt);
502 if (ret == -ENOTSUP) {
503 printf("Line %i: Algorightm %s not supported.\n",
504 __LINE__, rte_pm_search_names[search_type]);
508 printf("Line %i: PM build for algorithm %s failed! "
510 __LINE__, rte_pm_search_names[search_type], ret);
514 /* select which buffer list to process */
518 pm_test_buf = clean_buffers;
519 pm_test_buf_len = DIM(clean_buffers);
522 pm_test_buf = mixed_buffers;
523 pm_test_buf_len = DIM(mixed_buffers);
526 pm_test_buf = P1_buffers;
527 pm_test_buf_len = DIM(P1_buffers);
534 if (simple_search(pmx, bopt) < 0)
536 if (single_buffer_search(pmx, bopt) < 0)
538 if (split_buffer_search(pmx, bopt) < 0)
540 if (bulk_search(pmx, bopt) < 0)
543 /* create second context and load it with data from pmx */
544 pmx2 = rte_pm_create(¶m);
546 printf("Line %i: Creating second context failed!\n", __LINE__);
550 /* clear load/store buffer, store pmx data and load into pmx2 */
551 memset(buffer.buf, 0, BUFSIZE);
553 ret = rte_pm_store(pmx, pm_store, &buffer);
555 printf("Line %i: PM store failed!\n", __LINE__);
559 ret = rte_pm_load(pmx2, pm_load, &buffer);
561 printf("Line %i: PM load failed!\n", __LINE__);
565 /* do searches for pmx2 */
566 if (simple_search(pmx2, bopt) < 0)
568 if (single_buffer_search(pmx2, bopt) < 0)
570 if (split_buffer_search(pmx2, bopt) < 0)
572 if (bulk_search(pmx2, bopt) < 0)
575 /* free second context */
580 /* free load/store buffer */
591 /* add patterns to PM context */
593 add_patterns(struct rte_pm_ctx * pmx, enum pattern_set p_set)
596 struct rte_pm_pattern * pat = NULL;
598 /* only needed when converting strings */
599 uint8_t tmp_str[DIM(mixed_patterns)][MAX_PATTERN_LEN];
605 /* allocate space for patterns */
606 pat = malloc(sizeof(struct rte_pm_pattern) * DIM(clean_patterns));
609 printf("Line %i: Allocating space for patterns failed!\n",
614 for (i = 0; i < (int) DIM(clean_patterns); i++) {
615 pat[i].pattern = (const uint8_t *) clean_patterns[i];
616 pat[i].userdata = (uintptr_t) clean_patterns[i];
617 pat[i].len = strnlen(clean_patterns[i],
618 sizeof(clean_patterns[i]));
621 ret = rte_pm_add_patterns(pmx, pat, DIM(clean_patterns));
624 printf("Line %i: PM pattern add failed! Return code: %i\n",
636 pat = malloc(sizeof(struct rte_pm_pattern) * DIM(mixed_patterns));
637 memset(tmp_str, 0, sizeof(tmp_str));
640 printf("Line %i: Allocating space for patterns failed!\n",
647 for (i = 0; i < (int) DIM(mixed_patterns); i++) {
649 ret = rte_pm_convert_pattern(mixed_patterns[i],
650 tmp_str[i], MAX_PATTERN_LEN);
653 printf("Line %i: Converting pattern failed!\n", __LINE__);
657 pat[i].pattern = tmp_str[i];
658 /* we assign original string here so that later comparison
661 pat[i].userdata = (uintptr_t) mixed_patterns[i];
662 pat[i].len = strnlen((const char*) tmp_str[i], MAX_PATTERN_LEN);
665 ret = rte_pm_add_patterns(pmx, pat, DIM(mixed_patterns));
668 printf("Line %i: PM pattern add failed! Return code: %i\n",
678 pat = malloc(sizeof(struct rte_pm_pattern) * DIM(P1_patterns));
681 printf("Line %i: Allocating space for patterns failed!\n",
686 for (i = 0; i < (int) DIM(P1_patterns); i++) {
687 pat[i].pattern = (const uint8_t *) P1_patterns[i];
688 pat[i].userdata = (uintptr_t) P1_patterns[i];
689 pat[i].len = strnlen(P1_patterns[i], sizeof(P1_patterns[i]));
692 ret = rte_pm_add_patterns(pmx, pat, 1);
695 printf("Line %i: PM pattern add failed! Return code: %i\n",
704 printf("Line %i: Unknown pattern type\n", __LINE__);
711 * this function is in no way a replacement for
712 * proper in-depth unit tests (those are available
713 * as a separate application). this is just a quick
714 * sanity test to check basic functionality.
717 test_search_patterns(void)
719 struct rte_pm_ctx * pmx;
720 struct rte_pm_search_avail avail;
721 struct rte_pm_build_opt bopt;
724 /* bitmask to configure build options */
725 uint8_t options_bm = 0;
726 /* pattern set to use for tests */
727 enum pattern_set p_set;
729 /* reset the tested algorithms array */
730 memset(tested_algorithms, 0, sizeof(tested_algorithms));
732 /* two possible options: case sense and OOO */
733 for (options_bm = 0; options_bm < (1 << NUM_OPTS); options_bm++) {
735 bopt.search_type = RTE_PM_SEARCH_UNDEF;
737 /* configure options according to bitmask */
738 bopt.case_sense = !!(options_bm & OPT_CASE_SENSE);
739 bopt.out_of_order = !!(options_bm & OPT_OUT_OF_ORDER);
741 for (p_set = PAT_CLEAN; p_set < PAT_NUM; p_set++) {
743 /* create new PM context */
744 pmx = rte_pm_create(&good_param);
746 printf("Line %i: Failed to create PM context!\n", __LINE__);
750 /* add patterns to context */
751 ret = add_patterns(pmx, p_set);
755 ret = rte_pm_analyze(pmx, &bopt, &avail);
757 printf("Line %i: PM analyze failed! Return code: %i\n",
762 ret = build_and_search(pmx, &avail, &bopt, p_set);
773 * check if all algorithms were attempted
776 /* skip nil algorithm */
777 for (i = 1; i < RTE_PM_SEARCH_NUM; i++) {
778 if (tested_algorithms[i] == 0) {
779 printf("Line %i: Algorithm %s was not tested!\n",
780 __LINE__, rte_pm_search_names[i]);
793 * Test creating and finding PM contexts, and adding patterns
796 test_create_find_add(void)
798 struct rte_pm_param param;
799 struct rte_pm_ctx * pmx, *pmx2, *tmp;
800 struct rte_pm_pattern pat[LEN];
801 const char * pmx_name = "pmx";
802 const char * pmx2_name = "pmx2";
805 /* create two contexts */
806 memcpy(¶m, &good_param, sizeof(param));
807 param.max_pattern_len = 8;
808 param.max_pattern_num = 2;
810 param.name = pmx_name;
811 pmx = rte_pm_create(¶m);
813 printf("Line %i: Error creating %s!\n", __LINE__, pmx_name);
817 param.name = pmx2_name;
818 pmx2 = rte_pm_create(¶m);
819 if (pmx2 == NULL || pmx2 == pmx) {
820 printf("Line %i: Error creating %s!\n", __LINE__, pmx2_name);
825 /* try to create third one, with an existing name */
826 param.name = pmx_name;
827 tmp = rte_pm_create(¶m);
829 printf("Line %i: Creating context with existing name test failed!\n",
836 param.name = pmx2_name;
837 tmp = rte_pm_create(¶m);
839 printf("Line %i: Creating context with existing name test 2 failed!\n",
846 /* try to find existing PM contexts */
847 tmp = rte_pm_find_existing(pmx_name);
849 printf("Line %i: Finding %s failed!\n", __LINE__, pmx_name);
855 tmp = rte_pm_find_existing(pmx2_name);
857 printf("Line %i: Finding %s failed!\n", __LINE__, pmx2_name);
863 /* try to find non-existing context */
864 tmp = rte_pm_find_existing("invalid");
866 printf("Line %i: Non-existent PM context found!\n", __LINE__);
873 /* create valid (but severely limited) pmx */
874 memcpy(¶m, &good_param, sizeof(param));
875 param.max_pattern_num = LEN;
877 pmx = rte_pm_create(¶m);
879 printf("Line %i: Error creating %s!\n", __LINE__, param.name);
883 /* create dummy patterns */
884 for (i = 0; i < LEN; i++) {
887 pat[i].pattern = (const uint8_t*)"1234";
890 /* try filling up the context */
891 ret = rte_pm_add_patterns(pmx, pat, LEN);
893 printf("Line %i: Adding %i patterns to PM context failed!\n",
898 /* try adding to a (supposedly) full context */
899 ret = rte_pm_add_patterns(pmx, pat, 1);
901 printf("Line %i: Adding patterns to full PM context "
902 "should have failed!\n", __LINE__);
908 /* create another valid (but severely limited) pmx */
909 memcpy(¶m, &good_param, sizeof(param));
910 param.max_pattern_len = LEN * 4;
912 pmx = rte_pm_create(¶m);
914 printf("Line %i: Error creating %s!\n", __LINE__, param.name);
918 /* create dummy patterns */
919 for (i = 0; i < LEN; i++) {
922 pat[i].pattern = (const uint8_t*)"1234";
925 /* try filling up the context */
926 ret = rte_pm_add_patterns(pmx, pat, LEN);
928 printf("Line %i: Adding %i patterns to PM context failed!\n",
933 /* try adding to a (supposedly) full context */
934 ret = rte_pm_add_patterns(pmx, pat, 1);
936 printf("Line %i: Adding patterns to full PM context "
937 "should have failed!\n", __LINE__);
952 * test serialization functions.
954 * - passing invalid parameters to function
955 * - trying to load invalid pm store
956 * - save buffer, load buffer, save another, and compare them
957 * - try to load/save with a too small buffer (pm_store/pm_load should fail)
962 struct rte_pm_ctx * pmx, * pmx2;
963 struct rte_pm_build_opt build_opt;
964 struct rte_pm_pattern pat[LEN];
966 struct pm_store_buf buffer, buffer2;
968 memset(&buffer, 0, sizeof (buffer));
969 memset(&buffer2, 0, sizeof (buffer2));
971 /* allocate two load/store buffers */
972 if ((buffer.buf = malloc(BUFSIZE)) == NULL ||
973 (buffer2.buf = malloc(BUFSIZE)) == NULL) {
974 printf("Line %i: Creating load/store buffers failed!\n",
981 buffer.len = BUFSIZE;
982 memset(buffer.buf, 0, BUFSIZE);
984 buffer2.len = BUFSIZE;
985 memset(buffer2.buf, 0, BUFSIZE);
987 /* create a context */
988 pmx = rte_pm_create(&good_param);
990 printf("Line %i: Creating pmx failed!\n", __LINE__);
994 /* create dummy patterns */
995 for (i = 0; i < LEN; i++) {
998 pat[i].pattern = (const uint8_t*)"1234";
1001 /* fill context with patterns */
1002 res = rte_pm_add_patterns(pmx, pat, LEN);
1004 printf("Line %i: Adding patterns to PM context failed!\n", __LINE__);
1008 build_opt.search_type = RTE_PM_SEARCH_UNDEF;
1010 /* build the patterns */
1011 res = rte_pm_build(pmx, &build_opt);
1013 printf("Line %i: Building PM context failed!\n", __LINE__);
1018 * test serialize functions
1020 res = rte_pm_store(NULL, pm_store, &buffer);
1021 if (res != -EINVAL) {
1022 printf("Line %i: PM store should have failed!\n", __LINE__);
1026 res = rte_pm_store(pmx, NULL, &buffer);
1027 if (res != -EINVAL) {
1028 printf("Line %i: PM store should have failed!\n", __LINE__);
1032 res = rte_pm_store(pmx, pm_store, NULL);
1033 if (res != -EINVAL) {
1034 printf("Line %i: PM store should have failed!\n", __LINE__);
1039 res = rte_pm_load(NULL, pm_load, &buffer);
1040 if (res != -EINVAL) {
1041 printf("Line %i: PM load should have failed!\n", __LINE__);
1045 res = rte_pm_load(pmx, NULL, &buffer);
1046 if (res != -EINVAL) {
1047 printf("Line %i: PM load should have failed!\n", __LINE__);
1051 res = rte_pm_load(pmx, pm_load, NULL);
1052 if (res != -EINVAL) {
1053 printf("Line %i: PM load should have failed!\n", __LINE__);
1057 /* since buffer is currently zeroed out, load should complain about
1058 * unsupported format*/
1059 res = rte_pm_load(pmx, pm_load, &buffer);
1060 if (res != -EINVAL) {
1061 printf("Line %i: PM load should have failed!\n", __LINE__);
1065 /* rte_pm_load zeroed out the context, so re-add all patterns, rebuild,
1066 * save the context to buffer and free context
1070 /* create a context */
1071 pmx = rte_pm_create(&good_param);
1073 printf("Line %i: Creating pmx failed!\n", __LINE__);
1077 res = rte_pm_add_patterns(pmx, pat, LEN);
1079 printf("Line %i: Adding patterns to PM context failed!\n", __LINE__);
1083 res = rte_pm_build(pmx, &build_opt);
1085 printf("Line %i: Building PM context failed!\n", __LINE__);
1089 res = rte_pm_store(pmx, pm_store, &buffer);
1091 printf("Line %i: PM store failed!\n", __LINE__);
1101 pmx2 = rte_pm_create(&good_param);
1103 printf("Line %i: Creating pmx2 failed!\n", __LINE__);
1107 /* load buffer into pmx2 */
1108 res = rte_pm_load(pmx2, pm_load, &buffer);
1110 printf("Line %i: PM load failed!\n", __LINE__);
1114 /* save pmx2 into another buffer */
1115 res = rte_pm_store(pmx2, pm_store, &buffer2);
1117 printf("Line %i: PM store failed!\n", __LINE__);
1121 /* compare two buffers */
1122 if (memcmp(buffer.buf, buffer2.buf, BUFSIZE) != 0) {
1123 printf("Line %i: Buffers are different!\n", __LINE__);
1127 /* try and save pmx2 into a too small buffer */
1129 res = rte_pm_store(pmx2, pm_store, &buffer2);
1130 if (res != -ENOMEM) {
1131 printf("Line %i: PM store should have failed!\n", __LINE__);
1135 /* try and load from a too small buffer */
1136 res = rte_pm_load(pmx2, pm_load, &buffer2);
1137 if (res != -ENOMEM) {
1138 printf("Line %i: PM load should have failed!\n", __LINE__);
1142 /* free everything */
1159 * test functions by passing invalid or
1160 * non-workable parameters.
1162 * we do NOT test pattern search functions here
1163 * because those are performance-critical and
1164 * thus don't do any parameter checking.
1167 test_invalid_parameters(void)
1169 struct rte_pm_param param;
1170 struct rte_pm_ctx * pmx;
1171 enum rte_pm_search search_result;
1173 /* needed for rte_pm_convert_pattern */
1175 uint8_t out_buf[LEN];
1176 /* needed for rte_pm_add_patterns */
1177 struct rte_pm_pattern pat;
1178 /* needed for rte_pm_analyze */
1179 struct rte_pm_search_avail build_res[LEN];
1180 /* needed for rte_pm_build */
1181 struct rte_pm_build_opt build_opt;
1189 pmx = rte_pm_create(NULL);
1191 printf("Line %i: PM context creation with NULL param "
1192 "should have failed!\n", __LINE__);
1197 /* zero pattern len */
1198 memcpy(¶m, &good_param, sizeof(param));
1199 param.max_pattern_len = 0;
1201 pmx = rte_pm_create(¶m);
1203 printf("Line %i: PM context creation with zero pattern len failed!\n",
1210 /* zero pattern num */
1211 memcpy(¶m, &good_param, sizeof(param));
1212 param.max_pattern_num = 0;
1214 pmx = rte_pm_create(¶m);
1216 printf("Line %i: PM context creation with zero pattern num failed!\n",
1223 /* invalid NUMA node */
1224 memcpy(¶m, &good_param, sizeof(param));
1225 param.socket_id = RTE_MAX_NUMA_NODES + 1;
1227 pmx = rte_pm_create(¶m);
1229 printf("Line %i: PM context creation with invalid NUMA "
1230 "should have failed!\n", __LINE__);
1236 memcpy(¶m, &good_param, sizeof(param));
1239 pmx = rte_pm_create(¶m);
1241 printf("Line %i: PM context creation with NULL name "
1242 "should have failed!\n", __LINE__);
1248 * rte_pm_search_type_by_name()
1251 /* invalid algorithm names */
1252 search_result = rte_pm_search_type_by_name("invalid");
1253 if (search_result != RTE_PM_SEARCH_UNDEF) {
1254 printf("Line %i: Found invalid PM algorithm!\n", __LINE__);
1257 search_result = rte_pm_search_type_by_name(NULL);
1258 if (search_result != RTE_PM_SEARCH_UNDEF) {
1259 printf("Line %i: Found NULL PM algorithm!\n", __LINE__);
1263 * rte_pm_convert_pattern()
1266 /* null in buffer */
1267 res = rte_pm_convert_pattern(NULL, out_buf, sizeof(out_buf));
1268 if (res != (-EINVAL)) {
1269 printf("Line %i: Converting a NULL input pattern "
1270 "should have failed!\n", __LINE__);
1274 /* null out buffer */
1275 res = rte_pm_convert_pattern(in_buf, NULL, sizeof(out_buf));
1276 if (res != (-EINVAL)) {
1277 printf("Line %i: Converting to NULL output buffer "
1278 "should have failed!\n", __LINE__);
1282 /* zero length (should throw -ENOMEM) */
1283 res = rte_pm_convert_pattern(in_buf, out_buf, 0);
1284 if (res != -(ENOMEM)) {
1285 printf("Line %i: Converting to a 0-length output buffer "
1286 "should have failed!\n", __LINE__);
1290 /* wrong binary value */
1291 res = rte_pm_convert_pattern("|1", out_buf, sizeof(out_buf));
1292 if (res != (-EINVAL)) {
1293 printf("Line %i: Converting malformed binary "
1294 "should have failed!\n", __LINE__);
1298 /* wrong binary value */
1299 res = rte_pm_convert_pattern("|P1|", out_buf, sizeof(out_buf));
1300 if (res != (-EINVAL)) {
1301 printf("Line %i: Converting malformed binary "
1302 "should have failed!\n", __LINE__);
1306 /* wrong binary value */
1307 res = rte_pm_convert_pattern("|FFF|", out_buf, sizeof(out_buf));
1308 if (res != (-EINVAL)) {
1309 printf("Line %i: Converting malformed binary "
1310 "should have failed!\n", __LINE__);
1315 * rte_pm_add_patterns()
1317 /* create valid pmx since we'll need it for tests */
1318 memcpy(¶m, &good_param, sizeof(param));
1320 param.max_pattern_len = 2;
1322 pmx = rte_pm_create(¶m);
1324 printf("Line %i: Creating pmx failed!\n", __LINE__);
1329 res = rte_pm_add_patterns(NULL, &pat, LEN);
1330 if (res != -EINVAL) {
1331 printf("Line %i: Adding patterns to NULL PM context "
1332 "should have failed!\n", __LINE__);
1337 res = rte_pm_add_patterns(pmx, NULL, LEN);
1338 if (res != -EINVAL) {
1339 printf("Line %i: Adding patterns to NULL pattern "
1340 "should have failed!\n", __LINE__);
1346 /* zero len (should succeed) */
1347 res = rte_pm_add_patterns(pmx, &pat, 0);
1349 printf("Line %i: Adding 0 patterns to PM context failed!\n", __LINE__);
1359 res = rte_pm_analyze(NULL, &build_opt, build_res);
1360 if (res != -EINVAL) {
1361 printf("Line %i: PM analyze on NULL pmx "
1362 "should have failed!\n", __LINE__);
1368 res = rte_pm_analyze(pmx, NULL, build_res);
1369 if (res != -EINVAL) {
1370 printf("Line %i: PM analyze on NULL opt "
1371 "should have failed!\n", __LINE__);
1377 res = rte_pm_analyze(pmx, &build_opt, NULL);
1378 if (res != -EINVAL) {
1379 printf("Line %i: PM analyze on NULL res should have failed!\n",
1390 res = rte_pm_build(NULL, &build_opt);
1391 if (res != -EINVAL) {
1392 printf("Line %i: PM build on NULL pmx should have failed!\n",
1399 res = rte_pm_build(pmx, NULL);
1400 if (res != -EINVAL) {
1401 printf("Line %i: PM build on NULL opt should have failed!\n", __LINE__);
1406 /* build with unsuitable algorithm */
1407 build_opt.case_sense = 0;
1408 build_opt.out_of_order = 0;
1409 /* MB expects out_of_order */
1410 build_opt.search_type = RTE_PM_SEARCH_AC2_L1x4_MB;
1412 res = rte_pm_build(pmx, &build_opt);
1413 if (res != -EINVAL) {
1414 printf("Line %i: PM build on NULL opt should have failed! %i\n",
1424 * make sure void functions don't crash with NULL parameters
1436 * Various tests that don't test much but improve coverage
1441 struct rte_pm_build_opt build_opt;
1442 struct rte_pm_pattern pat;
1443 struct rte_pm_ctx * pmx;
1444 enum rte_pm_search search_result;
1445 char buf[MAX_PATTERN_LEN];
1450 /* search for existing PM algorithm */
1451 search_result = rte_pm_search_type_by_name("AC2_L1x4");
1452 if (search_result != RTE_PM_SEARCH_AC2_L1x4) {
1453 printf("Line %i: Wrong PM algorithm found!\n", __LINE__);
1456 pmx = rte_pm_create(&good_param);
1458 printf("Line %i: Failed to create PM context!\n", __LINE__);
1462 /* convert a pattern and add it to context */
1463 ret = rte_pm_convert_pattern("|01 02 03 04| readable", (uint8_t*) buf,
1467 printf("Line %i: Converting binary failed!\n", __LINE__);
1471 /* add pattern to context */
1472 pat.len = (uint32_t) ret;
1473 pat.pattern = (const uint8_t *) buf;
1476 ret = rte_pm_add_patterns(pmx, &pat, 1);
1479 printf("Line %i: Adding pattern failed!\n", __LINE__);
1483 /* convert another pattern and add it to context */
1484 ret = rte_pm_convert_pattern("pattern", (uint8_t*) buf, 4);
1488 printf("Line %i: Converting pattern failed!\n", __LINE__);
1492 /* add pattern to context */
1493 pat.len = (uint32_t) ret;
1494 pat.pattern = (const uint8_t *) buf;
1497 ret = rte_pm_add_patterns(pmx, &pat, 1);
1500 printf("Line %i: Adding pattern failed!\n", __LINE__);
1504 build_opt.case_sense = 0;
1505 build_opt.out_of_order = 0;
1506 build_opt.search_type = RTE_PM_SEARCH_AC2_L1x4;
1508 ret = rte_pm_build(pmx, &build_opt);
1511 printf("Line %i: Building PM failed!\n", __LINE__);
1515 /* dump context with patterns - useful for coverage */
1528 if (test_invalid_parameters() < 0)
1530 if (test_serialize() < 0)
1532 if (test_create_find_add() < 0)
1534 if (test_search_patterns() < 0)
1536 if (test_misc() < 0)
1541 #else /* RTE_LIBRTE_PMAC=n */
1546 printf("This binary was not compiled with PMAC support!\n");
1550 #endif /* RTE_LIBRTE_PMAC */