svm: move fifo tests to ut plugin
[vpp.git] / src / plugins / unittest / svm_fifo_test.c
index bcea0a5..14ebfca 100644 (file)
@@ -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
        {