summaryrefslogtreecommitdiff
path: root/cesar/lib/test
diff options
context:
space:
mode:
authorJérémy Dufour2011-07-13 16:18:50 +0200
committerJérémy Dufour2011-09-08 16:10:49 +0200
commit0fe91480bca31711e5edffd195eeeddc860857bc (patch)
treeeb90553392048d121f3765cf294377a5bd2a2fa6 /cesar/lib/test
parent70c444ae54fe48dec17698bf62af1b8bb3bd7452 (diff)
cesar/lib: add library to check sequence number in data packets, refs #2644
By default, this library is disabled (at compilation) for performance reasons.
Diffstat (limited to 'cesar/lib/test')
-rw-r--r--cesar/lib/test/seq_check/Config2
-rw-r--r--cesar/lib/test/seq_check/Makefile8
-rw-r--r--cesar/lib/test/seq_check/src/seq_check.c250
3 files changed, 260 insertions, 0 deletions
diff --git a/cesar/lib/test/seq_check/Config b/cesar/lib/test/seq_check/Config
new file mode 100644
index 0000000000..aab2ba7dab
--- /dev/null
+++ b/cesar/lib/test/seq_check/Config
@@ -0,0 +1,2 @@
+CONFIG_SEQ_CHECK = y
+CONFIG_STATS = n
diff --git a/cesar/lib/test/seq_check/Makefile b/cesar/lib/test/seq_check/Makefile
new file mode 100644
index 0000000000..a74fa304d6
--- /dev/null
+++ b/cesar/lib/test/seq_check/Makefile
@@ -0,0 +1,8 @@
+BASE = ../../..
+
+HOST_PROGRAMS = test_seq_check
+
+test_seq_check_SOURCES = seq_check.c
+test_seq_check_MODULES = lib
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/lib/test/seq_check/src/seq_check.c b/cesar/lib/test/seq_check/src/seq_check.c
new file mode 100644
index 0000000000..574f98f017
--- /dev/null
+++ b/cesar/lib/test/seq_check/src/seq_check.c
@@ -0,0 +1,250 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file lib/test/seq_check/src/seq_check.c
+ * \brief Sequence check test
+ * \ingroup test
+ *
+ * Test sequencer check.
+ */
+#include "common/std.h"
+
+#include "lib/test.h"
+#include "lib/seq_check.h"
+#include "common/defs/ethernet.h"
+#include "lib/rnd.h"
+#include "lib/bitstream.h"
+#include "lib/swap.h"
+
+/* Test structure to use with the callback. */
+typedef struct test_seq_check_callback_t
+{
+ struct test_t *test;
+ bool cb_called;
+ uint vlan;
+ uint seq_expected;
+ uint seq_actual;
+} test_seq_check_callback_t;
+
+void
+test_seq_check_write_ethertype (u8 *p, u16 ethertype, bool vlan)
+{
+ /* Store ethertype. */
+ uint pos = 6 * 2 * 8;
+ if (vlan)
+ {
+ bitstream_direct_write (p, pos, swap16 (0x8100), 16);
+ pos += 4 * 8;
+ }
+ bitstream_direct_write (p, pos, swap16 (ethertype), 16);
+}
+
+void
+test_seq_check_cb (void *user, uint vlan, uint seq_expected, uint seq_actual)
+{
+ dbg_assert (user);
+ test_seq_check_callback_t *test_seq_check_callback_values
+ = (test_seq_check_callback_t *) user;
+
+ test_within (test_seq_check_callback_values->test);
+ test_fail_if (test_seq_check_callback_values->vlan != vlan);
+ test_fail_if (test_seq_check_callback_values->seq_expected !=
+ seq_expected);
+ test_fail_if (test_seq_check_callback_values->seq_actual != seq_actual);
+ test_seq_check_callback_values->cb_called = true;
+}
+
+void
+test_seq_check_packet (test_t t, lib_rnd_t *rnd, uint pos, u16 ethertype)
+{
+ lib_seq_check_t s;
+ uint i;
+ u32 p[ETH_PACKET_MAX_SIZE];
+ bool res;
+ test_seq_check_callback_t test_seq_check_callback_values;
+ test_seq_check_callback_values.test = t;
+
+ /* Set configuration. */
+ lib_seq_check_config_t conf;
+ lib_seq_check_config_get (&conf);
+ conf.seq_pos = pos;
+ conf.ethertype = ethertype;
+ lib_seq_check_config_set (&conf);
+
+ test_begin (t, "config")
+ {
+ lib_seq_check_config_get (&conf);
+ test_fail_if (conf.seq_pos != pos);
+ test_fail_if (conf.ethertype != ethertype);
+ } test_end;
+
+ test_begin (t, "init")
+ {
+ lib_seq_check_init (&s, test_seq_check_cb,
+ &test_seq_check_callback_values);
+
+ for (i = 0; i < CONFIG_SEQ_CHECK_VLAN_MAX; i++)
+ {
+ test_fail_if (s.seq[i] != 0);
+ }
+ } test_end;
+
+ test_begin (t, "good sequence")
+ {
+ /* Store ethertype. */
+ test_seq_check_write_ethertype ((u8 *) p, ethertype, false);
+ for (i = 0; i < 1 << 16; i++)
+ {
+ bitstream_direct_write (p, pos * 8, swap16 (i), 16);
+ test_seq_check_callback_values.cb_called = false;
+ lib_seq_check_packet (&s, (u8 *) p, ETH_PACKET_MAX_SIZE);
+ test_fail_if (test_seq_check_callback_values.cb_called == true);
+ }
+ } test_end;
+
+ test_begin (t, "good and bad sequence")
+ {
+ u16 seq, prev;
+
+ /* Re-init. */
+ lib_seq_check_init (&s, test_seq_check_cb,
+ &test_seq_check_callback_values);
+ /* Store ethertype. */
+ test_seq_check_write_ethertype ((u8 *) p, ethertype, false);
+ for (seq = 0, i = 0; i < 1 << 16; i++, seq++)
+ {
+ if (lib_rnd_uniform (rnd, 2))
+ res = true;
+ else
+ {
+ prev = seq;
+ seq = lib_rnd_uniform (rnd, 1 << 16);
+ if (seq == prev)
+ seq++;
+ test_seq_check_callback_values.vlan = 0;
+ test_seq_check_callback_values.seq_expected = prev;
+ test_seq_check_callback_values.seq_actual = seq;
+ res = false;
+ }
+ test_seq_check_callback_values.cb_called = false;
+ bitstream_direct_write (p, pos * 8, swap16 (seq), 16);
+ lib_seq_check_packet (&s, (u8 *) p, ETH_PACKET_MAX_SIZE);
+ test_fail_if (test_seq_check_callback_values.cb_called == res);
+ }
+ } test_end;
+
+ test_begin (t, "good sequence with VLAN")
+ {
+ u16 seq[CONFIG_SEQ_CHECK_VLAN_MAX];
+
+ /* Re-init. */
+ lib_seq_check_init (&s, test_seq_check_cb,
+ &test_seq_check_callback_values);
+ /* Store ethertype. */
+ test_seq_check_write_ethertype ((u8 *) p, ethertype, true);
+
+ for (i = 0; i < CONFIG_SEQ_CHECK_VLAN_MAX; i ++)
+ {
+ seq[i] = 0;
+ }
+
+ for (i = 0; i < (1 << 16) * CONFIG_SEQ_CHECK_VLAN_MAX ; i++)
+ {
+ /* Get a random VLAN. */
+ uint vlan = lib_rnd_uniform (rnd, CONFIG_SEQ_CHECK_VLAN_MAX);
+ /* Write VLAN. */
+ bitstream_direct_write ((u8 *) p, 6 * 2 * 8 + 16, swap16 (vlan),
+ 16);
+
+ test_seq_check_callback_values.cb_called = false;
+ bitstream_direct_write (p, pos * 8, swap16 (seq[vlan]), 16);
+ lib_seq_check_packet (&s, (u8 *) p, ETH_PACKET_MAX_SIZE);
+ test_fail_if (test_seq_check_callback_values.cb_called == true);
+ seq[vlan]++;
+ }
+ } test_end;
+
+ test_begin (t, "good and bad sequence with VLAN")
+ {
+ u16 seq[CONFIG_SEQ_CHECK_VLAN_MAX], prev;
+
+ /* Re-init. */
+ lib_seq_check_init (&s, test_seq_check_cb,
+ &test_seq_check_callback_values);
+ /* Store ethertype. */
+ test_seq_check_write_ethertype ((u8 *) p, ethertype, true);
+
+ for (i = 0; i < CONFIG_SEQ_CHECK_VLAN_MAX; i ++)
+ {
+ seq[i] = 0;
+ }
+
+ for (i = 0; i < (1 << 16) * CONFIG_SEQ_CHECK_VLAN_MAX ; i++)
+ {
+ /* Get a random VLAN. */
+ uint vlan = lib_rnd_uniform (rnd, CONFIG_SEQ_CHECK_VLAN_MAX);
+ /* Write VLAN. */
+ bitstream_direct_write ((u8 *) p, 6 * 2 * 8 + 16, swap16 (vlan),
+ 16);
+
+ if (lib_rnd_uniform (rnd, 2))
+ res = true;
+ else
+ {
+ prev = seq[vlan];
+ seq[vlan] = lib_rnd_uniform (rnd, 1 << 16);
+ if (seq[vlan] == prev)
+ seq[vlan]++;
+ test_seq_check_callback_values.vlan = vlan;
+ test_seq_check_callback_values.seq_expected = prev;
+ test_seq_check_callback_values.seq_actual = seq[vlan];
+ res = false;
+ }
+ test_seq_check_callback_values.cb_called = false;
+ bitstream_direct_write (p, pos * 8, swap16 (seq[vlan]), 16);
+ lib_seq_check_packet (&s, (u8 *) p, ETH_PACKET_MAX_SIZE);
+ test_fail_if (test_seq_check_callback_values.cb_called == res);
+ seq[vlan]++;
+ }
+ } test_end;
+}
+
+int
+main (int argc, char **argv)
+{
+ lib_rnd_t rnd;
+ test_t test;
+
+ lib_rnd_init (&rnd, 0x42);
+ test_init (test, argc, argv);
+
+ test_suite_begin (test, "sequence check");
+
+ lib_seq_check_config_init ();
+
+ test_begin (test, "default config")
+ {
+ lib_seq_check_config_t conf;
+ lib_seq_check_config_get (&conf);
+ test_fail_if (conf.seq_size != 16);
+ test_fail_if (conf.seq_pos != 44);
+ test_fail_if (conf.ethertype != 0x8000);
+ } test_end;
+
+ test_case_begin (test, "IPerf");
+ /* Iperf position is at 44 and we check only IP packet. */
+ test_seq_check_packet (test, &rnd, 44, 0x8000);
+
+ test_case_begin (test, "Other");
+ /* Iperf position is at 44 and we check only IP packet. */
+ test_seq_check_packet (test, &rnd, 50, 0x8042);
+
+ test_result (test);
+ return test_nb_failed (test);
+}
+