#include <stdint.h>
#include "ctree.h"
#include "util.h"
#include "unittest.h"
enum {
TEST_NEW_DELETE = 0,
TEST_INSERT = 100,
TEST_REMOVE = 200,
};
#define TEST_VAL_A 1
#define TEST_VAL_B 2
#define TEST_VAL_C 3
static int Rcounter_malloc;
static void *
__wrap_malloc(size_t size)
{
switch (util_fetch_and_add32(&Rcounter_malloc, 1)) {
default:
return malloc(size);
case TEST_INSERT + 3:
case TEST_INSERT + 0:
case TEST_NEW_DELETE + 0:
return NULL;
}
}
static void
test_ctree_new_delete_empty(void)
{
struct ctree *t = NULL;
Rcounter_malloc = TEST_NEW_DELETE;
t = ctree_new();
UT_ASSERT(t == NULL);
t = ctree_new();
UT_ASSERT(t != NULL);
ctree_delete(t);
}
static void
test_ctree_insert(void)
{
struct ctree *t = ctree_new();
UT_ASSERT(t != NULL);
Rcounter_malloc = TEST_INSERT;
UT_ASSERT(ctree_is_empty(t));
UT_ASSERT(ctree_insert(t, TEST_VAL_A, 0) != 0);
UT_ASSERT(ctree_insert(t, TEST_VAL_B, 0) == 0);
UT_ASSERT(ctree_insert(t, TEST_VAL_A, 0) != 0);
UT_ASSERT(ctree_insert(t, TEST_VAL_B, 0) != 0);
UT_ASSERT(ctree_insert(t, TEST_VAL_A, 0) == 0);
UT_ASSERT(!ctree_is_empty(t));
ctree_delete(t);
}
static void
test_ctree_find(void)
{
struct ctree *t = ctree_new();
UT_ASSERT(t != NULL);
uint64_t k = TEST_VAL_A;
UT_ASSERT(ctree_find_le(t, &k) == 0);
UT_ASSERT(ctree_insert(t, TEST_VAL_A, TEST_VAL_A) == 0);
UT_ASSERT(ctree_insert(t, TEST_VAL_B, TEST_VAL_B) == 0);
k = 0;
UT_ASSERT(ctree_find_le(t, &k) == 0);
k = TEST_VAL_A;
UT_ASSERT(ctree_find_le(t, &k) == TEST_VAL_A);
k = TEST_VAL_B;
UT_ASSERT(ctree_find_le(t, &k) == TEST_VAL_B);
ctree_delete(t);
}
static void
test_ctree_remove(void)
{
struct ctree *t = ctree_new();
UT_ASSERT(t != NULL);
Rcounter_malloc = TEST_REMOVE;
UT_ASSERT(ctree_remove(t, TEST_VAL_A, 0) == 0);
UT_ASSERT(ctree_insert(t, TEST_VAL_A, 0) == 0);
UT_ASSERT(ctree_insert(t, TEST_VAL_B, 0) == 0);
UT_ASSERT(ctree_remove(t, TEST_VAL_C, 0) == 0);
UT_ASSERT(ctree_remove(t, TEST_VAL_A, 1) == TEST_VAL_A);
UT_ASSERT(ctree_remove(t, TEST_VAL_B, 1) == TEST_VAL_B);
ctree_delete(t);
}
static void
test_ctree_remove_max(void)
{
struct ctree *t = ctree_new();
UT_ASSERT(t != NULL);
ctree_insert(t, TEST_VAL_A, TEST_VAL_A);
ctree_insert(t, TEST_VAL_B, TEST_VAL_B);
ctree_insert(t, TEST_VAL_C, TEST_VAL_C);
uint64_t key;
uint64_t value;
UT_ASSERTeq(ctree_remove_max_unlocked(t, &key, &value), 0);
UT_ASSERTeq(key, TEST_VAL_C);
UT_ASSERTeq(key, TEST_VAL_C);
UT_ASSERTeq(ctree_remove_max_unlocked(t, &key, &value), 0);
UT_ASSERTeq(key, TEST_VAL_B);
UT_ASSERTeq(key, TEST_VAL_B);
UT_ASSERTeq(ctree_remove_max_unlocked(t, &key, &value), 0);
UT_ASSERTeq(key, TEST_VAL_A);
UT_ASSERTeq(key, TEST_VAL_A);
UT_ASSERTeq(ctree_remove_max_unlocked(t, &key, &value), -1);
ctree_delete(t);
}
int
main(int argc, char *argv[])
{
START(argc, argv, "obj_ctree");
Malloc = __wrap_malloc;
test_ctree_new_delete_empty();
test_ctree_insert();
test_ctree_find();
test_ctree_remove();
test_ctree_remove_max();
DONE(NULL);
}