Browse files

Use Check for our unit tests and refactor unit testing.

# Please enter the commit message for your changes.
# (Comment lines starting with '#' will not be included)
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   gc.c
#
  • Loading branch information...
1 parent 67934dc commit 1358a83b0ae10be0494b9ada8dce8f9283549f7a @nelhage committed Dec 26, 2008
Showing with 265 additions and 191 deletions.
  1. +1 −0 .gitignore
  2. +12 −8 Makefile
  3. +0 −154 gc.c
  4. +0 −29 symbol.c
  5. +252 −0 tests.c
View
1 .gitignore
@@ -1,3 +1,4 @@
dist/
+tests
tester
*~
View
20 Makefile
@@ -1,17 +1,21 @@
-CFLAGS=-g -Wall $(DEFS) $(TEST_CFLAGS)
+CFLAGS=-g -Wall $(DEFS)
OBJECTS=gc.o symbol.o read.o
-TEST_OBJECTS=$(OBJECTS) test.o
-TEST_CFLAGS=-DBUILD_TEST
-TESTER=tester
+TEST_CFLAGS=
+TEST_LIBS=
+TEST_LDFLAGS=
+TEST_OBJECTS=tests.o /usr/lib/libcheck.a
+TESTER=tests
-all: $(TESTER)
+all: check
-test: $(TESTER)
+check: $(TESTER)
./$<
-$(TESTER): $(TEST_OBJECTS)
- gcc -o $@ $(TEST_OBJECTS) $(LDFLAGS)
+$(TEST_OBJECTS): CFLAGS += $(TEST_CFLAGS)
+
+$(TESTER): LDFLAGS += $(TEST_LDFLAGS) $(foreach lib,$(TEST_LIBS), -l$(lib))
+$(TESTER): $(TEST_OBJECTS) $(OBJECTS)
clean:
rm -f *.o $(TEST)
View
154 gc.c
@@ -503,157 +503,3 @@ void gc_realloc(uint32_t need) {
uint32_t gc_free_mem() {
return mem_size - (free_ptr - working_mem);
}
-
-#ifdef BUILD_TEST
-
-static int gc_count = 0;
-
-static sc_val external_root = NIL;
-
-void gc_reloc_external() {
- gc_count++;
- gc_relocate(&external_root);
-}
-
-void test_gc(void) {
- int c;
- uint32_t free_mem;
- sc_val reg = NIL, reg2 = NIL;
- sc_val t = NIL;
- gc_register_roots(&reg, &t, NULL);
- gc_register_gc_root_hook(gc_reloc_external);
-
- reg = gc_alloc_cons();
- sc_set_car(reg, sc_make_number(32));
- sc_set_cdr(reg, gc_alloc_cons());
- t = sc_cdr(reg);
- sc_set_car(t, gc_make_string("Hello, World\n"));
- sc_set_cdr(t, NIL);
- t = NIL;
-
- assert(sc_numberp(sc_car(reg)));
- assert(sc_number(sc_car(reg)) == 32);
- assert(sc_consp(sc_cdr(reg)));
- assert(sc_stringp(sc_car(sc_cdr(reg))));
- assert(!strcmp(sc_string(sc_car(sc_cdr(reg))),"Hello, World\n"));
- assert(NILP(sc_cdr(sc_cdr(reg))));
-
- c = gc_count;
- gc_gc();
- assert(c + 1 == gc_count);
-
- assert(sc_numberp(sc_car(reg)));
- assert(sc_number(sc_car(reg)) == 32);
- assert(sc_consp(sc_cdr(reg)));
- assert(sc_stringp(sc_car(sc_cdr(reg))));
- assert(!strcmp(sc_string(sc_car(sc_cdr(reg))),"Hello, World\n"));
- assert(NILP(sc_cdr(sc_cdr(reg))));
-
- sc_set_car(reg, NIL);
- sc_set_cdr(reg, NIL);
-
- free_mem = gc_free_mem();
- c = gc_count;
- gc_gc();
- assert(c + 1 == gc_count);
-#ifndef TEST_STRESS_GC
- assert(gc_free_mem() > free_mem);
-#endif
-
- t = gc_alloc_cons();
- sc_set_car(t, t);
- sc_set_cdr(t, reg);
- sc_set_car(reg, t);
- sc_set_cdr(reg, t);
-
- assert(sc_car(sc_car(reg)) == sc_car(reg));
- assert(sc_cdr(sc_car(reg)) == reg);
- assert(sc_car(reg) == sc_cdr(reg));
-
- c = gc_count;
- gc_gc();
- assert(c + 1 == gc_count);
-
- assert(sc_car(sc_car(reg)) == sc_car(reg));
- assert(sc_cdr(sc_car(reg)) == reg);
- assert(sc_car(reg) == sc_cdr(reg));
-
- t = reg = NIL;
-
- free_mem = gc_free_mem();
- c = gc_count;
- gc_gc();
- assert(c + 1 == gc_count);
-#ifndef TEST_STRESS_GC
- assert(gc_free_mem() > free_mem);
-#endif
-
- reg = gc_alloc_cons();
-
- sc_set_car(reg, gc_alloc_vector(10));
- sc_set_cdr(reg, NIL);
-
- int i, j;
- for(i = 0; i < 10; i++) {
- t = gc_alloc_vector(i);
- for(j = 0; j < i; j++) {
- sc_vector_set(t, j, sc_car(reg));
- }
- sc_vector_set(sc_car(reg), i, t);
- }
-
- assert(sc_vectorp(sc_car(reg)));
- for(i = 0; i < 10; i++) {
- t = sc_vector_ref(sc_car(reg), i);
- assert(sc_vectorp(t));
- assert(sc_vector_len(t) == i);
- for(j = 0; j < i; j++) {
- assert(sc_vector_ref(t, j) == sc_car(reg));
- }
- }
-
- gc_gc();
-
- assert(sc_vectorp(sc_car(reg)));
- for(i = 0; i < 10; i++) {
- t = sc_vector_ref(sc_car(reg), i);
- assert(sc_vectorp(t));
- assert(sc_vector_len(t) == i);
- for(j = 0; j < i; j++) {
- assert(sc_vector_ref(t, j) == sc_car(reg));
- }
- }
-
- external_root = gc_alloc_cons();
- sc_set_car(external_root, external_root);
- sc_set_cdr(external_root, NIL);
-
- gc_gc();
-
- assert(sc_consp(external_root));
- assert(sc_consp(sc_car(external_root)));
- assert(external_root == sc_car(external_root));
-
- for(i=0;i<2000;i++) {
- gc_alloc_cons();
- }
-
- gc_alloc_vector(0x2000);
-
- reg = gc_alloc_cons();
- sc_set_car(reg, NIL);
- sc_set_cdr(reg, NIL);
-
- reg2 = reg;
-
- gc_register_roots(&reg2);
- gc_gc();
- assert(reg == reg2);
- gc_pop_roots();
- gc_gc();
- assert(reg != reg2);
-
- gc_pop_roots();
-}
-
-#endif /* BUILD_TEST */
View
29 symbol.c
@@ -39,32 +39,3 @@ sc_val sc_intern_symbol(char * name) {
sc_vector_set(obarray, i, v);
return v;
}
-
-#ifdef BUILD_TEST
-
-void test_symbol(void) {
- sc_val r0, r1;
- char str[2] = "a";
- int i;
-
- gc_register_roots(&r0, &r1, NULL);
-
- r0 = sc_intern_symbol("hello");
- r1 = sc_intern_symbol("hello");
-
- assert(!strcmp(sc_symbol_name(r0), "hello"));
- assert(r0 == r1);
-
- /* Intern a lot of junk to force an obarray realloc */
- for(i = 0; i < 26; i++) {
- str[0] = 'a' + i;
- sc_intern_symbol(str);
- str[0] = 'A' + i;
- sc_intern_symbol(str);
- }
-
- assert(!strcmp(sc_symbol_name(r0), "hello"));
- assert(r0 == r1);
-}
-
-#endif
View
252 tests.c
@@ -0,0 +1,252 @@
+#include <check.h>
+#include "gc.h"
+#include "string.h"
+#include "symbol.h"
+
+sc_val reg1, reg2;
+
+static void gc_core_setup(void) {
+ gc_init();
+ gc_register_roots(&reg1, &reg2, NULL);
+}
+
+static void gc_core_teardown(void) {
+ gc_pop_roots();
+}
+
+START_TEST(gc_sanity_check)
+{
+ reg1 = gc_alloc_cons();
+ sc_set_car(reg1, sc_make_number(32));
+ sc_set_cdr(reg1, gc_alloc_cons());
+ reg2 = sc_cdr(reg1);
+ sc_set_car(reg2, gc_make_string("Hello, World\n"));
+ sc_set_cdr(reg2, NIL);
+ reg2 = NIL;
+
+ fail_unless(sc_numberp(sc_car(reg1)));
+ fail_unless(sc_number(sc_car(reg1)) == 32);
+ fail_unless(sc_consp(sc_cdr(reg1)));
+ fail_unless(sc_stringp(sc_car(sc_cdr(reg1))));
+ fail_unless(!strcmp(sc_string(sc_car(sc_cdr(reg1))),"Hello, World\n"));
+ fail_unless(NILP(sc_cdr(sc_cdr(reg1))));
+}
+END_TEST
+
+START_TEST(objs_survive_gc)
+{
+ reg1 = gc_alloc_cons();
+ sc_set_car(reg1, sc_make_number(32));
+ sc_set_cdr(reg1, gc_alloc_cons());
+ reg2 = sc_cdr(reg1);
+ sc_set_car(reg2, gc_make_string("Hello, World\n"));
+ sc_set_cdr(reg2, NIL);
+ reg2 = NIL;
+
+ gc_gc();
+
+ fail_unless(sc_numberp(sc_car(reg1)));
+ fail_unless(sc_number(sc_car(reg1)) == 32);
+ fail_unless(sc_consp(sc_cdr(reg1)));
+ fail_unless(sc_stringp(sc_car(sc_cdr(reg1))));
+ fail_unless(!strcmp(sc_string(sc_car(sc_cdr(reg1))),"Hello, World\n"));
+ fail_unless(NILP(sc_cdr(sc_cdr(reg1))));
+}
+END_TEST
+
+START_TEST(gc_frees_mem)
+{
+#ifndef TEST_STRESS_GC
+ uint32_t free_mem;
+ int i;
+ for(i=0; i < 10; i++) {
+ fail_unless((intptr_t)gc_alloc_cons());
+ }
+ free_mem = gc_free_mem();
+ gc_gc();
+ fail_unless(gc_free_mem() > free_mem);
+#endif
+}
+END_TEST
+
+START_TEST(gc_cons_cycle)
+{
+ uint32_t free_mem;
+ reg1 = gc_alloc_cons();
+ reg2 = gc_alloc_cons();
+ sc_set_car(reg1, reg1);
+ sc_set_cdr(reg1, reg2);
+ sc_set_car(reg2, reg1);
+ sc_set_cdr(reg2, reg1);
+
+ fail_unless(sc_car(sc_car(reg2)) == sc_car(reg2));
+ fail_unless(sc_cdr(sc_car(reg2)) == reg2);
+ fail_unless(sc_car(reg2) == sc_cdr(reg2));
+
+ gc_gc();
+
+ fail_unless(sc_car(sc_car(reg2)) == sc_car(reg2));
+ fail_unless(sc_cdr(sc_car(reg2)) == reg2);
+ fail_unless(sc_car(reg2) == sc_cdr(reg2));
+
+ reg1 = reg2 = NIL;
+
+ free_mem = gc_free_mem();
+ gc_gc();
+#ifndef TEST_STRESS_GC
+ fail_unless(gc_free_mem() > free_mem);
+#endif
+}
+END_TEST
+
+START_TEST(gc_basic_vector)
+{
+ int i;
+ reg1 = gc_alloc_vector(10);
+ for(i = 0; i < 10; i++) {
+ sc_vector_set(reg1, i, gc_alloc_cons());
+ sc_set_car(sc_vector_ref(reg1, i), sc_make_number(i));
+ }
+ gc_gc();
+ for(i = 0; i < 10; i++) {
+ fail_unless(sc_consp(sc_vector_ref(reg1, i)));
+ fail_unless(sc_number(sc_car(sc_vector_ref(reg1, i))) == i);
+ }
+}
+END_TEST
+
+START_TEST(gc_large_allocs)
+{
+ int i;
+ for(i=0;i<2000;i++) {
+ gc_alloc_cons();
+ }
+ gc_alloc_vector(0x2000);
+ reg1 = gc_alloc_cons();
+
+ gc_gc();
+
+ fail_unless(sc_consp(reg1));
+}
+END_TEST
+
+sc_val external_root;
+void gc_reloc_external() {
+ gc_relocate(&external_root);
+}
+
+START_TEST(gc_root_hook)
+{
+ gc_register_gc_root_hook(gc_reloc_external);
+ external_root = gc_alloc_cons();
+ sc_set_car(external_root, external_root);
+ sc_set_cdr(external_root, NIL);
+
+ gc_gc();
+
+ fail_unless(sc_consp(external_root));
+ fail_unless(sc_consp(sc_car(external_root)));
+ fail_unless(external_root == sc_car(external_root));
+}
+END_TEST
+
+START_TEST(gc_roots)
+{
+ sc_val reg;
+
+ reg = reg1 = gc_alloc_cons();
+
+ gc_register_roots(&reg, NULL);
+
+ gc_gc();
+
+ fail_unless(reg == reg1);
+
+ gc_pop_roots();
+
+ gc_gc();
+
+ fail_unless(reg != reg1);
+}
+END_TEST
+
+static void obarray_setup() {
+ obarray_init();
+}
+
+static void obarray_teardown() {
+
+}
+
+START_TEST(obarray_sancheck)
+{
+ reg1 = sc_intern_symbol("hello");
+ fail_unless(sc_symbolp(reg1));
+ fail_unless(!strcmp(sc_symbol_name(reg1), "hello"));
+ reg2 = sc_intern_symbol("hello");
+ fail_unless(reg1 == reg2);
+}
+END_TEST
+
+START_TEST(obarray_realloc)
+{
+ int i;
+ char str[2] = "a";
+ reg1 = sc_intern_symbol("hello");
+ /* Intern a lot of junk to force an obarray realloc */
+ for(i = 0; i < 26; i++) {
+ str[0] = 'a' + i;
+ fail_unless(sc_symbolp(sc_intern_symbol(str)));
+ str[0] = 'A' + i;
+ fail_unless(sc_symbolp(sc_intern_symbol(str)));
+ }
+
+ fail_unless(!strcmp(sc_symbol_name(reg1), "hello"));
+ fail_unless(sc_intern_symbol("hello") == reg1);
+}
+END_TEST
+
+
+Suite *gc_suite()
+{
+ Suite *s = suite_create("GC Test Suites");
+ TCase *tc_core = tcase_create("GC core");
+ tcase_add_checked_fixture(tc_core,
+ gc_core_setup,
+ gc_core_teardown);
+ tcase_add_test(tc_core, gc_sanity_check);
+ tcase_add_test(tc_core, objs_survive_gc);
+ tcase_add_test(tc_core, gc_frees_mem);
+ tcase_add_test(tc_core, gc_cons_cycle);
+ tcase_add_test(tc_core, gc_basic_vector);
+ tcase_add_test(tc_core, gc_large_allocs);
+ tcase_add_test(tc_core, gc_root_hook);
+ tcase_add_test(tc_core, gc_roots);
+ suite_add_tcase(s, tc_core);
+
+ TCase *tc_obarray = tcase_create("obarray");
+
+ tcase_add_checked_fixture(tc_obarray,
+ gc_core_setup,
+ gc_core_teardown);
+ tcase_add_checked_fixture(tc_obarray,
+ obarray_setup,
+ obarray_teardown);
+ tcase_add_test(tc_obarray, obarray_sancheck);
+ tcase_add_test(tc_obarray, obarray_realloc);
+ suite_add_tcase(s, tc_obarray);
+
+ return s;
+}
+
+int main()
+{
+ int failed;
+ Suite *s = gc_suite();
+ SRunner *sr = srunner_create(s);
+ srunner_run_all(sr, CK_NORMAL);
+ failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return failed != 0;
+}

0 comments on commit 1358a83

Please sign in to comment.