summaryrefslogtreecommitdiff
path: root/cesar/cl/test/utest_eoc/src/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cl/test/utest_eoc/src/send.c')
-rw-r--r--cesar/cl/test/utest_eoc/src/send.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/cesar/cl/test/utest_eoc/src/send.c b/cesar/cl/test/utest_eoc/src/send.c
new file mode 100644
index 0000000000..58af73dd68
--- /dev/null
+++ b/cesar/cl/test/utest_eoc/src/send.c
@@ -0,0 +1,261 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cl/test/utest_eoc/src/send.c
+ * \brief CL TX unit tests.
+ * \ingroup cl/test/utest_eoc
+ */
+#include <string.h>
+
+#include "common/std.h"
+#include "lib/test.h"
+
+#include "cl/test/utest_eoc/test.h"
+#include "cl/inc/send.h"
+#include "cl/inc/context.h"
+#include "lib/bitstream.h"
+
+uint
+cl_classifer_get_lid (cl_t *ctx, uint tei, uint tag,
+ bool *bcast, bool *acs,
+ bool *drop);
+
+void
+sar_msdu_process (sar_t *ctx, u8 *buffer, u16 length,
+ mfs_tx_t *mfs, u32 arrival_time_ntb)
+{
+ sar_test_t *t = (sar_test_t*) ctx;
+ dbg_assert (ctx);
+ dbg_assert (t->nb <= TEST_BUFFER_MAX_NB);
+
+ t->buffer[t->nb] = buffer;
+ t->length[t->nb] = length;
+ t->mfs[t->nb] = mfs;
+ t->nb++;
+}
+
+void
+cl_test_case__cl_data_send_prepare (test_t test)
+{
+ test_case_begin (test, "Data send");
+
+ u8 buffer [1024];
+ cl_test_t t;
+ cl_data_send_link_t expected;
+ mac_t sta_mac [] = {0x123456789abcull, 0x23456789abceull};
+ mfs_tx_t *mfs[COUNT(sta_mac)];
+ uint i, j;
+ uint start_time_ntb = 0;
+ uint tag = 0;
+ uint tx_data = 0;
+ uint tx_data_bytes = 0;
+ uint sar_nb = 0;
+ uint length = 123;
+ bool added = false;
+
+ cl_test_init (&t, 0x95490d);
+ cl_test_prepare_mactotei (&t, sta_mac, COUNT (sta_mac));
+
+ test_begin (test, "To SAR")
+ for (j = 0; j < COUNT (sta_mac); j++)
+ {
+ mfs[j] = mac_store_mfs_add_tx (t.mac_store, false, false,
+ MAC_LLID_MIN + 1, j + 100, &added);
+ dbg_assert (added);
+ t.sar.nb = 0;
+ cl_test_prepare_buffer (&t, buffer, length, sta_mac[j], 0);
+ expected.mfs = mfs[j];
+ expected.last_update_date_ntb = start_time_ntb;
+ expected.dmac = sta_mac[j];
+ for (i = start_time_ntb; i < 500000; i+= 100000)
+ {
+ if (i == MAC_MS_TO_TCK (CL_DATA_SEND_EXCEED_TIME_MS))
+ expected.last_update_date_ntb = i;
+ tx_data_bytes = t.cl->stats.tx_data_bytes;
+ tx_data = t.cl->stats.tx_data;
+ sar_nb = t.sar.nb;
+ cl_data_send (t.cl, buffer, length, tag, i);
+ test_fail_unless (t.cl->data_send_link.mfs == expected.mfs);
+ test_fail_unless (t.cl->data_send_link.last_update_date_ntb
+ == expected.last_update_date_ntb);
+ test_fail_unless (t.cl->stats.tx_data_bytes
+ == tx_data_bytes + length);
+ test_fail_unless (t.cl->stats.tx_data == tx_data + 1);
+ test_fail_unless (t.sar.nb == sar_nb + 1);
+ test_fail_unless (t.cl->data_send_link.dmac
+ == bitstream_direct_read_large (buffer, 0, 48));
+ }
+ mac_store_mfs_remove (t.mac_store, PARENT_OF (mfs_t, tx, mfs[j]));
+ blk_release (mfs [j]);
+ dbg_check (mac_store_sta_remove (t.mac_store, j + 100));
+ }
+ test_end;
+
+ cl_test_uninit (&t);
+}
+
+void
+cl_test_case__cl_data_send_mcast (test_t test)
+{
+ test_case_begin (test, "Multicast send");
+
+ u8 buffer [1024];
+ cl_test_t t;
+ mfs_tx_t *mfs_ref, *mfs_mcast[MCAST_GROUP_MAX_NB][MCAST_MEMBER_MAX_NB];
+ uint i, j;
+ uint start_time_ntb = 0;
+ uint tx_data_multicast = 0;
+ uint tx_data = 0;
+ uint tx_data_bytes = 0;
+ uint length = 123;
+ bool added = false;
+ bool bcast = false;
+ bool acs = false;
+ bool drop = false;
+
+ cl_test_init (&t, 0x95490d);
+
+ test_begin (test, "Multicast data.")
+ {
+ /** Prepare the groups and the mactotei table. */
+ for (j = 0; j < MCAST_GROUP_MAX_NB; j++)
+ {
+ t.cl->groups.group_mac[j] =
+ MAC_ADDRESS (0x01, 0x00, 0x5E, 0x00, j + 1, 0x01);
+ t.cl->groups.nb_actual_members[j] = j % (MCAST_MEMBER_MAX_NB + 1);
+ t.cl->groups.member_tei[j][0] = MAC_TEI_UNASSOCIATED;
+
+ for (i = 0; i < t.cl->groups.nb_actual_members[j]; i++)
+ {
+ t.cl->groups.member_tei[j][i]
+ = 100 + j * MCAST_MEMBER_MAX_NB + i;
+ mfs_mcast[j][i] = mac_store_mfs_add_tx (t.mac_store, false,
+ false, MAC_LLID_MIN + 1,
+ t.cl->groups.member_tei[j][i], &added);
+ dbg_assert (added);
+ }
+ cl_eoc_mactotei_entry_insert (t.cl, t.cl->groups.group_mac[j],
+ MAC_TEI_BCAST);
+ }
+ t.cl->groups.nb = MCAST_GROUP_MAX_NB;
+
+ for (j = 0; j < MCAST_GROUP_MAX_NB; j++)
+ {
+ cl_test_prepare_buffer (&t, buffer, length,
+ MAC_ADDRESS (0x01, 0x00, 0x5E, 0x00, j + 1, 0x01),
+ 0);
+
+ /** Send the multicast message */
+ t.sar.nb = 0;
+ tx_data_bytes = t.cl->stats.tx_data_bytes;
+ tx_data_multicast = t.cl->stats.tx_data_multicast;
+ tx_data = t.cl->stats.tx_data;
+
+ cl_data_send (t.cl, buffer, length, 0, start_time_ntb);
+
+ test_fail_unless (t.cl->stats.tx_data_bytes
+ == tx_data_bytes + length);
+ test_fail_unless (t.cl->stats.tx_data_multicast
+ == tx_data_multicast + 1);
+ test_fail_unless (t.cl->stats.tx_data == tx_data);
+
+ if (t.cl->groups.nb_actual_members[j] == 0)
+ {
+ test_fail_unless (t.sar.nb == 0);
+ }
+ else
+ {
+ test_fail_unless (t.sar.nb
+ == t.cl->groups.nb_actual_members[j]);
+
+ for (i = 0; i < t.cl->groups.nb_actual_members[j]; i++)
+ {
+ uint tei = 100 + j * MCAST_MEMBER_MAX_NB + i;
+ uint lid = cl_classifer_get_lid (t.cl, tei, 0, &bcast,
+ &acs, &drop);
+ mfs_ref = mac_store_mfs_get_tx (t.cl->mac_store, bcast,
+ false, lid, tei);
+
+ test_fail_unless (mfs_ref == t.sar.mfs[i]);
+ test_fail_unless (buffer == t.sar.buffer[i]);
+ test_fail_unless (mfs_ref->common.tei == tei);
+ test_fail_unless (bcast == false);
+
+ mac_store_mfs_remove (t.mac_store,
+ PARENT_OF (mfs_t, tx, mfs_ref));
+ blk_release (mfs_ref);
+ dbg_check (mac_store_sta_remove (t.mac_store, tei));
+ }
+ }
+ for (i = 0; i < t.cl->groups.nb_actual_members[j]; i++)
+ {
+ mac_store_mfs_remove (t.mac_store,
+ PARENT_OF (mfs_t, tx, mfs_mcast[j][i]));
+ blk_release (mfs_mcast[j][i]);
+ }
+ }
+ cl_mactotei_release_table (t.cl);
+ }
+ test_end;
+
+ test_begin (test, "Multicast not IGMP members")
+ {
+ /*
+ * From Wikipedia
+ * http://en.wikipedia.org/wiki/Multicast_address#Ethernet
+ *
+ * 01-00-0C-CC-CC-CC 0x0802 CDP, VTP
+ * 01-00-0C-CC-CC-CD 0x0802 Cisco Shared Spanning Tree Protocol Address
+ * 01-80-C2-00-00-00 0x0802 Spanning Tree Protocol IEEE 802.1D
+ * 01-80-C2-00-00-08 0x0802 Spanning Tree Protocol IEEE 802.1AD
+ * 01-80-C2-00-00-02 0x8809 Ethernet OAM Protocol IEEE 802.3ah
+ * 01-00-5E-xx-xx-xx 0x0800 IPv4 Multicast (RFC 1112)
+ */
+ mac_t mcast_mac_addr[] = {
+ MAC_ADDRESS (0x01, 0x00, 0x0C, 0xCC, 0xCC, 0xCC),
+ MAC_ADDRESS (0x01, 0x00, 0x0C, 0xCC, 0xCC, 0xCD),
+ MAC_ADDRESS (0x01, 0x80, 0xC2, 0x00, 0x00, 0x00),
+ MAC_ADDRESS (0x01, 0x80, 0xC2, 0x00, 0x00, 0x08),
+ MAC_ADDRESS (0x01, 0x80, 0xC2, 0x00, 0x00, 0x02),
+ MCAST_MAC_IGMP_GENERAL_QUERY,
+ };
+
+ uint i;
+ uint tag = 0;
+ for (i = 0; i < COUNT (mcast_mac_addr); i++)
+ {
+ mfs_t *mfs;
+ cl_test_prepare_buffer (&t, buffer, length, mcast_mac_addr[i],
+ tag);
+ cl_data_send (t.cl, buffer, length, tag, 0x0);
+ mfs = PARENT_OF_OR_NULL (mfs_t, tx, t.sar.mfs[0]);
+ test_fail_unless (mfs && mfs->common.bcast);
+ /* Release the MFS from:
+ * - the CL ("fast path") i.e. data_send_link,
+ * - the overridden SAR layer which contains a pointer to it,
+ * - the mac store which has initialised it.
+ */
+ t.cl->data_send_link.mfs = NULL;
+ t.sar.nb = 0;
+ t.sar.mfs[0] = NULL;
+ mac_store_mfs_remove (t.mac_store, mfs);
+ blk_release (mfs);
+ }
+ }
+ test_end;
+
+ cl_test_uninit (&t);
+}
+
+void
+cl_test_suite_send (test_t test)
+{
+ test_suite_begin (test, "CL send");
+ cl_test_case__cl_data_send_prepare (test);
+ cl_test_case__cl_data_send_mcast (test);
+}