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.
37 #include <cmdline_parse.h>
39 #include <rte_string_fns.h>
44 #ifdef RTE_LIBRTE_PMAC
48 #include "test_pmac_pm.h"
55 struct rte_pm_param good_param = {
57 .socket_id = SOCKET_ID_ANY,
58 .max_pattern_num = 0x20000,
59 .max_pattern_len = 0x20000,
63 * this switches between clean (ASCII-only), mixed (those needing conversion
64 * from ASCII to binary) and P1 (a list of only 1 pattern, for use with P1
65 * algorithm) pattern sets. each pattern set is attempted to be tested with all
66 * algorithms, thus maximizing coverage.
77 #define BUFSIZE 0x1000000
79 #define OPT_CASE_SENSE 0x1
80 #define OPT_OUT_OF_ORDER 0x2
83 /* keep track of which algorithms were tested */
84 uint8_t tested_algorithms[RTE_PM_SEARCH_NUM];
86 /* pointer to an array with one of the test buffers from test_pmac_pm.h */
87 static struct pm_test_buffer * pm_test_buf;
88 /* length of the list (since we can't use sizeof on a pointer) */
89 int pm_test_buf_len = 0;
92 /* store pattern-match buffer */
94 pm_store(void *arg, const void *buf,
95 uint64_t offset, uint64_t size)
97 struct pm_store_buf * dst = (struct pm_store_buf *) arg;
98 if (size + offset > dst->len) {
99 printf("Line %i: Not enough space in PM store buffer!\n", __LINE__);
102 memcpy((char*) dst->buf + offset, buf, size);
107 /* load pattern-match buffer */
109 pm_load(void *arg, void *buf,
110 uint64_t offset, uint64_t size)
112 struct pm_store_buf * src = (struct pm_store_buf *) arg;
113 if (size + offset > src->len) {
114 printf("Line %i: Not enough space in PM load buffer!\n", __LINE__);
117 memcpy(buf, (char*) src->buf + offset, size);
123 * perform bulk search
125 * Due to the way bulk works, we can only look for <=1 results per buffer
128 bulk_search(struct rte_pm_ctx * pmx, struct rte_pm_build_opt * bopt)
130 struct rte_pm_match res[pm_test_buf_len];
131 struct rte_pm_inbuf in_buf[pm_test_buf_len];
134 int num_matches, total_matches;
136 if (pm_test_buf_len <= 0) {
137 printf("Line %i: Error at %s invalid value for "
138 "pm_test_buf_len: %d\n",
139 __LINE__, __func__, pm_test_buf_len);
143 memset(res, 0, sizeof(res));
144 memset(in_buf, 0, sizeof(in_buf));
146 /* prepare buffers */
147 for (i = 0; i < pm_test_buf_len; i++) {
149 /* prepare PM buffer */
150 len = strnlen(pm_test_buf[i].string, sizeof(pm_test_buf[i].string));
152 in_buf[i].buf = (const uint8_t*) pm_test_buf[i].string;
158 /* get number of total matches we're supposed to get */
159 /* we can only get up to 1 results because of bulk search */
160 if (bopt->case_sense) {
161 for (i = 0; i < pm_test_buf_len; i++)
162 num_matches += pm_test_buf[i].n_matches_with_case_sense > 0;
165 for (i = 0; i < pm_test_buf_len; i++)
166 num_matches += pm_test_buf[i].n_matches > 0;
169 /* run bulk search */
170 total_matches = rte_pm_search_bulk(pmx, in_buf, res, pm_test_buf_len);
172 /* check if we have a different number of total matches */
173 if (total_matches != num_matches) {
175 printf("Line %i: Error bulk matching (ret=%i num_matches=%i)!\n",
176 __LINE__, total_matches, num_matches);
179 /* cycle through each result and check first match, if any */
181 for (i = 0; i < pm_test_buf_len; i++) {
183 /* get supposed number of matches */
184 if (bopt->case_sense)
185 tmp = pm_test_buf[i].n_matches_with_case_sense > 0;
187 tmp = pm_test_buf[i].n_matches > 0;
189 /* check if we have a match when we shouldn't (and vice versa) */
190 if (((const char *)(uintptr_t)res[i].userdata !=
191 NULL) == (tmp == 0)) {
192 printf("Line %i: Should have %i matches!\n", __LINE__, tmp);
196 /* skip null results */
200 /* compare result string */
201 if ((const char*)(uintptr_t)res[i].userdata !=
202 pm_test_buf[i].matched_str[0]) {
204 printf("Line %i: Wrong match at bulk search %i!\n",
206 printf("Matched: %s\n",
207 (const char *)(uintptr_t)
209 printf("Should have matched: %s\n",
210 pm_test_buf[i].matched_str[0]);
219 * perform multiple searches on a split single buffer
222 split_buffer_search(struct rte_pm_ctx * pmx, struct rte_pm_build_opt * bopt)
224 /* works with any reasonable segment count */
226 struct rte_pm_match res_seg[NUM_SEG][MAX_MATCH_COUNT];
227 struct rte_pm_inbuf in_seg[NUM_SEG];
228 struct rte_pm_match * res;
229 struct rte_pm_state state;
231 int len, seg_len, total_len;
233 int cur_match, num_matches, total_matches = 0;
236 for (i = 0; i < pm_test_buf_len; i++) {
238 memset(res_seg, 0, sizeof(res_seg));
239 memset(&state, 0, sizeof(struct rte_pm_state));
241 /* prepare PM buffer */
242 len = strnlen(pm_test_buf[i].string, sizeof(pm_test_buf[i].string));
246 /* create segments out of one string */
247 for (n_seg = 0; n_seg < NUM_SEG; n_seg++) {
248 /* if last segment */
249 if (n_seg == NUM_SEG - 1)
250 seg_len = len - total_len;
252 seg_len = len / NUM_SEG;
253 in_seg[n_seg].len = seg_len;
255 (const uint8_t*) (pm_test_buf[i].string + total_len);
256 total_len += seg_len;
260 /* number of matches we are supposed to find */
261 if (bopt->case_sense)
262 num_matches = pm_test_buf[i].n_matches_with_case_sense;
264 num_matches = pm_test_buf[i].n_matches;
266 /* search in segments */
267 for (n_seg = 0; n_seg < NUM_SEG; n_seg++) {
268 /* if first segment */
270 total_matches = rte_pm_search_chain_start(pmx, &in_seg[n_seg],
271 res_seg[n_seg], MAX_MATCH_COUNT, &state);
273 total_matches += rte_pm_search_chain_next(pmx, &in_seg[n_seg],
274 res_seg[n_seg], MAX_MATCH_COUNT - total_matches,
278 if (total_matches != num_matches) {
280 printf("Line %i: Error matching %s%s (ret=%i num_matches=%i)!\n",
281 __LINE__, in_seg[0].buf, in_seg[1].buf, total_matches,
285 /* check if match was correct */
288 for (j = 0; j < MAX_MATCH_COUNT * NUM_SEG; j++) {
290 /* check if we have reached our maximum */
291 if (cur_match == num_matches || cur_match == MAX_MATCH_COUNT)
294 n_seg = j / MAX_MATCH_COUNT;
296 /* get current result pointer */
297 res = &res_seg[n_seg][j % MAX_MATCH_COUNT];
299 /* skip uninitialized results */
303 /* compare result string */
304 if ((const char*)(uintptr_t)res->userdata !=
305 pm_test_buf[i].matched_str[cur_match]) {
307 printf("Line %i: Wrong match at split buffer search %i!\n",
309 printf("Matched: %s\n",
310 (const char *)(uintptr_t)
312 printf("Should have matched: %s\n",
313 pm_test_buf[i].matched_str[cur_match]);
316 /* we got ourselves a match! */
326 * perform multiple searches on a single buffer
329 single_buffer_search(struct rte_pm_ctx * pmx, struct rte_pm_build_opt * bopt)
331 struct rte_pm_match res[MAX_MATCH_COUNT];
332 struct rte_pm_state state;
333 struct rte_pm_inbuf in_buf;
336 int match, num_matches, total_matches = 0;
338 /* look at same segment three times */
339 for (i = 0; i < pm_test_buf_len; i++) {
341 memset(&res, 0, sizeof(res));
342 memset(&state, 0, sizeof(struct rte_pm_state));
344 /* prepare PM buffer */
345 len = strnlen(pm_test_buf[i].string, sizeof(pm_test_buf[i].string));
347 in_buf.buf = (const uint8_t*) pm_test_buf[i].string;
350 /* number of matches we are supposed to find */
351 if (bopt->case_sense)
352 num_matches = pm_test_buf[i].n_matches_with_case_sense;
354 num_matches = pm_test_buf[i].n_matches;
356 /* run through a buffer multiple times, looking for 1 match */
357 for (j = 0; j < MAX_MATCH_COUNT; j++) {
358 /* start search chain */
360 total_matches = rte_pm_search_chain_start(pmx, &in_buf,
362 /* continue search */
364 total_matches += rte_pm_search_chain(pmx, &res[j], 1, &state);
367 if (total_matches != num_matches) {
369 printf("Line %i: Error matching %s (ret=%i num_matches=%i)!\n",
370 __LINE__, in_buf.buf, total_matches, num_matches);
373 /* check if match was correct */
375 for (match = 0; match < num_matches; match++) {
376 if ((const char*)(uintptr_t)
377 res[match].userdata !=
378 pm_test_buf[i].matched_str[match]) {
380 printf("Line %i: Wrong match at single buffer search %i!\n",
382 printf("Matched: %s\n",
383 (const char *)(uintptr_t)
384 res[match].userdata);
385 printf("Should have matched: %s\n",
386 pm_test_buf[i].matched_str[match]);
397 * perform basic searches
400 simple_search(struct rte_pm_ctx * pmx, struct rte_pm_build_opt * bopt)
402 struct rte_pm_match res[MAX_MATCH_COUNT];
403 struct rte_pm_state state;
404 struct rte_pm_inbuf in_buf;
407 int match, num_matches;
409 /* simple matching */
410 for (i = 0; i < pm_test_buf_len; i++) {
412 memset(&res, 0, sizeof(res));
413 memset(&state, 0, sizeof(struct rte_pm_state));
415 /* prepare PM buffer */
416 len = strnlen(pm_test_buf[i].string, sizeof(pm_test_buf[i].string));
418 in_buf.buf = (const uint8_t*) pm_test_buf[i].string;
421 /* number of matches we are supposed to find */
422 if (bopt->case_sense)
423 num_matches = pm_test_buf[i].n_matches_with_case_sense;
425 num_matches = pm_test_buf[i].n_matches;
427 ret = rte_pm_search_chain_start(pmx, &in_buf, res,
428 MAX_MATCH_COUNT, &state);
430 if (ret != num_matches) {
432 printf("Line %i: Error matching %s (ret=%i num_matches=%i)!\n",
433 __LINE__, in_buf.buf, ret, num_matches);
436 /* check if match was correct */
438 for (match = 0; match < num_matches; match++) {
439 if ((const char *)(uintptr_t)
440 res[match].userdata !=
441 pm_test_buf[i].matched_str[match]) {
443 printf("Line %i: Wrong match at simple search %i!\n",
445 printf("Matched: %s\n",
446 (const char *)(uintptr_t)
447 res[match].userdata);
448 printf("Should have matched: %s\n",
449 pm_test_buf[i].matched_str[match]);
460 * build PM context and call search function
463 build_and_search(struct rte_pm_ctx * pmx,
464 struct rte_pm_search_avail * avail,
465 struct rte_pm_build_opt * bopt, enum pattern_set p_set)
467 struct rte_pm_param param;
468 struct rte_pm_ctx * pmx2;
469 struct pm_store_buf buffer;
470 enum rte_pm_search search_type;
473 /* allocate load/store buffer */
474 if ((buffer.buf = malloc(BUFSIZE)) == NULL) {
475 printf("%s at line %i: failed to allocate load/store buffer!\n",
479 buffer.len = BUFSIZE;
481 /* prepare data for second context */
482 memcpy(¶m, &good_param, sizeof(param));
485 /* cycle through all search algorithms */
486 for (search_type = RTE_PM_SEARCH_UNDEF; search_type < RTE_PM_SEARCH_NUM;
489 /* skip unavailable search types, but include RTE_PM_SEARCH_UNDEF
490 * as it should work */
491 if (search_type == RTE_PM_SEARCH_UNDEF ||
492 RTE_PM_GET_BIT(avail->avail, search_type) > 0) {
494 /* make a note that we tested this algorithm */
495 tested_algorithms[search_type] = 1;
498 bopt->search_type = search_type;
500 ret = rte_pm_build(pmx, bopt);
501 if (ret == -ENOTSUP) {
502 printf("Line %i: Algorightm %s not supported.\n",
503 __LINE__, rte_pm_search_names[search_type]);
507 printf("Line %i: PM build for algorithm %s failed! "
509 __LINE__, rte_pm_search_names[search_type], ret);
513 /* select which buffer list to process */
517 pm_test_buf = clean_buffers;
518 pm_test_buf_len = DIM(clean_buffers);
521 pm_test_buf = mixed_buffers;
522 pm_test_buf_len = DIM(mixed_buffers);
525 pm_test_buf = P1_buffers;
526 pm_test_buf_len = DIM(P1_buffers);
533 if (simple_search(pmx, bopt) < 0)
535 if (single_buffer_search(pmx, bopt) < 0)
537 if (split_buffer_search(pmx, bopt) < 0)
539 if (bulk_search(pmx, bopt) < 0)
542 /* create second context and load it with data from pmx */
543 pmx2 = rte_pm_create(¶m);
545 printf("Line %i: Creating second context failed!\n", __LINE__);
549 /* clear load/store buffer, store pmx data and load into pmx2 */
550 memset(buffer.buf, 0, BUFSIZE);
552 ret = rte_pm_store(pmx, pm_store, &buffer);
554 printf("Line %i: PM store failed!\n", __LINE__);
558 ret = rte_pm_load(pmx2, pm_load, &buffer);
560 printf("Line %i: PM load failed!\n", __LINE__);
564 /* do searches for pmx2 */
565 if (simple_search(pmx2, bopt) < 0)
567 if (single_buffer_search(pmx2, bopt) < 0)
569 if (split_buffer_search(pmx2, bopt) < 0)
571 if (bulk_search(pmx2, bopt) < 0)
574 /* free second context */
579 /* free load/store buffer */
590 /* add patterns to PM context */
592 add_patterns(struct rte_pm_ctx * pmx, enum pattern_set p_set)
595 struct rte_pm_pattern * pat = NULL;
597 /* only needed when converting strings */
598 uint8_t tmp_str[DIM(mixed_patterns)][MAX_PATTERN_LEN];
604 /* allocate space for patterns */
605 pat = malloc(sizeof(struct rte_pm_pattern) * DIM(clean_patterns));
608 printf("Line %i: Allocating space for patterns failed!\n",
613 for (i = 0; i < (int) DIM(clean_patterns); i++) {
614 pat[i].pattern = (const uint8_t *) clean_patterns[i];
615 pat[i].userdata = (uintptr_t) clean_patterns[i];
616 pat[i].len = strnlen(clean_patterns[i],
617 sizeof(clean_patterns[i]));
620 ret = rte_pm_add_patterns(pmx, pat, DIM(clean_patterns));
623 printf("Line %i: PM pattern add failed! Return code: %i\n",
635 pat = malloc(sizeof(struct rte_pm_pattern) * DIM(mixed_patterns));
636 memset(tmp_str, 0, sizeof(tmp_str));
639 printf("Line %i: Allocating space for patterns failed!\n",
646 for (i = 0; i < (int) DIM(mixed_patterns); i++) {
648 ret = rte_pm_convert_pattern(mixed_patterns[i],
649 tmp_str[i], MAX_PATTERN_LEN);
652 printf("Line %i: Converting pattern failed!\n", __LINE__);
656 pat[i].pattern = tmp_str[i];
657 /* we assign original string here so that later comparison
660 pat[i].userdata = (uintptr_t) mixed_patterns[i];
661 pat[i].len = strnlen((const char*) tmp_str[i], MAX_PATTERN_LEN);
664 ret = rte_pm_add_patterns(pmx, pat, DIM(mixed_patterns));
667 printf("Line %i: PM pattern add failed! Return code: %i\n",
677 pat = malloc(sizeof(struct rte_pm_pattern) * DIM(P1_patterns));
680 printf("Line %i: Allocating space for patterns failed!\n",
685 for (i = 0; i < (int) DIM(P1_patterns); i++) {
686 pat[i].pattern = (const uint8_t *) P1_patterns[i];
687 pat[i].userdata = (uintptr_t) P1_patterns[i];
688 pat[i].len = strnlen(P1_patterns[i], sizeof(P1_patterns[i]));
691 ret = rte_pm_add_patterns(pmx, pat, 1);
694 printf("Line %i: PM pattern add failed! Return code: %i\n",
703 printf("Line %i: Unknown pattern type\n", __LINE__);
710 * this function is in no way a replacement for
711 * proper in-depth unit tests (those are available
712 * as a separate application). this is just a quick
713 * sanity test to check basic functionality.
716 test_search_patterns(void)
718 struct rte_pm_ctx * pmx;
719 struct rte_pm_search_avail avail;
720 struct rte_pm_build_opt bopt;
723 /* bitmask to configure build options */
724 uint8_t options_bm = 0;
725 /* pattern set to use for tests */
726 enum pattern_set p_set;
728 /* reset the tested algorithms array */
729 memset(tested_algorithms, 0, sizeof(tested_algorithms));
731 /* two possible options: case sense and OOO */
732 for (options_bm = 0; options_bm < (1 << NUM_OPTS); options_bm++) {
734 bopt.search_type = RTE_PM_SEARCH_UNDEF;
736 /* configure options according to bitmask */
737 bopt.case_sense = !!(options_bm & OPT_CASE_SENSE);
738 bopt.out_of_order = !!(options_bm & OPT_OUT_OF_ORDER);
740 for (p_set = PAT_CLEAN; p_set < PAT_NUM; p_set++) {
742 /* create new PM context */
743 pmx = rte_pm_create(&good_param);
745 printf("Line %i: Failed to create PM context!\n", __LINE__);
749 /* add patterns to context */
750 ret = add_patterns(pmx, p_set);
754 ret = rte_pm_analyze(pmx, &bopt, &avail);
756 printf("Line %i: PM analyze failed! Return code: %i\n",
761 ret = build_and_search(pmx, &avail, &bopt, p_set);
772 * check if all algorithms were attempted
775 /* skip nil algorithm */
776 for (i = 1; i < RTE_PM_SEARCH_NUM; i++) {
777 if (tested_algorithms[i] == 0) {
778 printf("Line %i: Algorithm %s was not tested!\n",
779 __LINE__, rte_pm_search_names[i]);
792 * Test creating and finding PM contexts, and adding patterns
795 test_create_find_add(void)
797 struct rte_pm_param param;
798 struct rte_pm_ctx * pmx, *pmx2, *tmp;
799 struct rte_pm_pattern pat[LEN];
800 const char * pmx_name = "pmx";
801 const char * pmx2_name = "pmx2";
804 /* create two contexts */
805 memcpy(¶m, &good_param, sizeof(param));
806 param.max_pattern_len = 8;
807 param.max_pattern_num = 2;
809 param.name = pmx_name;
810 pmx = rte_pm_create(¶m);
812 printf("Line %i: Error creating %s!\n", __LINE__, pmx_name);
816 param.name = pmx2_name;
817 pmx2 = rte_pm_create(¶m);
818 if (pmx2 == NULL || pmx2 == pmx) {
819 printf("Line %i: Error creating %s!\n", __LINE__, pmx2_name);
824 /* try to create third one, with an existing name */
825 param.name = pmx_name;
826 tmp = rte_pm_create(¶m);
828 printf("Line %i: Creating context with existing name test failed!\n",
835 param.name = pmx2_name;
836 tmp = rte_pm_create(¶m);
838 printf("Line %i: Creating context with existing name test 2 failed!\n",
845 /* try to find existing PM contexts */
846 tmp = rte_pm_find_existing(pmx_name);
848 printf("Line %i: Finding %s failed!\n", __LINE__, pmx_name);
854 tmp = rte_pm_find_existing(pmx2_name);
856 printf("Line %i: Finding %s failed!\n", __LINE__, pmx2_name);
862 /* try to find non-existing context */
863 tmp = rte_pm_find_existing("invalid");
865 printf("Line %i: Non-existent PM context found!\n", __LINE__);
872 /* create valid (but severely limited) pmx */
873 memcpy(¶m, &good_param, sizeof(param));
874 param.max_pattern_num = LEN;
876 pmx = rte_pm_create(¶m);
878 printf("Line %i: Error creating %s!\n", __LINE__, param.name);
882 /* create dummy patterns */
883 for (i = 0; i < LEN; i++) {
886 pat[i].pattern = (const uint8_t*)"1234";
889 /* try filling up the context */
890 ret = rte_pm_add_patterns(pmx, pat, LEN);
892 printf("Line %i: Adding %i patterns to PM context failed!\n",
897 /* try adding to a (supposedly) full context */
898 ret = rte_pm_add_patterns(pmx, pat, 1);
900 printf("Line %i: Adding patterns to full PM context "
901 "should have failed!\n", __LINE__);
907 /* create another valid (but severely limited) pmx */
908 memcpy(¶m, &good_param, sizeof(param));
909 param.max_pattern_len = LEN * 4;
911 pmx = rte_pm_create(¶m);
913 printf("Line %i: Error creating %s!\n", __LINE__, param.name);
917 /* create dummy patterns */
918 for (i = 0; i < LEN; i++) {
921 pat[i].pattern = (const uint8_t*)"1234";
924 /* try filling up the context */
925 ret = rte_pm_add_patterns(pmx, pat, LEN);
927 printf("Line %i: Adding %i patterns to PM context failed!\n",
932 /* try adding to a (supposedly) full context */
933 ret = rte_pm_add_patterns(pmx, pat, 1);
935 printf("Line %i: Adding patterns to full PM context "
936 "should have failed!\n", __LINE__);
951 * test serialization functions.
953 * - passing invalid parameters to function
954 * - trying to load invalid pm store
955 * - save buffer, load buffer, save another, and compare them
956 * - try to load/save with a too small buffer (pm_store/pm_load should fail)
961 struct rte_pm_ctx * pmx, * pmx2;
962 struct rte_pm_build_opt build_opt;
963 struct rte_pm_pattern pat[LEN];
965 struct pm_store_buf buffer, buffer2;
967 memset(&buffer, 0, sizeof (buffer));
968 memset(&buffer2, 0, sizeof (buffer2));
970 /* allocate two load/store buffers */
971 if ((buffer.buf = malloc(BUFSIZE)) == NULL ||
972 (buffer2.buf = malloc(BUFSIZE)) == NULL) {
973 printf("Line %i: Creating load/store buffers failed!\n",
980 buffer.len = BUFSIZE;
981 memset(buffer.buf, 0, BUFSIZE);
983 buffer2.len = BUFSIZE;
984 memset(buffer2.buf, 0, BUFSIZE);
986 /* create a context */
987 pmx = rte_pm_create(&good_param);
989 printf("Line %i: Creating pmx failed!\n", __LINE__);
993 /* create dummy patterns */
994 for (i = 0; i < LEN; i++) {
997 pat[i].pattern = (const uint8_t*)"1234";
1000 /* fill context with patterns */
1001 res = rte_pm_add_patterns(pmx, pat, LEN);
1003 printf("Line %i: Adding patterns to PM context failed!\n", __LINE__);
1007 build_opt.search_type = RTE_PM_SEARCH_UNDEF;
1009 /* build the patterns */
1010 res = rte_pm_build(pmx, &build_opt);
1012 printf("Line %i: Building PM context failed!\n", __LINE__);
1017 * test serialize functions
1019 res = rte_pm_store(NULL, pm_store, &buffer);
1020 if (res != -EINVAL) {
1021 printf("Line %i: PM store should have failed!\n", __LINE__);
1025 res = rte_pm_store(pmx, NULL, &buffer);
1026 if (res != -EINVAL) {
1027 printf("Line %i: PM store should have failed!\n", __LINE__);
1031 res = rte_pm_store(pmx, pm_store, NULL);
1032 if (res != -EINVAL) {
1033 printf("Line %i: PM store should have failed!\n", __LINE__);
1038 res = rte_pm_load(NULL, pm_load, &buffer);
1039 if (res != -EINVAL) {
1040 printf("Line %i: PM load should have failed!\n", __LINE__);
1044 res = rte_pm_load(pmx, NULL, &buffer);
1045 if (res != -EINVAL) {
1046 printf("Line %i: PM load should have failed!\n", __LINE__);
1050 res = rte_pm_load(pmx, pm_load, NULL);
1051 if (res != -EINVAL) {
1052 printf("Line %i: PM load should have failed!\n", __LINE__);
1056 /* since buffer is currently zeroed out, load should complain about
1057 * unsupported format*/
1058 res = rte_pm_load(pmx, pm_load, &buffer);
1059 if (res != -EINVAL) {
1060 printf("Line %i: PM load should have failed!\n", __LINE__);
1064 /* rte_pm_load zeroed out the context, so re-add all patterns, rebuild,
1065 * save the context to buffer and free context
1069 /* create a context */
1070 pmx = rte_pm_create(&good_param);
1072 printf("Line %i: Creating pmx failed!\n", __LINE__);
1076 res = rte_pm_add_patterns(pmx, pat, LEN);
1078 printf("Line %i: Adding patterns to PM context failed!\n", __LINE__);
1082 res = rte_pm_build(pmx, &build_opt);
1084 printf("Line %i: Building PM context failed!\n", __LINE__);
1088 res = rte_pm_store(pmx, pm_store, &buffer);
1090 printf("Line %i: PM store failed!\n", __LINE__);
1100 pmx2 = rte_pm_create(&good_param);
1102 printf("Line %i: Creating pmx2 failed!\n", __LINE__);
1106 /* load buffer into pmx2 */
1107 res = rte_pm_load(pmx2, pm_load, &buffer);
1109 printf("Line %i: PM load failed!\n", __LINE__);
1113 /* save pmx2 into another buffer */
1114 res = rte_pm_store(pmx2, pm_store, &buffer2);
1116 printf("Line %i: PM store failed!\n", __LINE__);
1120 /* compare two buffers */
1121 if (memcmp(buffer.buf, buffer2.buf, BUFSIZE) != 0) {
1122 printf("Line %i: Buffers are different!\n", __LINE__);
1126 /* try and save pmx2 into a too small buffer */
1128 res = rte_pm_store(pmx2, pm_store, &buffer2);
1129 if (res != -ENOMEM) {
1130 printf("Line %i: PM store should have failed!\n", __LINE__);
1134 /* try and load from a too small buffer */
1135 res = rte_pm_load(pmx2, pm_load, &buffer2);
1136 if (res != -ENOMEM) {
1137 printf("Line %i: PM load should have failed!\n", __LINE__);
1141 /* free everything */
1158 * test functions by passing invalid or
1159 * non-workable parameters.
1161 * we do NOT test pattern search functions here
1162 * because those are performance-critical and
1163 * thus don't do any parameter checking.
1166 test_invalid_parameters(void)
1168 struct rte_pm_param param;
1169 struct rte_pm_ctx * pmx;
1170 enum rte_pm_search search_result;
1172 /* needed for rte_pm_convert_pattern */
1174 uint8_t out_buf[LEN];
1175 /* needed for rte_pm_add_patterns */
1176 struct rte_pm_pattern pat;
1177 /* needed for rte_pm_analyze */
1178 struct rte_pm_search_avail build_res[LEN];
1179 /* needed for rte_pm_build */
1180 struct rte_pm_build_opt build_opt;
1188 pmx = rte_pm_create(NULL);
1190 printf("Line %i: PM context creation with NULL param "
1191 "should have failed!\n", __LINE__);
1196 /* zero pattern len */
1197 memcpy(¶m, &good_param, sizeof(param));
1198 param.max_pattern_len = 0;
1200 pmx = rte_pm_create(¶m);
1202 printf("Line %i: PM context creation with zero pattern len failed!\n",
1209 /* zero pattern num */
1210 memcpy(¶m, &good_param, sizeof(param));
1211 param.max_pattern_num = 0;
1213 pmx = rte_pm_create(¶m);
1215 printf("Line %i: PM context creation with zero pattern num failed!\n",
1222 /* invalid NUMA node */
1223 memcpy(¶m, &good_param, sizeof(param));
1224 param.socket_id = RTE_MAX_NUMA_NODES + 1;
1226 pmx = rte_pm_create(¶m);
1228 printf("Line %i: PM context creation with invalid NUMA "
1229 "should have failed!\n", __LINE__);
1235 memcpy(¶m, &good_param, sizeof(param));
1238 pmx = rte_pm_create(¶m);
1240 printf("Line %i: PM context creation with NULL name "
1241 "should have failed!\n", __LINE__);
1247 * rte_pm_search_type_by_name()
1250 /* invalid algorithm names */
1251 search_result = rte_pm_search_type_by_name("invalid");
1252 if (search_result != RTE_PM_SEARCH_UNDEF) {
1253 printf("Line %i: Found invalid PM algorithm!\n", __LINE__);
1256 search_result = rte_pm_search_type_by_name(NULL);
1257 if (search_result != RTE_PM_SEARCH_UNDEF) {
1258 printf("Line %i: Found NULL PM algorithm!\n", __LINE__);
1262 * rte_pm_convert_pattern()
1265 /* null in buffer */
1266 res = rte_pm_convert_pattern(NULL, out_buf, sizeof(out_buf));
1267 if (res != (-EINVAL)) {
1268 printf("Line %i: Converting a NULL input pattern "
1269 "should have failed!\n", __LINE__);
1273 /* null out buffer */
1274 res = rte_pm_convert_pattern(in_buf, NULL, sizeof(out_buf));
1275 if (res != (-EINVAL)) {
1276 printf("Line %i: Converting to NULL output buffer "
1277 "should have failed!\n", __LINE__);
1281 /* zero length (should throw -ENOMEM) */
1282 res = rte_pm_convert_pattern(in_buf, out_buf, 0);
1283 if (res != -(ENOMEM)) {
1284 printf("Line %i: Converting to a 0-length output buffer "
1285 "should have failed!\n", __LINE__);
1289 /* wrong binary value */
1290 res = rte_pm_convert_pattern("|1", out_buf, sizeof(out_buf));
1291 if (res != (-EINVAL)) {
1292 printf("Line %i: Converting malformed binary "
1293 "should have failed!\n", __LINE__);
1297 /* wrong binary value */
1298 res = rte_pm_convert_pattern("|P1|", out_buf, sizeof(out_buf));
1299 if (res != (-EINVAL)) {
1300 printf("Line %i: Converting malformed binary "
1301 "should have failed!\n", __LINE__);
1305 /* wrong binary value */
1306 res = rte_pm_convert_pattern("|FFF|", out_buf, sizeof(out_buf));
1307 if (res != (-EINVAL)) {
1308 printf("Line %i: Converting malformed binary "
1309 "should have failed!\n", __LINE__);
1314 * rte_pm_add_patterns()
1316 /* create valid pmx since we'll need it for tests */
1317 memcpy(¶m, &good_param, sizeof(param));
1319 param.max_pattern_len = 2;
1321 pmx = rte_pm_create(¶m);
1323 printf("Line %i: Creating pmx failed!\n", __LINE__);
1328 res = rte_pm_add_patterns(NULL, &pat, LEN);
1329 if (res != -EINVAL) {
1330 printf("Line %i: Adding patterns to NULL PM context "
1331 "should have failed!\n", __LINE__);
1336 res = rte_pm_add_patterns(pmx, NULL, LEN);
1337 if (res != -EINVAL) {
1338 printf("Line %i: Adding patterns to NULL pattern "
1339 "should have failed!\n", __LINE__);
1345 /* zero len (should succeed) */
1346 res = rte_pm_add_patterns(pmx, &pat, 0);
1348 printf("Line %i: Adding 0 patterns to PM context failed!\n", __LINE__);
1358 res = rte_pm_analyze(NULL, &build_opt, build_res);
1359 if (res != -EINVAL) {
1360 printf("Line %i: PM analyze on NULL pmx "
1361 "should have failed!\n", __LINE__);
1367 res = rte_pm_analyze(pmx, NULL, build_res);
1368 if (res != -EINVAL) {
1369 printf("Line %i: PM analyze on NULL opt "
1370 "should have failed!\n", __LINE__);
1376 res = rte_pm_analyze(pmx, &build_opt, NULL);
1377 if (res != -EINVAL) {
1378 printf("Line %i: PM analyze on NULL res should have failed!\n",
1389 res = rte_pm_build(NULL, &build_opt);
1390 if (res != -EINVAL) {
1391 printf("Line %i: PM build on NULL pmx should have failed!\n",
1398 res = rte_pm_build(pmx, NULL);
1399 if (res != -EINVAL) {
1400 printf("Line %i: PM build on NULL opt should have failed!\n", __LINE__);
1405 /* build with unsuitable algorithm */
1406 build_opt.case_sense = 0;
1407 build_opt.out_of_order = 0;
1408 /* MB expects out_of_order */
1409 build_opt.search_type = RTE_PM_SEARCH_AC2_L1x4_MB;
1411 res = rte_pm_build(pmx, &build_opt);
1412 if (res != -EINVAL) {
1413 printf("Line %i: PM build on NULL opt should have failed! %i\n",
1423 * make sure void functions don't crash with NULL parameters
1435 * Various tests that don't test much but improve coverage
1440 struct rte_pm_build_opt build_opt;
1441 struct rte_pm_pattern pat;
1442 struct rte_pm_ctx * pmx;
1443 enum rte_pm_search search_result;
1444 char buf[MAX_PATTERN_LEN];
1449 /* search for existing PM algorithm */
1450 search_result = rte_pm_search_type_by_name("AC2_L1x4");
1451 if (search_result != RTE_PM_SEARCH_AC2_L1x4) {
1452 printf("Line %i: Wrong PM algorithm found!\n", __LINE__);
1455 pmx = rte_pm_create(&good_param);
1457 printf("Line %i: Failed to create PM context!\n", __LINE__);
1461 /* convert a pattern and add it to context */
1462 ret = rte_pm_convert_pattern("|01 02 03 04| readable", (uint8_t*) buf,
1466 printf("Line %i: Converting binary failed!\n", __LINE__);
1470 /* add pattern to context */
1471 pat.len = (uint32_t) ret;
1472 pat.pattern = (const uint8_t *) buf;
1475 ret = rte_pm_add_patterns(pmx, &pat, 1);
1478 printf("Line %i: Adding pattern failed!\n", __LINE__);
1482 /* convert another pattern and add it to context */
1483 ret = rte_pm_convert_pattern("pattern", (uint8_t*) buf, 4);
1487 printf("Line %i: Converting pattern failed!\n", __LINE__);
1491 /* add pattern to context */
1492 pat.len = (uint32_t) ret;
1493 pat.pattern = (const uint8_t *) buf;
1496 ret = rte_pm_add_patterns(pmx, &pat, 1);
1499 printf("Line %i: Adding pattern failed!\n", __LINE__);
1503 build_opt.case_sense = 0;
1504 build_opt.out_of_order = 0;
1505 build_opt.search_type = RTE_PM_SEARCH_AC2_L1x4;
1507 ret = rte_pm_build(pmx, &build_opt);
1510 printf("Line %i: Building PM failed!\n", __LINE__);
1514 /* dump context with patterns - useful for coverage */
1527 if (test_invalid_parameters() < 0)
1529 if (test_serialize() < 0)
1531 if (test_create_find_add() < 0)
1533 if (test_search_patterns() < 0)
1535 if (test_misc() < 0)
1540 #else /* RTE_LIBRTE_PMAC=n */
1545 printf("This binary was not compiled with PMAC support!\n");
1549 #endif /* RTE_LIBRTE_PMAC */