]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Add unit tests for lib/heap.h datastructures
authorPavel Tvrdík <pawel.tvrdik@gmail.cz>
Fri, 13 Mar 2015 17:36:10 +0000 (18:36 +0100)
committerPavel Tvrdík <pawel.tvrdik@gmail.cz>
Fri, 13 Mar 2015 17:36:10 +0000 (18:36 +0100)
lib/heap_test.c [new file with mode: 0644]

diff --git a/lib/heap_test.c b/lib/heap_test.c
new file mode 100644 (file)
index 0000000..aaf616b
--- /dev/null
@@ -0,0 +1,153 @@
+#include "lib/heap.h"
+#include "birdtest.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define MAX_NUM 1000
+#define SPECIAL_KEY -3213
+
+#define MY_CMP(x, y) ((x) < (y))
+
+static int num;
+static int heap[MAX_NUM+1];
+
+#define SHOW_HEAP(heap)                        \
+    do {                                       \
+      uint _i;                                         \
+      bt_debug("\nnum = %d; ", num);           \
+      for(_i = 1; _i <= num; _i++)             \
+       bt_debug("%d ", heap[_i]);              \
+      if(is_heap_valid(heap, num))             \
+        bt_debug("OK \n");                     \
+      else                                     \
+       bt_debug("NON-VALID HEAP! \n");         \
+    } while(0)
+
+
+#undef HEAP_SWAP
+#define HEAP_SWAP(heap,a,b,t)                  \
+    do {                                       \
+      t=heap[a];                               \
+      heap[a]=heap[b];                         \
+      heap[b]=t;                               \
+      bt_debug("swap(%d %d) ", a, b);          \
+    } while(0)
+
+static int
+is_heap_valid(int heap[], uint num)
+{
+ /*
+  * A valid heap must follow these rules:
+  *   - `num >= 0`
+  *   - `heap[i] >= heap[i / 2]` for each `i` in `[2, num]`
+  */
+
+  if(num < 0)
+    return 0;
+
+  int i;
+  for(i = 2; i <= num; i++)
+    if(heap[i] < heap[i / 2])
+      return 0;
+
+  return 1;
+}
+
+static void
+init_heap(void)
+{
+  int i;
+  num = 0;
+  heap[0] = SPECIAL_KEY;               /* heap[0] should be unused */
+  for(i = 1; i <= MAX_NUM; i++)
+    heap[i] = 0;
+}
+
+static int
+t_heap_insert(void)
+{
+  init_heap();
+
+  int i;
+  for(i = 1; i <= MAX_NUM; i++)
+  {
+    bt_debug("ins %d at pos %d ", MAX_NUM - i, i);
+    heap[i] = MAX_NUM - i;
+    HEAP_INSERT(heap, ++num, int, MY_CMP, HEAP_SWAP);
+    SHOW_HEAP(heap);
+    bt_assert(is_heap_valid(heap, num));
+  }
+
+  return BT_SUCCESS;
+}
+
+static int
+t_heap_increase_decrease(void)
+{
+  init_heap();
+  t_heap_insert();
+
+  int i;
+  for(i = 1; i <= MAX_NUM; i++)
+  {
+    if(i > heap[i])
+    {
+      bt_debug("inc %d ", i);
+      heap[i] = i;
+      HEAP_INCREASE(heap, num, int, MY_CMP, HEAP_SWAP, i);
+    }
+    else if (i < heap[i])
+    {
+      bt_debug("dec %d ", i);
+      heap[i] = i;
+      HEAP_INCREASE(heap, num, int, MY_CMP, HEAP_SWAP, i);
+    }
+    SHOW_HEAP(heap);
+    bt_assert(is_heap_valid(heap, num));
+  }
+
+  return BT_SUCCESS;
+}
+
+static int
+t_heap_delete(void)
+{
+  init_heap();
+  t_heap_insert();
+  t_heap_increase_decrease();
+
+  int i;
+  for(i = 1; i <= num; i++)
+  {
+    bt_debug("del at pos %d ", i);
+    HEAP_DELETE(heap, num, int, MY_CMP, HEAP_SWAP, i);
+    SHOW_HEAP(heap);
+    bt_assert(is_heap_valid(heap, num));
+  }
+
+  return BT_SUCCESS;
+}
+
+static int
+t_heap_0(void)
+{
+  init_heap();
+  t_heap_insert();
+  t_heap_increase_decrease();
+  t_heap_delete();
+
+  return (heap[0] == SPECIAL_KEY) ? BT_SUCCESS : BT_FAILURE;
+}
+
+int
+main(int argc, char *argv[])
+{
+  bt_init(argc, argv);
+
+  bt_test_case(t_heap_insert, "Test Inserting", 1, 5);
+  bt_test_case(t_heap_increase_decrease, "Test Increasing/Decreasing", 1, 5);
+  bt_test_case(t_heap_delete, "Test Deleting", 1, 5);
+  bt_test_case(t_heap_0, "Is heap[0] unused?", 1, 5);
+
+  return 0;
+}