added TEST macro

reenabled test_list_*
fixed bug when adding an uninitialized list_node
This commit is contained in:
Anthony Pesch 2016-12-17 01:31:50 -08:00
parent 4ff03a0d2f
commit ac6bd3a677
9 changed files with 200 additions and 407 deletions

View File

@ -408,10 +408,9 @@ if(BUILD_TESTS)
## build test binary
set(RETEST_SOURCES
test/test_dead_code_elimination_pass.c
test/test_list.c
test/test_load_store_elimination_pass.c
#test/test_interval_tree.cc
#test/test_intrusive_list.cc
#test/test_list.cc
#test/test_minmax_heap.cc
#test/test_sh4.cc
#${asm_inc}

View File

@ -10,30 +10,24 @@ void list_add(struct list *list, struct list_node *n) {
void list_add_after(struct list *list, struct list_node *after,
struct list_node *n) {
if (!after) {
if (list->head) {
n->next = list->head;
n->next->prev = n;
}
list->head = n;
} else {
struct list_node *next = after->next;
struct list_node *before = NULL;
if (after) {
before = after->next;
n->prev = after;
n->prev->next = n;
if (next) {
n->next = next;
n->next->prev = n;
} else {
n->next = NULL;
}
} else {
before = list->head;
list->head = n;
list->head->prev = NULL;
}
/* no need to check list->tail == NULL, in that case after would be NULL */
if (list->tail == after) {
if (before) {
n->next = before;
n->next->prev = n;
} else {
list->tail = n;
list->tail->next = NULL;
}
}

View File

@ -1,5 +1,18 @@
#include <stdlib.h>
#include "retest.h"
static struct list tests;
void test_register(struct test *test) {
list_add(&tests, &test->it);
}
int main() {
list_for_each_entry(test, &tests, struct test, it) {
LOG_INFO("[%s]", test->name);
test->run();
LOG_INFO(ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET);
}
return EXIT_SUCCESS;
}

26
test/retest.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef RETEST_H
#define RETEST_H
#include "core/assert.h"
#include "core/constructor.h"
#include "core/list.h"
typedef void (*test_callback_t)();
struct test {
const char *name;
test_callback_t run;
struct list_node it;
};
#define TEST(name) \
static void name(); \
CONSTRUCTOR(TEST_REGISTER_##name) { \
static struct test test = {#name, &name, {0}}; \
test_register(&test); \
} \
void name()
void test_register(struct test *test);
#endif

View File

@ -1,12 +1,11 @@
#include "core/assert.h"
#include "core/constructor.h"
#include "jit/ir/ir.h"
#include "jit/ir/passes/dead_code_elimination_pass.h"
#include "retest.h"
static uint8_t ir_buffer[1024 * 1024];
static char scratch_buffer[1024 * 1024];
CONSTRUCTOR(test_dead_code_elimination_pass) {
TEST(test_dead_code_elimination_pass) {
static const char input_str[] =
"i32 %0 = load_context i32 0xbc\n"
"i32 %1 = load_slow i32 %0\n"

View File

@ -1,218 +0,0 @@
#include <gtest/gtest.h>
extern "C" {
#include "core/arena.h"
#include "core/intrusive_list.h"
}
using namespace re;
struct Person : public IntrusiveListNode<Person> {
Person(const char *name) : name(name) {}
const char *name;
};
struct PersonComparator {
bool operator()(const Person *a, const Person *b) const {
// sort is descending order
return strcmp(b->name, a->name) < 0;
}
};
class IntrusiveTestEmptySet : public ::testing::Test {
public:
IntrusiveTestEmptySet() : arena(1024) {}
Arena arena;
IntrusiveList<Person> people;
};
class IntrusiveTestABCSet : public ::testing::Test {
public:
IntrusiveTestABCSet() : arena(1024) {
aaa = new (arena.Alloc<Person>()) Person("aaa");
people.Append(aaa);
bbb = new (arena.Alloc<Person>()) Person("bbb");
people.Append(bbb);
ccc = new (arena.Alloc<Person>()) Person("ccc");
people.Append(ccc);
}
Arena arena;
IntrusiveList<Person> people;
Person *aaa, *bbb, *ccc;
};
// add tests
TEST_F(IntrusiveTestEmptySet, AddSingle) {
Person *aaa = new (arena.Alloc<Person>()) Person("aaa");
people.Append(aaa);
ASSERT_EQ(aaa, people.head());
ASSERT_EQ(aaa, *people.begin());
ASSERT_EQ(aaa, people.tail());
ASSERT_EQ(aaa, *(--people.end()));
}
TEST_F(IntrusiveTestEmptySet, Prepend) {
Person *aaa = new (arena.Alloc<Person>()) Person("aaa");
people.Prepend(aaa);
ASSERT_EQ(aaa, people.head());
ASSERT_EQ(NULL, people.head()->prev());
ASSERT_EQ(NULL, people.head()->next());
ASSERT_EQ(aaa, *people.begin());
Person *bbb = new (arena.Alloc<Person>()) Person("bbb");
people.Prepend(bbb);
ASSERT_EQ(aaa, people.head()->next());
ASSERT_EQ(aaa, people.tail());
ASSERT_EQ(bbb, people.tail()->prev());
ASSERT_EQ(NULL, people.tail()->next());
ASSERT_EQ(aaa, *(--people.end()));
}
TEST_F(IntrusiveTestEmptySet, Append) {
Person *aaa = new (arena.Alloc<Person>()) Person("aaa");
people.Append(aaa);
ASSERT_EQ(aaa, people.head());
ASSERT_EQ(NULL, people.head()->prev());
ASSERT_EQ(NULL, people.head()->next());
ASSERT_EQ(aaa, *people.begin());
Person *bbb = new (arena.Alloc<Person>()) Person("bbb");
people.Append(bbb);
ASSERT_EQ(bbb, people.head()->next());
ASSERT_EQ(bbb, people.tail());
ASSERT_EQ(aaa, people.tail()->prev());
ASSERT_EQ(NULL, people.tail()->next());
ASSERT_EQ(bbb, *(--people.end()));
}
// remove tests
TEST_F(IntrusiveTestABCSet, RemoveHead) {
people.Remove(aaa);
ASSERT_EQ(bbb, people.head());
ASSERT_EQ(NULL, people.head()->prev());
ASSERT_EQ(ccc, people.head()->next());
ASSERT_EQ(bbb, *people.begin());
ASSERT_EQ(ccc, people.tail());
ASSERT_EQ(bbb, people.tail()->prev());
ASSERT_EQ(NULL, people.tail()->next());
ASSERT_EQ(ccc, *(--people.end()));
}
TEST_F(IntrusiveTestABCSet, RemoveMiddle) {
people.Remove(bbb);
ASSERT_EQ(aaa, people.head());
ASSERT_EQ(NULL, people.head()->prev());
ASSERT_EQ(ccc, people.head()->next());
ASSERT_EQ(aaa, *people.begin());
ASSERT_EQ(ccc, people.tail());
ASSERT_EQ(aaa, people.tail()->prev());
ASSERT_EQ(NULL, people.tail()->next());
ASSERT_EQ(ccc, *(--people.end()));
}
TEST_F(IntrusiveTestABCSet, RemoveTail) {
people.Remove(ccc);
ASSERT_EQ(aaa, people.head());
ASSERT_EQ(NULL, people.head()->prev());
ASSERT_EQ(bbb, people.head()->next());
ASSERT_EQ(aaa, *people.begin());
ASSERT_EQ(bbb, people.tail());
ASSERT_EQ(aaa, people.tail()->prev());
ASSERT_EQ(NULL, people.tail()->next());
ASSERT_EQ(bbb, *(--people.end()));
}
TEST_F(IntrusiveTestABCSet, Clear) {
people.Clear();
ASSERT_EQ(NULL, people.head());
ASSERT_EQ(NULL, people.tail());
}
// iterator tests
TEST_F(IntrusiveTestEmptySet, EmptyIterate) {
ASSERT_EQ(people.begin(), people.end());
}
TEST_F(IntrusiveTestABCSet, ForwardIterator) {
auto it = people.begin();
ASSERT_EQ(aaa, *it);
ASSERT_EQ(bbb, *(++it));
ASSERT_EQ(ccc, *(++it));
ASSERT_EQ(people.end(), ++it);
}
TEST_F(IntrusiveTestABCSet, ForwardIteratorReverse) {
auto it = people.end();
ASSERT_EQ(ccc, *(--it));
ASSERT_EQ(bbb, *(--it));
ASSERT_EQ(aaa, *(--it));
ASSERT_EQ(people.begin(), it);
}
TEST_F(IntrusiveTestABCSet, ReverseIterator) {
auto it = people.rbegin();
ASSERT_EQ(ccc, *it);
ASSERT_EQ(bbb, *(++it));
ASSERT_EQ(aaa, *(++it));
ASSERT_EQ(people.rend(), ++it);
}
TEST_F(IntrusiveTestABCSet, ReverseIteratorReverse) {
auto it = people.rend();
ASSERT_EQ(aaa, *(--it));
ASSERT_EQ(bbb, *(--it));
ASSERT_EQ(ccc, *(--it));
ASSERT_EQ(people.rbegin(), it);
}
TEST_F(IntrusiveTestABCSet, ValidOnInsert) {
auto it = people.begin();
ASSERT_EQ(aaa, *it);
Person *zzz = new (arena.Alloc<Person>()) Person("zzz");
people.Prepend(zzz);
ASSERT_EQ(aaa, *it);
}
TEST_F(IntrusiveTestABCSet, ValidOnRemove) {
auto it = ++people.begin();
ASSERT_EQ(bbb, *it);
people.Remove(aaa);
ASSERT_EQ(bbb, *it);
}
// sort tests
TEST_F(IntrusiveTestEmptySet, EmptySort) {
people.Sort(PersonComparator());
ASSERT_EQ(NULL, people.head());
ASSERT_EQ(NULL, people.tail());
}
TEST_F(IntrusiveTestABCSet, Sort) {
people.Sort(PersonComparator());
auto it = people.begin();
ASSERT_STREQ("ccc", (it++)->name);
ASSERT_STREQ("bbb", (it++)->name);
ASSERT_STREQ("aaa", (it++)->name);
}

144
test/test_list.c Normal file
View File

@ -0,0 +1,144 @@
#include "core/list.h"
#include "retest.h"
struct person {
const char *name;
struct list_node it;
};
static struct person aaa = {"aaa", {0}};
static struct person bbb = {"bbb", {0}};
static struct person ccc = {"ccc", {0}};
static void init_people(struct list *people) {
list_add(people, &aaa.it);
list_add(people, &bbb.it);
list_add(people, &ccc.it);
}
static void validate_people(struct list *people, struct person **expected,
int num_expected) {
/* validate iterating forward */
{
int n = 0;
list_for_each_entry(person, people, struct person, it) {
struct person *expected_person = expected[n];
CHECK_STREQ(person->name, expected_person->name);
n++;
}
CHECK_EQ(n, num_expected);
}
/* validate iterating in reverse */
{
int n = 0;
list_for_each_entry_reverse(person, people, struct person, it) {
struct person *expected_person = expected[num_expected - n - 1];
CHECK_STREQ(person->name, expected_person->name);
n++;
}
CHECK_EQ(n, num_expected);
}
}
/* add tests */
TEST(test_intrusive_list_append) {
struct list people = {0};
list_add(&people, &aaa.it);
list_add(&people, &bbb.it);
list_add(&people, &ccc.it);
struct person *expected[] = {&aaa, &bbb, &ccc};
int num_expected = array_size(expected);
validate_people(&people, expected, num_expected);
}
TEST(test_intrusive_list_prepend) {
struct list people = {0};
list_add_after(&people, NULL, &aaa.it);
list_add_after(&people, NULL, &bbb.it);
list_add_after(&people, NULL, &ccc.it);
struct person *expected[] = {&ccc, &bbb, &aaa};
int num_expected = array_size(expected);
validate_people(&people, expected, num_expected);
}
/* remove tests */
TEST(test_intrusive_list_remove_head) {
struct list people = {0};
init_people(&people);
list_remove(&people, &aaa.it);
struct person *expected[] = {&bbb, &ccc};
int num_expected = array_size(expected);
validate_people(&people, expected, num_expected);
}
TEST(test_intrusive_list_remove_middle) {
struct list people = {0};
init_people(&people);
list_remove(&people, &bbb.it);
struct person *expected[] = {&aaa, &ccc};
int num_expected = array_size(expected);
validate_people(&people, expected, num_expected);
}
TEST(test_intrusive_list_remove_tail) {
struct list people = {0};
init_people(&people);
list_remove(&people, &ccc.it);
struct person *expected[] = {&aaa, &bbb};
int num_expected = array_size(expected);
validate_people(&people, expected, num_expected);
}
TEST(test_intrusive_list_remove_clear) {
struct list people = {0};
init_people(&people);
CHECK(!list_empty(&people));
list_for_each(&people, it) {
list_remove(&people, it);
}
CHECK(list_empty(&people));
}
/* sort tests */
int person_sort(const struct list_node *list_lhs,
const struct list_node *list_rhs) {
const struct person *lhs = list_entry(list_lhs, const struct person, it);
const struct person *rhs = list_entry(list_rhs, const struct person, it);
/* sort in descending order */
return strcmp(rhs->name, lhs->name);
}
TEST(test_intrusive_list_empty_sort) {
struct list people = {0};
list_sort(&people, &person_sort);
CHECK(list_empty(&people));
}
TEST(test_intrusive_list_sort) {
struct list people = {0};
init_people(&people);
list_sort(&people, &person_sort);
struct person *expected[] = {&ccc, &bbb, &aaa};
int num_expected = array_size(expected);
validate_people(&people, expected, num_expected);
}

View File

@ -1,163 +0,0 @@
#include <gtest/gtest.h>
extern "C" {
#include "core/list.h"
}
typedef struct {
struct list_node it;
const char *name;
} person_t;
// struct PersonComparator {
// bool operator()(const Person *a, const Person *b) const {
// // sort is descending order
// return strcmp(b->name, a->name) < 0;
// }
// };
class IntrusiveTestEmptySet : public ::testing::Test {
public:
IntrusiveTestEmptySet() {}
struct list people_list = {};
};
class IntrusiveTestABCSet : public ::testing::Test {
public:
IntrusiveTestABCSet() {
list_add(&people_list, &aaa.it);
list_add(&people_list, &bbb.it);
list_add(&people_list, &ccc.it);
}
struct list people_list = {};
person_t aaa = {{}, "aaa"};
person_t bbb = {{}, "bbb"};
person_t ccc = {{}, "ccc"};
};
static void validate_people(struct list *people_list,
person_t **expected_people,
int num_expected_people) {
int n = 0;
list_for_each_entry(person, people_list, person_t, it) {
person_t *expected_person = expected_people[n];
ASSERT_STREQ(person->name, expected_person->name);
n++;
}
ASSERT_EQ(n, num_expected_people);
}
static void validate_people_reverse(struct list *people_list,
person_t **expected_people,
int num_expected_people) {
int n = 0;
list_for_each_entry_reverse(person, people_list, person_t, it) {
person_t *expected_person = expected_people[num_expected_people - n - 1];
ASSERT_STREQ(person->name, expected_person->name);
n++;
}
ASSERT_EQ(n, num_expected_people);
}
// add tests
TEST_F(IntrusiveTestEmptySet, Append) {
person_t aaa = {{}, "aaa"};
person_t bbb = {{}, "bbb"};
person_t ccc = {{}, "ccc"};
person_t *people[] = {&aaa, &bbb, &ccc};
int num_people = array_size(people);
for (int i = 0; i < num_people; i++) {
person_t *expected_person = people[i];
list_add(&people_list, &expected_person->it);
}
person_t *expected_people[] = {&aaa, &bbb, &ccc};
int num_expected_people = array_size(expected_people);
validate_people(&people_list, expected_people, num_expected_people);
validate_people_reverse(&people_list, expected_people, num_expected_people);
}
TEST_F(IntrusiveTestEmptySet, Prepend) {
person_t aaa = {{}, "aaa"};
person_t bbb = {{}, "bbb"};
person_t ccc = {{}, "ccc"};
person_t *people[] = {&aaa, &bbb, &ccc};
int num_people = array_size(people);
for (int i = 0; i < num_people; i++) {
person_t *expected_person = people[i];
list_add_after(&people_list, NULL, &expected_person->it);
}
person_t *expected_people[] = {&ccc, &bbb, &aaa};
int num_expected_people = array_size(expected_people);
validate_people(&people_list, expected_people, num_expected_people);
validate_people_reverse(&people_list, expected_people, num_expected_people);
}
// remove tests
TEST_F(IntrusiveTestABCSet, RemoveHead) {
list_remove(&people_list, &aaa.it);
person_t *expected_people[] = {&bbb, &ccc};
int num_expected_people = array_size(expected_people);
validate_people(&people_list, expected_people, num_expected_people);
validate_people_reverse(&people_list, expected_people, num_expected_people);
}
TEST_F(IntrusiveTestABCSet, RemoveMiddle) {
list_remove(&people_list, &bbb.it);
person_t *expected_people[] = {&aaa, &ccc};
int num_expected_people = array_size(expected_people);
validate_people(&people_list, expected_people, num_expected_people);
validate_people_reverse(&people_list, expected_people, num_expected_people);
}
TEST_F(IntrusiveTestABCSet, RemoveTail) {
list_remove(&people_list, &ccc.it);
person_t *expected_people[] = {&aaa, &bbb};
int num_expected_people = array_size(expected_people);
validate_people(&people_list, expected_people, num_expected_people);
validate_people_reverse(&people_list, expected_people, num_expected_people);
}
TEST_F(IntrusiveTestABCSet, Clear) {
ASSERT_FALSE(list_empty(&people_list));
list_for_each(&people_list, it) {
list_remove(&people_list, it);
}
ASSERT_TRUE(list_empty(&people_list));
}
// // sort tests
// TEST_F(IntrusiveTestEmptySet, EmptySort) {
// people.Sort(PersonComparator());
// ASSERT_EQ(NULL, people.head());
// ASSERT_EQ(NULL, people.tail());
// }
// TEST_F(IntrusiveTestABCSet, Sort) {
// people.Sort(PersonComparator());
// auto it = people.begin();
// ASSERT_STREQ("ccc", (it++)->name);
// ASSERT_STREQ("bbb", (it++)->name);
// ASSERT_STREQ("aaa", (it++)->name);
// }

View File

@ -1,12 +1,11 @@
#include "core/assert.h"
#include "core/constructor.h"
#include "jit/ir/ir.h"
#include "jit/ir/passes/load_store_elimination_pass.h"
#include "retest.h"
static uint8_t ir_buffer[1024 * 1024];
static char scratch_buffer[1024 * 1024];
CONSTRUCTOR(test_load_store_elimination_pass_test) {
TEST(test_load_store_elimination_pass_test) {
static const char input_str[] =
"store_context i32 0x104, i32 0x0\n"
"store_context i32 0x100, i32 0x0\n"