diff options
Diffstat (limited to 'src/plugins/unittest/svm_fifo_test.c')
-rw-r--r-- | src/plugins/unittest/svm_fifo_test.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/src/plugins/unittest/svm_fifo_test.c b/src/plugins/unittest/svm_fifo_test.c index bcea0a5e96f..14ebfcacebd 100644 --- a/src/plugins/unittest/svm_fifo_test.c +++ b/src/plugins/unittest/svm_fifo_test.c @@ -13,6 +13,7 @@ * limitations under the License. */ #include <svm/svm_fifo.h> +#include <svm/svm_fifo_segment.h> #include <vlib/vlib.h> #define SFIFO_TEST_I(_cond, _comment, _args...) \ @@ -1090,6 +1091,269 @@ tcp_test_fifo_replay (vlib_main_t * vm, unformat_input_t * input) return 0; } +static svm_fifo_segment_main_t segment_main; + +static int +tcp_test_fifo_segment_hello_world (int verbose) +{ + svm_fifo_segment_create_args_t _a, *a = &_a; + svm_fifo_segment_main_t *sm = &segment_main; + u8 *test_data, *retrieved_data = 0; + svm_fifo_segment_private_t *sp; + svm_fifo_t *f; + int rv; + + clib_memset (a, 0, sizeof (*a)); + a->segment_name = "fifo-test1"; + a->segment_size = 256 << 10; + + rv = svm_fifo_segment_create (sm, a); + + SFIFO_TEST (!rv, "svm_fifo_segment_create returned %d", rv); + + sp = svm_fifo_segment_get_segment (sm, a->new_segment_indices[0]); + f = svm_fifo_segment_alloc_fifo (sp, 4096, FIFO_SEGMENT_RX_FREELIST); + + SFIFO_TEST (f != 0, "svm_fifo_segment_alloc_fifo"); + + test_data = format (0, "Hello world%c", 0); + vec_validate (retrieved_data, vec_len (test_data) - 1); + + while (svm_fifo_max_enqueue (f) >= vec_len (test_data)) + svm_fifo_enqueue_nowait (f, vec_len (test_data), test_data); + + while (svm_fifo_max_dequeue (f) >= vec_len (test_data)) + svm_fifo_dequeue_nowait (f, vec_len (retrieved_data), retrieved_data); + + while (svm_fifo_max_enqueue (f) >= vec_len (test_data)) + svm_fifo_enqueue_nowait (f, vec_len (test_data), test_data); + + while (svm_fifo_max_dequeue (f) >= vec_len (test_data)) + svm_fifo_dequeue_nowait (f, vec_len (retrieved_data), retrieved_data); + + SFIFO_TEST (!memcmp (retrieved_data, test_data, vec_len (test_data)), + "data should be identical"); + + vec_free (test_data); + vec_free (retrieved_data); + svm_fifo_segment_free_fifo (sp, f, FIFO_SEGMENT_RX_FREELIST); + svm_fifo_segment_delete (sm, sp); + return 0; +} + +static int +tcp_test_fifo_segment_slave (int verbose) +{ + svm_fifo_segment_create_args_t _a, *a = &_a; + svm_fifo_segment_main_t *sm = &segment_main; + u8 *test_data, *retrieved_data = 0; + svm_fifo_segment_private_t *sp; + svm_fifo_segment_header_t *fsh; + ssvm_shared_header_t *sh; + svm_fifo_t *f; + u32 *result; + int rv, i; + + sleep (2); + + sm->timeout_in_seconds = 5; + clib_memset (a, 0, sizeof (*a)); + a->segment_name = "fifo-test1"; + + rv = svm_fifo_segment_attach (sm, a); + + SFIFO_TEST (!rv, "svm_fifo_segment_attach returned %d", rv); + + sp = svm_fifo_segment_get_segment (sm, a->new_segment_indices[0]); + sh = sp->ssvm.sh; + fsh = (svm_fifo_segment_header_t *) sh->opaque[0]; + + /* might wanna wait.. */ + f = fsh->fifos; + + /* Lazy bastards united */ + test_data = format (0, "Hello world%c", 0); + vec_validate (retrieved_data, vec_len (test_data) - 1); + + for (i = 0; i < 1000; i++) + { + svm_fifo_dequeue_nowait (f, vec_len (retrieved_data), retrieved_data); + if (memcmp (retrieved_data, test_data, vec_len (retrieved_data))) + { + result = (u32 *) f->head_chunk->data; + *result = 1; + _exit (0); + } + } + + result = (u32 *) f->head_chunk->data; + *result = 0; + + vec_free (test_data); + vec_free (retrieved_data); + _exit (0); +} + +static int +tcp_test_fifo_segment_master_slave (int verbose) +{ + svm_fifo_segment_create_args_t _a, *a = &_a; + svm_fifo_segment_main_t *sm = &segment_main; + svm_fifo_segment_private_t *sp; + svm_fifo_t *f; + u8 *test_data; + u32 *result; + int rv, i; + pid_t pid; + + pid = fork (); + if (pid < 0) + SFIFO_TEST (0, "fork failed"); + + if (!pid) + tcp_test_fifo_segment_slave (verbose); + + clib_memset (a, 0, sizeof (*a)); + a->segment_name = "fifo-test1"; + a->segment_size = 256 << 10; + + rv = svm_fifo_segment_create (sm, a); + + SFIFO_TEST (!rv, "svm_fifo_segment_create returned %d", rv); + + sp = svm_fifo_segment_get_segment (sm, a->new_segment_indices[0]); + f = svm_fifo_segment_alloc_fifo (sp, 4096, FIFO_SEGMENT_RX_FREELIST); + + SFIFO_TEST (f != 0, "svm_fifo_segment_alloc_fifo alloc"); + + test_data = format (0, "Hello world%c", 0); + + usleep (200e3); + + for (i = 0; i < 1000; i++) + svm_fifo_enqueue_nowait (f, vec_len (test_data), test_data); + + /* Wait for slave */ + i = 0; + while (svm_fifo_max_dequeue (f) && i++ < 1e10) + ; + + usleep (1e3); + + result = (u32 *) f->head_chunk->data; + SFIFO_TEST (*result == 0, "slave reported no error"); + + vec_free (test_data); + svm_fifo_segment_free_fifo (sp, f, FIFO_SEGMENT_RX_FREELIST); + svm_fifo_segment_delete (sm, sp); + return 0; +} + +static int +tcp_test_fifo_segment_mempig (int verbose) +{ + svm_fifo_segment_create_args_t _a, *a = &_a; + svm_fifo_segment_main_t *sm = &segment_main; + svm_fifo_segment_private_t *sp; + svm_fifo_t *f; + svm_fifo_t **flist = 0; + int rv; + int i; + + clib_memset (a, 0, sizeof (*a)); + + a->segment_name = "fifo-test1"; + a->segment_size = 256 << 10; + + rv = svm_fifo_segment_create (sm, a); + + SFIFO_TEST (!rv, "svm_fifo_segment_create returned %d", rv); + + sp = svm_fifo_segment_get_segment (sm, a->new_segment_indices[0]); + + for (i = 0; i < 1000; i++) + { + f = svm_fifo_segment_alloc_fifo (sp, 4096, FIFO_SEGMENT_RX_FREELIST); + if (f == 0) + break; + vec_add1 (flist, f); + } + + SFIFO_TEST (vec_len (flist), "created %d fifos", vec_len (flist)); + + for (i = 0; i < vec_len (flist); i++) + { + f = flist[i]; + svm_fifo_segment_free_fifo (sp, f, FIFO_SEGMENT_RX_FREELIST); + } + + _vec_len (flist) = 0; + + for (i = 0; i < 1000; i++) + { + f = svm_fifo_segment_alloc_fifo (sp, 4096, FIFO_SEGMENT_RX_FREELIST); + if (f == 0) + break; + vec_add1 (flist, f); + } + + SFIFO_TEST (vec_len (flist), "second try created %d fifos", + vec_len (flist)); + for (i = 0; i < vec_len (flist); i++) + { + f = flist[i]; + svm_fifo_segment_free_fifo (sp, f, FIFO_SEGMENT_RX_FREELIST); + } + + svm_fifo_segment_delete (sm, sp); + return 0; +} + +static int +tcp_test_fifo_segment (vlib_main_t * vm, unformat_input_t * input) +{ + int rv, verbose = 0; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "verbose")) + verbose = 1; + else if (unformat (input, "masterslave")) + { + if ((rv = tcp_test_fifo_segment_master_slave (verbose))) + return -1; + } + else if (unformat (input, "basic")) + { + if ((rv = tcp_test_fifo_segment_hello_world (verbose))) + return -1; + } + else if (unformat (input, "mempig")) + { + if ((rv = tcp_test_fifo_segment_mempig (verbose))) + return -1; + } + else if (unformat (input, "all")) + { + if ((rv = tcp_test_fifo_segment_hello_world (verbose))) + return -1; + if ((rv = tcp_test_fifo_segment_mempig (verbose))) + return -1; + /* Pretty slow so avoid running it always + if ((rv = tcp_test_fifo_segment_master_slave (verbose))) + return -1; + */ + } + else + { + vlib_cli_output (vm, "parse error: '%U'", format_unformat_error, + input); + return -1; + } + } + return 0; +} + static clib_error_t * svm_fifo_test (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd_arg) @@ -1113,6 +1377,8 @@ svm_fifo_test (vlib_main_t * vm, unformat_input_t * input, res = tcp_test_fifo_replay (vm, input); else if (unformat (input, "grow")) res = tcp_test_fifo_grow (vm, input); + else if (unformat (input, "segment")) + res = tcp_test_fifo_segment (vm, input); else if (unformat (input, "all")) { if ((res = tcp_test_fifo1 (vm, input))) @@ -1162,6 +1428,11 @@ svm_fifo_test (vlib_main_t * vm, unformat_input_t * input, if ((res = tcp_test_fifo_grow (vm, input))) goto done; + + str = "all"; + unformat_init_cstring (input, str); + if ((res = tcp_test_fifo_segment (vm, input))) + goto done; } else { |