diff --git a/tests/07-simulation-base/31-data-structures-sky.csc b/tests/07-simulation-base/31-data-structures-sky.csc
new file mode 100644
index 000000000..cd0e35ee3
--- /dev/null
+++ b/tests/07-simulation-base/31-data-structures-sky.csc
@@ -0,0 +1,98 @@
+
+
+ [APPS_DIR]/mrm
+ [APPS_DIR]/mspsim
+ [APPS_DIR]/avrora
+ [APPS_DIR]/serial_socket
+ [APPS_DIR]/collect-view
+ [APPS_DIR]/powertracker
+
+ data-structures-sky
+ 123456
+ 1000000
+
+ org.contikios.cooja.radiomediums.UDGM
+ 50.0
+ 100.0
+ 1.0
+ 1.0
+
+
+ 40000
+
+
+ org.contikios.cooja.mspmote.SkyMoteType
+ sky1
+ Sky Mote Type #sky1
+
+ make test-data-structures.sky TARGET=sky
+ [CONTIKI_DIR]/tests/07-simulation-base/code-data-structures/test-data-structures.sky
+ org.contikios.cooja.interfaces.Position
+ org.contikios.cooja.interfaces.RimeAddress
+ org.contikios.cooja.interfaces.IPAddress
+ org.contikios.cooja.interfaces.Mote2MoteRelations
+ org.contikios.cooja.interfaces.MoteAttributes
+ org.contikios.cooja.mspmote.interfaces.MspClock
+ org.contikios.cooja.mspmote.interfaces.MspMoteID
+ org.contikios.cooja.mspmote.interfaces.SkyButton
+ org.contikios.cooja.mspmote.interfaces.SkyFlash
+ org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem
+ org.contikios.cooja.mspmote.interfaces.Msp802154Radio
+ org.contikios.cooja.mspmote.interfaces.MspSerial
+ org.contikios.cooja.mspmote.interfaces.SkyLED
+ org.contikios.cooja.mspmote.interfaces.MspDebugOutput
+ org.contikios.cooja.mspmote.interfaces.SkyTemperature
+
+
+
+
+ org.contikios.cooja.interfaces.Position
+ 3.086692968239446
+ 5.726233183606267
+ 0.0
+
+
+ org.contikios.cooja.mspmote.interfaces.MspClock
+ 1.0
+
+
+ org.contikios.cooja.mspmote.interfaces.MspMoteID
+ 1
+
+ sky1
+
+
+
+ org.contikios.cooja.plugins.SimControl
+ 280
+ 2
+ 160
+ 400
+ 0
+
+
+ org.contikios.cooja.plugins.LogListener
+
+
+
+
+
+ 586
+ 1
+ 666
+ 400
+ 160
+
+
+ org.contikios.cooja.plugins.ScriptRunner
+
+ [CONFIG_DIR]/js/data-structures.js
+ true
+
+ 600
+ 0
+ 700
+ 5
+ 1
+
+
diff --git a/tests/07-simulation-base/code-data-structures/Makefile b/tests/07-simulation-base/code-data-structures/Makefile
new file mode 100644
index 000000000..d88177bbe
--- /dev/null
+++ b/tests/07-simulation-base/code-data-structures/Makefile
@@ -0,0 +1,9 @@
+all: test-data-structures
+
+MODULES += os/services/unit-test
+
+MAKE_MAC = MAKE_MAC_NULLMAC
+MAKE_NET = MAKE_NET_NULLNET
+
+CONTIKI = ../../..
+include $(CONTIKI)/Makefile.include
diff --git a/tests/07-simulation-base/code-data-structures/project-conf.h b/tests/07-simulation-base/code-data-structures/project-conf.h
new file mode 100644
index 000000000..1e6d48809
--- /dev/null
+++ b/tests/07-simulation-base/code-data-structures/project-conf.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, Yasuyuki Tanaka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PROJECT_CONF_H_
+#define PROJECT_CONF_H_
+
+#define UNIT_TEST_PRINT_FUNCTION print_test_report
+
+#endif /* PROJECT_CONF_H_ */
diff --git a/tests/07-simulation-base/code-data-structures/test-data-structures.c b/tests/07-simulation-base/code-data-structures/test-data-structures.c
new file mode 100644
index 000000000..e682e43da
--- /dev/null
+++ b/tests/07-simulation-base/code-data-structures/test-data-structures.c
@@ -0,0 +1,897 @@
+/*
+ * Copyright (c) 2017, George Oikonomou - http://www.spd.gr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*---------------------------------------------------------------------------*/
+#include "contiki.h"
+#include "lib/stack.h"
+#include "lib/queue.h"
+#include "lib/circular-list.h"
+#include "lib/dbl-list.h"
+#include "lib/dbl-circ-list.h"
+#include "lib/random.h"
+#include "services/unit-test/unit-test.h"
+
+#include
+#include
+#include
+#include
+/*---------------------------------------------------------------------------*/
+PROCESS(data_structure_test_process, "Data structure process");
+AUTOSTART_PROCESSES(&data_structure_test_process);
+/*---------------------------------------------------------------------------*/
+typedef struct demo_struct_s {
+ struct demo_struct_s *next;
+ struct demo_struct_s *previous;
+} demo_struct_t;
+/*---------------------------------------------------------------------------*/
+#define ELEMENT_COUNT 10
+static demo_struct_t elements[ELEMENT_COUNT];
+/*---------------------------------------------------------------------------*/
+void
+print_test_report(const unit_test_t *utp)
+{
+ printf("=check-me= ");
+ if(utp->result == unit_test_failure) {
+ printf("FAILED - %s: exit at L%u\n", utp->descr, utp->exit_line);
+ } else {
+ printf("SUCCEEDED - %s\n", utp->descr);
+ }
+}
+/*---------------------------------------------------------------------------*/
+UNIT_TEST_REGISTER(test_stack, "Stack Push/Pop");
+UNIT_TEST(test_stack)
+{
+ STACK(stack);
+
+ UNIT_TEST_BEGIN();
+
+ memset(elements, 0, sizeof(elements));
+ stack_init(stack);
+
+ /* Starts from empty */
+ UNIT_TEST_ASSERT(stack_is_empty(stack) == true);
+ UNIT_TEST_ASSERT(stack_peek(stack) == NULL);
+ UNIT_TEST_ASSERT(stack_pop(stack) == NULL);
+
+ /*
+ * Push two elements. Peek and pop should be the last one. Stack should be
+ * non-empty after the pop
+ */
+ stack_push(stack, &elements[0]);
+ stack_push(stack, &elements[1]);
+
+ UNIT_TEST_ASSERT(stack_peek(stack) == &elements[1]);
+ UNIT_TEST_ASSERT(stack_pop(stack) == &elements[1]);
+ UNIT_TEST_ASSERT(stack_peek(stack) == &elements[0]);
+ UNIT_TEST_ASSERT(stack_is_empty(stack) == false);
+ UNIT_TEST_ASSERT(stack_pop(stack) == &elements[0]);
+
+ /* Ends empty */
+ UNIT_TEST_ASSERT(stack_is_empty(stack) == true);
+ UNIT_TEST_ASSERT(stack_peek(stack) == NULL);
+ UNIT_TEST_ASSERT(stack_pop(stack) == NULL);
+
+ UNIT_TEST_END();
+}
+/*---------------------------------------------------------------------------*/
+UNIT_TEST_REGISTER(test_queue, "Queue Enqueue/Dequeue");
+UNIT_TEST(test_queue)
+{
+ QUEUE(queue);
+
+ UNIT_TEST_BEGIN();
+
+ memset(elements, 0, sizeof(elements));
+ queue_init(queue);
+
+ /* Starts from empty */
+ UNIT_TEST_ASSERT(queue_is_empty(queue) == true);
+ UNIT_TEST_ASSERT(queue_peek(queue) == NULL);
+ UNIT_TEST_ASSERT(queue_dequeue(queue) == NULL);
+
+ /* Enqueue three elements. They should come out in the same order */
+ queue_enqueue(queue, &elements[0]);
+ queue_enqueue(queue, &elements[1]);
+ queue_enqueue(queue, &elements[2]);
+
+ UNIT_TEST_ASSERT(queue_dequeue(queue) == &elements[0]);
+ UNIT_TEST_ASSERT(queue_dequeue(queue) == &elements[1]);
+ UNIT_TEST_ASSERT(queue_dequeue(queue) == &elements[2]);
+
+ /* Should be empty */
+ UNIT_TEST_ASSERT(queue_is_empty(queue) == true);
+ UNIT_TEST_ASSERT(queue_peek(queue) == NULL);
+ UNIT_TEST_ASSERT(queue_dequeue(queue) == NULL);
+
+ UNIT_TEST_END();
+}
+/*---------------------------------------------------------------------------*/
+UNIT_TEST_REGISTER(test_csll, "Circular, singly-linked list");
+UNIT_TEST(test_csll)
+{
+ demo_struct_t *head, *tail;
+
+ CIRCULAR_LIST(csll);
+
+ UNIT_TEST_BEGIN();
+
+ memset(elements, 0, sizeof(elements));
+ circular_list_init(csll);
+
+ /* Starts from empty */
+ UNIT_TEST_ASSERT(circular_list_is_empty(csll) == true);
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 0);
+ UNIT_TEST_ASSERT(circular_list_head(csll) == NULL);
+ UNIT_TEST_ASSERT(circular_list_tail(csll) == NULL);
+
+ /* Add one element. Should point to itself and act as head and tail */
+ circular_list_add(csll, &elements[0]);
+
+ UNIT_TEST_ASSERT(circular_list_is_empty(csll) == false);
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 1);
+ UNIT_TEST_ASSERT(circular_list_head(csll) == &elements[0]);
+ UNIT_TEST_ASSERT(circular_list_tail(csll) == &elements[0]);
+ UNIT_TEST_ASSERT(elements[0].next == &elements[0]);
+
+ /* Add a second element. The two should point to each-other */
+ circular_list_add(csll, &elements[1]);
+ UNIT_TEST_ASSERT(elements[0].next == &elements[1]);
+ UNIT_TEST_ASSERT(elements[1].next == &elements[0]);
+
+ /*
+ * Add a third element and check that head->next->next points to tail.
+ * Check that tail->next points to the head
+ */
+ circular_list_add(csll, &elements[2]);
+ head = circular_list_head(csll);
+ tail = circular_list_tail(csll);
+
+ UNIT_TEST_ASSERT(head->next->next == circular_list_tail(csll));
+ UNIT_TEST_ASSERT(tail->next == circular_list_head(csll));
+
+ /* Re-add an existing element. Check the list's integrity */
+ circular_list_add(csll, &elements[1]);
+ head = circular_list_head(csll);
+ tail = circular_list_tail(csll);
+
+ UNIT_TEST_ASSERT(circular_list_is_empty(csll) == false);
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 3);
+ UNIT_TEST_ASSERT(head->next->next->next == circular_list_head(csll));
+ UNIT_TEST_ASSERT(head->next->next == circular_list_tail(csll));
+ UNIT_TEST_ASSERT(tail->next == circular_list_head(csll));
+
+ /* Add another two elements, then start testing removal */
+ circular_list_add(csll, &elements[3]);
+ circular_list_add(csll, &elements[4]);
+
+ /* Remove an item in the middle and test list integrity */
+ head = circular_list_head(csll);
+ circular_list_remove(csll, head->next->next);
+ head = circular_list_head(csll);
+ tail = circular_list_tail(csll);
+
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 4);
+ UNIT_TEST_ASSERT(head->next->next->next->next == circular_list_head(csll));
+ UNIT_TEST_ASSERT(head->next->next->next == circular_list_tail(csll));
+ UNIT_TEST_ASSERT(tail->next == circular_list_head(csll));
+
+ /* Remove the head and test list integrity */
+ circular_list_remove(csll, circular_list_head(csll));
+ head = circular_list_head(csll);
+ tail = circular_list_tail(csll);
+
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 3);
+ UNIT_TEST_ASSERT(head->next->next->next == circular_list_head(csll));
+ UNIT_TEST_ASSERT(head->next->next == circular_list_tail(csll));
+ UNIT_TEST_ASSERT(tail->next == circular_list_head(csll));
+
+ /* Remove the tail and test list integrity */
+ circular_list_remove(csll, circular_list_tail(csll));
+ head = circular_list_head(csll);
+ tail = circular_list_tail(csll);
+
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 2);
+ UNIT_TEST_ASSERT(head->next->next == circular_list_head(csll));
+ UNIT_TEST_ASSERT(head->next == circular_list_tail(csll));
+ UNIT_TEST_ASSERT(tail->next == circular_list_head(csll));
+
+ /*
+ * Remove the tail
+ * Only one item left: Make sure the head and tail are the same and point to
+ * each other
+ */
+ circular_list_remove(csll, circular_list_tail(csll));
+ head = circular_list_head(csll);
+ tail = circular_list_tail(csll);
+
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 1);
+ UNIT_TEST_ASSERT(head == tail);
+ UNIT_TEST_ASSERT(head->next->next == circular_list_head(csll));
+ UNIT_TEST_ASSERT(head->next == circular_list_head(csll));
+ UNIT_TEST_ASSERT(head->next == circular_list_tail(csll));
+ UNIT_TEST_ASSERT(tail->next == circular_list_head(csll));
+ UNIT_TEST_ASSERT(tail->next == circular_list_tail(csll));
+
+ /* Remove the last element by removing the head */
+ circular_list_remove(csll, circular_list_head(csll));
+ UNIT_TEST_ASSERT(circular_list_is_empty(csll) == true);
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 0);
+ UNIT_TEST_ASSERT(circular_list_head(csll) == NULL);
+ UNIT_TEST_ASSERT(circular_list_tail(csll) == NULL);
+
+ /* Remove the last element by removing the tail */
+ circular_list_add(csll, &elements[0]);
+ circular_list_remove(csll, circular_list_tail(csll));
+ UNIT_TEST_ASSERT(circular_list_is_empty(csll) == true);
+ UNIT_TEST_ASSERT(circular_list_length(csll) == 0);
+ UNIT_TEST_ASSERT(circular_list_head(csll) == NULL);
+ UNIT_TEST_ASSERT(circular_list_tail(csll) == NULL);
+
+ UNIT_TEST_END();
+}
+/*---------------------------------------------------------------------------*/
+UNIT_TEST_REGISTER(test_dll, "Doubly-linked list");
+UNIT_TEST(test_dll)
+{
+ demo_struct_t *head, *tail;
+
+ CIRCULAR_LIST(dll);
+
+ UNIT_TEST_BEGIN();
+
+ memset(elements, 0, sizeof(elements));
+
+ /* Starts from empty */
+ dbl_list_init(dll);
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == true);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 0);
+ UNIT_TEST_ASSERT(dbl_list_head(dll) == NULL);
+ UNIT_TEST_ASSERT(dbl_list_tail(dll) == NULL);
+
+ /*
+ * Add an item by adding to the head.
+ * Head and tail should point to NULL in both directions
+ */
+ dbl_list_add_head(dll, &elements[0]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 1);
+ UNIT_TEST_ASSERT(head == &elements[0]);
+ UNIT_TEST_ASSERT(tail == &elements[0]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == NULL);
+ UNIT_TEST_ASSERT(tail->previous == NULL);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Add an item by adding to the tail.
+ * Head and tail should point to NULL in both directions
+ */
+ dbl_list_remove(dll, dbl_list_head(dll));
+ dbl_list_add_tail(dll, &elements[1]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 1);
+ UNIT_TEST_ASSERT(head == &elements[1]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == NULL);
+ UNIT_TEST_ASSERT(tail->previous == NULL);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Add a second item to head. Head points forward to tail.
+ * Tail points backwards to head.
+ */
+ dbl_list_add_head(dll, &elements[2]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 2);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == tail);
+ UNIT_TEST_ASSERT(tail->previous == head);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Add before head.
+ * NULL <-- 3 --> 2 --> 1 --> NULL
+ */
+ dbl_list_add_before(dll, dbl_list_head(dll), &elements[3]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 3);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == &elements[2]);
+ UNIT_TEST_ASSERT(head->next->next == tail);
+ UNIT_TEST_ASSERT(head->next->next->next == NULL);
+ UNIT_TEST_ASSERT(tail->previous == &elements[2]);
+ UNIT_TEST_ASSERT(tail->previous->previous == &elements[3]);
+ UNIT_TEST_ASSERT(tail->previous->previous->previous == NULL);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Add after head.
+ * NULL <-- 3 --> 4 --> 2 --> 1 --> NULL
+ */
+ dbl_list_add_after(dll, dbl_list_head(dll), &elements[4]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 4);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == &elements[4]);
+ UNIT_TEST_ASSERT(head->next->next == &elements[2]);
+ UNIT_TEST_ASSERT(head->next->next->next == tail);
+ UNIT_TEST_ASSERT(head->next->next->next->next == NULL);
+ UNIT_TEST_ASSERT(tail->previous == &elements[2]);
+ UNIT_TEST_ASSERT(tail->previous->previous == &elements[4]);
+ UNIT_TEST_ASSERT(tail->previous->previous->previous == &elements[3]);
+ UNIT_TEST_ASSERT(tail->previous->previous->previous->previous == NULL);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Add at 3rd position by adding after 2nd
+ * NULL <-- 3 --> 4 --> 5 --> 2 --> 1 --> NULL
+ */
+ dbl_list_add_after(dll, &elements[4], &elements[5]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 5);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == &elements[4]);
+ UNIT_TEST_ASSERT(head->next->next == &elements[5]);
+ UNIT_TEST_ASSERT(tail->previous->previous == &elements[5]);
+ UNIT_TEST_ASSERT(tail->previous == &elements[2]);
+ UNIT_TEST_ASSERT(elements[5].next == &elements[2]);
+ UNIT_TEST_ASSERT(elements[5].previous == &elements[4]);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Add at 3rd position by adding before 3rd
+ * NULL <-- 3 --> 4 --> 6 --> 5 --> 2 --> 1 --> NULL
+ */
+ dbl_list_add_before(dll, &elements[5], &elements[6]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 6);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == &elements[4]);
+ UNIT_TEST_ASSERT(head->next->next == &elements[6]);
+ UNIT_TEST_ASSERT(tail->previous->previous == &elements[5]);
+ UNIT_TEST_ASSERT(elements[6].next == &elements[5]);
+ UNIT_TEST_ASSERT(elements[6].previous == &elements[4]);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Add before tail
+ * NULL <-- 3 --> 4 --> 6 --> 5 --> 2 --> 7 --> 1 --> NULL
+ */
+ dbl_list_add_before(dll, dbl_list_tail(dll), &elements[7]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 7);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(tail->previous == &elements[7]);
+ UNIT_TEST_ASSERT(elements[7].next == &elements[1]);
+ UNIT_TEST_ASSERT(elements[7].previous == &elements[2]);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Add after tail
+ * NULL <-- 3 --> 4 --> 6 --> 5 --> 2 --> 7 --> 1 --> 8 --> NULL
+ */
+ dbl_list_add_after(dll, dbl_list_tail(dll), &elements[8]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 8);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[8]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(tail->previous == &elements[1]);
+ UNIT_TEST_ASSERT(elements[8].next == NULL);
+ UNIT_TEST_ASSERT(elements[8].previous == &elements[1]);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Find and remove element 5
+ * NULL <-- 3 --> 4 --> 6 --> 2 --> 7 --> 1 --> 8 --> NULL
+ */
+ dbl_list_remove(dll, &elements[5]);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 7);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[8]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(elements[6].next == &elements[2]);
+ UNIT_TEST_ASSERT(elements[2].previous == &elements[6]);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Remove before tail
+ * NULL <-- 3 --> 4 --> 6 --> 2 --> 7 --> 8 --> NULL
+ */
+ dbl_list_remove(dll, ((demo_struct_t *)dbl_list_tail(dll))->previous);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 6);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[8]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(elements[7].next == tail);
+ UNIT_TEST_ASSERT(tail->previous == &elements[7]);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Remove after head
+ * NULL <-- 3 --> 6 --> 2 --> 7 --> 8 --> NULL
+ */
+ dbl_list_remove(dll, ((demo_struct_t *)dbl_list_head(dll))->next);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 5);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[8]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == &elements[6]);
+ UNIT_TEST_ASSERT(elements[6].previous == head);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Find element 2 and remove whatever is after it
+ * NULL <-- 3 --> 6 --> 2 --> 8 --> NULL
+ */
+ dbl_list_remove(dll, elements[2].next);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 4);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[8]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(elements[2].next == tail);
+ UNIT_TEST_ASSERT(tail->previous == &elements[2]);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Find element 2 and remove whatever is before it
+ * NULL <-- 3 --> 2 --> 8 --> NULL
+ */
+ dbl_list_remove(dll, elements[2].previous);
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 3);
+ UNIT_TEST_ASSERT(head == &elements[3]);
+ UNIT_TEST_ASSERT(tail == &elements[8]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == &elements[2]);
+ UNIT_TEST_ASSERT(elements[2].previous == head);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Remove head
+ * NULL <-- 2 --> 8 --> NULL
+ */
+ dbl_list_remove(dll, dbl_list_head(dll));
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 2);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[8]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == tail);
+ UNIT_TEST_ASSERT(tail->previous == head);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /*
+ * Remove tail
+ * NULL <-- 8 --> NULL
+ */
+ dbl_list_remove(dll, dbl_list_head(dll));
+ head = dbl_list_head(dll);
+ tail = dbl_list_tail(dll);
+
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == false);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 1);
+ UNIT_TEST_ASSERT(head == &elements[8]);
+ UNIT_TEST_ASSERT(tail == &elements[8]);
+ UNIT_TEST_ASSERT(head->previous == NULL);
+ UNIT_TEST_ASSERT(head->next == NULL);
+ UNIT_TEST_ASSERT(tail->previous == NULL);
+ UNIT_TEST_ASSERT(tail->next == NULL);
+
+ /* Remove the last element */
+ dbl_list_remove(dll, dbl_list_head(dll));
+ UNIT_TEST_ASSERT(dbl_list_is_empty(dll) == true);
+ UNIT_TEST_ASSERT(dbl_list_length(dll) == 0);
+ UNIT_TEST_ASSERT(dbl_list_head(dll) == NULL);
+ UNIT_TEST_ASSERT(dbl_list_tail(dll) == NULL);
+
+ UNIT_TEST_END();
+}
+/*---------------------------------------------------------------------------*/
+UNIT_TEST_REGISTER(test_cdll, "Circular, doubly-linked list");
+UNIT_TEST(test_cdll)
+{
+ demo_struct_t *head, *tail;
+
+ CIRCULAR_LIST(cdll);
+
+ UNIT_TEST_BEGIN();
+
+ memset(elements, 0, sizeof(elements));
+
+ /* Starts from empty */
+ dbl_circ_list_init(cdll);
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == true);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 0);
+ UNIT_TEST_ASSERT(dbl_circ_list_head(cdll) == NULL);
+ UNIT_TEST_ASSERT(dbl_circ_list_tail(cdll) == NULL);
+
+ /*
+ * Add an item by adding to the head.
+ * Head and tail should be the same element and should point to itself in
+ * both directions
+ */
+ dbl_circ_list_add_head(cdll, &elements[0]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 1);
+ UNIT_TEST_ASSERT(head == &elements[0]);
+ UNIT_TEST_ASSERT(tail == &elements[0]);
+ UNIT_TEST_ASSERT(head->previous == head);
+ UNIT_TEST_ASSERT(head->next == head);
+ UNIT_TEST_ASSERT(tail->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == tail);
+
+ /*
+ * Add an item by adding to the tail.
+ * (tail) <--> 0 <--> 1 <--> (head)
+ * Head should point to tail in both directions
+ */
+ dbl_circ_list_add_tail(cdll, &elements[1]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 2);
+ UNIT_TEST_ASSERT(head == &elements[0]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->next == tail);
+ UNIT_TEST_ASSERT(tail->previous == head);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+
+ /*
+ * Add before head.
+ * (tail) <--> 2 <--> 0 <--> 1 <--> (head)
+ */
+ dbl_circ_list_add_before(cdll, dbl_circ_list_head(cdll), &elements[2]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 3);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[2].previous == tail);
+ UNIT_TEST_ASSERT(elements[2].next == &elements[0]);
+ UNIT_TEST_ASSERT(elements[0].previous == head);
+
+ /*
+ * Add after head.
+ * (tail) <--> 2 <--> 3 <--> 0 <--> 1 <--> (head)
+ */
+ dbl_circ_list_add_after(cdll, dbl_circ_list_head(cdll), &elements[3]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 4);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[3].previous == head);
+ UNIT_TEST_ASSERT(elements[3].next == &elements[0]);
+ UNIT_TEST_ASSERT(elements[0].previous == &elements[3]);
+
+ /*
+ * Add at 3rd position by adding after 2nd
+ * (tail) <--> 2 <--> 3 <--> 4 <--> 0 <--> 1 <--> (head)
+ */
+ dbl_circ_list_add_after(cdll, &elements[3], &elements[4]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 5);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[3].next == &elements[4]);
+ UNIT_TEST_ASSERT(elements[4].previous == &elements[3]);
+ UNIT_TEST_ASSERT(elements[4].next == &elements[0]);
+ UNIT_TEST_ASSERT(elements[0].previous == &elements[4]);
+
+ /*
+ * Add at 3rd position by adding before 3rd
+ * (tail) <--> 2 <--> 3 <--> 5 <--> 4 <--> 0 <--> 1 <--> (head)
+ */
+ dbl_circ_list_add_before(cdll, &elements[4], &elements[5]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 6);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[3].next == &elements[5]);
+ UNIT_TEST_ASSERT(elements[5].previous == &elements[3]);
+ UNIT_TEST_ASSERT(elements[5].next == &elements[4]);
+ UNIT_TEST_ASSERT(elements[4].previous == &elements[5]);
+
+ /*
+ * Add before tail
+ * (tail) <--> 2 <--> 3 <--> 5 <--> 4 <--> 0 <--> 6 <--> 1 <--> (head)
+ */
+ dbl_circ_list_add_before(cdll, dbl_circ_list_tail(cdll), &elements[6]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 7);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[1]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[0].next == &elements[6]);
+ UNIT_TEST_ASSERT(elements[6].previous == &elements[0]);
+ UNIT_TEST_ASSERT(elements[6].next == &elements[1]);
+ UNIT_TEST_ASSERT(elements[1].previous == &elements[6]);
+
+ /*
+ * Add after tail
+ * (tail) <--> 2 <--> 3 <--> 5 <--> 4 <--> 0 <--> 6 <--> 1 <--> 7 <--> (head)
+ */
+ dbl_circ_list_add_after(cdll, dbl_circ_list_tail(cdll), &elements[7]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 8);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[7]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[1].next == &elements[7]);
+ UNIT_TEST_ASSERT(elements[7].previous == &elements[1]);
+ UNIT_TEST_ASSERT(elements[7].next == &elements[2]);
+ UNIT_TEST_ASSERT(elements[2].previous == &elements[7]);
+
+ /*
+ * Find and remove element 5
+ * (tail) <--> 2 <--> 3 <--> 4 <--> 0 <--> 6 <--> 1 <--> 7 <--> (head)
+ */
+ dbl_circ_list_remove(cdll, &elements[5]);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 7);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[7]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[3].next == &elements[4]);
+ UNIT_TEST_ASSERT(elements[4].previous == &elements[3]);
+
+ /*
+ * Find element 4 and remove what's after it
+ * (tail) <--> 2 <--> 3 <--> 4 <--> 6 <--> 1 <--> 7 <--> (head)
+ */
+ dbl_circ_list_remove(cdll, elements[4].next);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 6);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[7]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[4].next == &elements[6]);
+ UNIT_TEST_ASSERT(elements[6].previous == &elements[4]);
+
+ /*
+ * Find element 4 and remove what's before it
+ * (tail) <--> 2 <--> 4 <--> 6 <--> 1 <--> 7 <--> (head)
+ */
+ dbl_circ_list_remove(cdll, elements[4].previous);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 5);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[7]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[2].next == &elements[4]);
+ UNIT_TEST_ASSERT(elements[4].previous == &elements[2]);
+
+ /*
+ * Remove before tail
+ * (tail) <--> 2 <--> 4 <--> 6 <--> 7 <--> (head)
+ */
+ dbl_circ_list_remove(cdll,
+ ((demo_struct_t *)dbl_circ_list_tail(cdll))->previous);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 4);
+ UNIT_TEST_ASSERT(head == &elements[2]);
+ UNIT_TEST_ASSERT(tail == &elements[7]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[6].next == &elements[7]);
+ UNIT_TEST_ASSERT(elements[7].previous == &elements[6]);
+
+ /*
+ * Remove after tail
+ * (tail) <--> 4 <--> 6 <--> 7 <--> (head)
+ */
+ dbl_circ_list_remove(cdll,
+ ((demo_struct_t *)dbl_circ_list_tail(cdll))->next);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 3);
+ UNIT_TEST_ASSERT(head == &elements[4]);
+ UNIT_TEST_ASSERT(tail == &elements[7]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(tail->next == head);
+ UNIT_TEST_ASSERT(elements[7].next == &elements[4]);
+ UNIT_TEST_ASSERT(elements[4].previous == &elements[7]);
+
+ /*
+ * Remove after head
+ * (tail) <--> 4 <--> 7 <--> (head)
+ */
+ dbl_circ_list_remove(cdll,
+ ((demo_struct_t *)dbl_circ_list_head(cdll))->next);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 2);
+ UNIT_TEST_ASSERT(head == &elements[4]);
+ UNIT_TEST_ASSERT(tail == &elements[7]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(head->next == tail);
+ UNIT_TEST_ASSERT(tail->previous == head);
+ UNIT_TEST_ASSERT(tail->next == head);
+
+ /*
+ * Remove before head
+ * (tail) <--> 4 <--> (head)
+ */
+ dbl_circ_list_remove(cdll,
+ ((demo_struct_t *)dbl_circ_list_head(cdll))->previous);
+ head = dbl_circ_list_head(cdll);
+ tail = dbl_circ_list_tail(cdll);
+
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == false);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 1);
+ UNIT_TEST_ASSERT(head == &elements[4]);
+ UNIT_TEST_ASSERT(tail == &elements[4]);
+ UNIT_TEST_ASSERT(head->previous == tail);
+ UNIT_TEST_ASSERT(head->next == tail);
+
+ /* Remove head */
+ dbl_circ_list_remove(cdll, dbl_circ_list_head(cdll));
+ dbl_circ_list_remove(cdll, dbl_circ_list_head(cdll));
+ UNIT_TEST_ASSERT(dbl_circ_list_is_empty(cdll) == true);
+ UNIT_TEST_ASSERT(dbl_circ_list_length(cdll) == 0);
+ UNIT_TEST_ASSERT(dbl_circ_list_head(cdll) == NULL);
+ UNIT_TEST_ASSERT(dbl_circ_list_tail(cdll) == NULL);
+
+ UNIT_TEST_END();
+}
+/*---------------------------------------------------------------------------*/
+PROCESS_THREAD(data_structure_test_process, ev, data)
+{
+ PROCESS_BEGIN();
+
+ printf("Run unit-test\n");
+ printf("---\n");
+
+ memset(elements, 0, sizeof(elements));
+
+ UNIT_TEST_RUN(test_stack);
+ UNIT_TEST_RUN(test_queue);
+ UNIT_TEST_RUN(test_csll);
+ UNIT_TEST_RUN(test_dll);
+ UNIT_TEST_RUN(test_cdll);
+
+ printf("=check-me= DONE\n");
+
+ PROCESS_END();
+}
+/*---------------------------------------------------------------------------*/
diff --git a/tests/07-simulation-base/js/data-structures.js b/tests/07-simulation-base/js/data-structures.js
new file mode 100644
index 000000000..5acb27f11
--- /dev/null
+++ b/tests/07-simulation-base/js/data-structures.js
@@ -0,0 +1,25 @@
+TIMEOUT(10000, log.testFailed());
+
+var failed = false;
+
+while(true) {
+ YIELD();
+
+ log.log(time + " " + "node-" + id + " "+ msg + "\n");
+
+ if(msg.contains("=check-me=") == false) {
+ continue;
+ }
+
+ if(msg.contains("FAILED")) {
+ failed = true;
+ }
+
+ if(msg.contains("DONE")) {
+ break;
+ }
+}
+if(failed) {
+ log.testFailed();
+}
+log.testOK();