diff --git a/nemu/Makefile b/nemu/Makefile index 2226426..f63e3cf 100644 --- a/nemu/Makefile +++ b/nemu/Makefile @@ -13,8 +13,6 @@ # See the Mulan PSL v2 for more details. #**************************************************************************************/ -.EXPORT: - # Sanity check ifeq ($(wildcard $(NEMU_HOME)/src/nemu-main.c),) $(error NEMU_HOME=$(NEMU_HOME) is not a NEMU repo) @@ -61,3 +59,13 @@ else # Include rules to build NEMU include $(NEMU_HOME)/scripts/native.mk endif + +.PHONY: test + +include $(NEMU_HOME)/tests/Makefile +all-tests: CFLAGS += $(shell pkg-config --cflags check) +all-tests: LDFLAGS += $(shell pkg-config --libs check) +all-tests: $(TEST_SRCS:%.c=$(OBJ_DIR)/%) + +test: all-tests + @$(OBJ_DIR)/tests/expr_test diff --git a/nemu/flake.nix b/nemu/flake.nix index 4acb4a4..47bb216 100644 --- a/nemu/flake.nix +++ b/nemu/flake.nix @@ -41,6 +41,7 @@ flex bison pkg-config + python3 # for testing ]; buildInputs = [ diff --git a/nemu/tests/Makefile b/nemu/tests/Makefile index 2742b7c..ba3afb5 100644 --- a/nemu/tests/Makefile +++ b/nemu/tests/Makefile @@ -1,3 +1,11 @@ -CFLGAS += $(pkg-config --cflags --libs check) +TEST_SRCS += tests/expr_test.c -include $(NEMU_HOME)/scripts/build.mk \ No newline at end of file +$(OBJ_DIR)/%: %.c $(OBJS) + @echo + CC $< + @$(CC) $(CFLAGS) -Wl,-e,test_main -o $@ $< $(LDFLAGS) $(CFLGAS) + @$(CC) $(CFLAGS) -Wl,-e,test_main -o $@ $^ $(LDFLAGS) $(CFLGAS) + +$(OBJ_DIR)/%: %.c $(OBJS) + @echo + CC $< + @$(CC) $(CFLAGS) -Wl,-e,test_main -o $@ $< $(LDFLAGS) $(CFLGAS) + @$(CC) $(CFLAGS) -Wl,-e,test_main -o $@ $^ $(LDFLAGS) $(CFLGAS) diff --git a/nemu/tests/expr_test.c b/nemu/tests/expr_test.c index 4e72c0a..46d940f 100644 --- a/nemu/tests/expr_test.c +++ b/nemu/tests/expr_test.c @@ -1,3 +1,114 @@ +#include "sys/types.h" #include +#include +#include +#include +#include +#include +#include +#include +char buf[65536] = "python3 -c print("; +char *buf_ptr = buf + 17; + +void gen(char c) { + *(buf_ptr++) = c; +} + +void gen_num(void) { + int len = rand() % 8 + 1; + int base = 10; + switch(rand() % 2) { + case 0: base = 10; break; + case 1: base = 16; break; + default: assert(0); + } + const char *strmap = "0123456789abcdef"; + // TODO: add minus + if (base == 16) { + gen('0'); + gen('x'); + } + while(len--) { + gen(strmap[rand() % base]); + } +} + +void gen_rand_op(void) { + switch(rand() % 4) { + case 0: gen('+'); break; + case 1: gen('-'); break; + case 2: gen('*'); break; + case 3: gen('/'); break; + } +} + +void gen_rand_expr(void) { + int choice = rand() % 3; + switch (choice) { + case 0: gen_num(); break; + case 1: gen('('); gen_rand_expr(); gen(')'); break; + default: gen_rand_expr(); gen_rand_op(); gen_rand_expr(); break; + } + printf("buf: %s\n", buf); +} + +START_TEST(test_test1) { + for (int i = 0; i < 10; i++) { + gen_rand_expr(); + yy_scan_string(buf + 18); + uint32_t addr; + ck_assert(!yyparse(&addr)); + yylex_destroy(); + + /* Open the command for reading. */ + FILE *fp; + *(buf_ptr++) = ')'; + fp = popen(buf, "r"); + ck_assert(fp != NULL); + + /* Read the output a line at a time - output it. */ + uint32_t reference = 0; + ck_assert(fscanf(fp, "%u", &reference) == 0); + ck_assert(addr == reference); + + while(buf_ptr != buf + 18) { + *(--buf_ptr) = '\0'; + } + } +} END_TEST + +START_TEST(test_test2) { + ; +} END_TEST + +Suite *expr_suite(void) { + Suite *s; + TCase *tc_core; + + s = suite_create("Expr test"); + tc_core = tcase_create("Core"); + + tcase_add_test(tc_core, test_test1); + tcase_add_test(tc_core, test_test2); + suite_add_tcase(s, tc_core); + + return s; +} + +int test_main(void) { + int number_failed; + Suite *s; + SRunner *sr; + srand(time(0)); + + s = expr_suite(); + sr = srunner_create(s); + + srunner_run_all(sr, CK_NORMAL); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +}