diff --git a/configure b/configure index 0d2ce81d499..60b33f3bf5d 100755 --- a/configure +++ b/configure @@ -182,8 +182,7 @@ for i in \ rustllvm \ dl stage0 stage1 stage2 stage3 \ stage0/lib stage1/lib stage2/lib stage3/lib \ - test/run-pass test/run-fail test/compile-fail \ - test/bench/99-bottles test/bench/shootout test/bench/task-perf + test/run-pass test/run-fail test/compile-fail test/bench do make_dir $i done diff --git a/mk/clean.mk b/mk/clean.mk index db5397a4a81..6c3645fe85e 100644 --- a/mk/clean.mk +++ b/mk/clean.mk @@ -38,6 +38,7 @@ clean: $(Q)rm -f rt/$(CFG_RUNTIME) $(Q)rm -f rt/main.o $(Q)rm -f rt/main.ll + $(Q)rm -f test/run_pass_stage2.rc test/run_pass_stage2_driver.rs $(Q)rm -Rf $(PKG_NAME)-*.tar.gz dist $(Q)rm -f $(foreach ext,o a d bc s exe,$(wildcard stage*/*.$(ext))) $(Q)rm -Rf $(foreach ext,out out.tmp \ diff --git a/mk/platform.mk b/mk/platform.mk index bb16e7fa320..a66afc3251f 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -63,24 +63,27 @@ ifneq ($(findstring MINGW,$(CFG_OSTYPE)),) CFG_WINDOWSY := 1 endif -CFG_TESTLIB=$(CFG_BUILD_DIR)/$(strip \ - $(if $(findstring stage0,$(1)), \ - stage0/lib, \ - $(if $(findstring stage1,$(1)), \ - stage1/lib, \ - $(if $(findstring stage2,$(1)),\ - stage2/lib, \ - )))) +CFG_TESTLIB=$(CFG_BUILD_DIR)/$(strip \ + $(if $(findstring stage0,$(1)), \ + stage0/lib, \ + $(if $(findstring stage1,$(1)), \ + stage1/lib, \ + $(if $(findstring stage2,$(1)), \ + stage2/lib, \ + $(if $(findstring stage3,$(1)), \ + stage3/lib, \ + ))))) ifdef CFG_UNIXY CFG_INFO := $(info cfg: unix-y environment) CFG_PATH_MUNGE := true CFG_EXE_SUFFIX := - CFG_RUN_TARG=$(CFG_LDENV)=$(CFG_BUILD_DIR)/$(1) $(2) - CFG_RUN_TEST=\ - $(CFG_LDENV)=$(call CFG_TESTLIB,$(1)) \ - $(CFG_VALGRIND) $(1) + CFG_LDPATH := + CFG_RUN=$(CFG_LDENV)=$(1) $(2) + CFG_RUN_TARG=$(call CFG_RUN,$(CFG_BUILD_DIR)/$(1),$(2)) + CFG_RUN_TEST=$(call CFG_RUN,$(call CFG_TESTLIB,$(1)),\ + $(CFG_VALGRIND) $(1)) ifdef CFG_ENABLE_MINGW_CROSS CFG_WINDOWSY := 1 @@ -117,8 +120,9 @@ ifdef CFG_WINDOWSY CFG_DEF_SUFFIX := .def CFG_LDPATH :=$(CFG_LLVM_BINDIR) CFG_LDPATH :=$(CFG_LDPATH):$$PATH - CFG_RUN_TEST=PATH="$(CFG_LDPATH):$(call CFG_TESTLIB,$(1))" $(1) - CFG_RUN_TARG=PATH="$(CFG_LDPATH)" $(2) + CFG_RUN=PATH="$(CFG_LDPATH):$(1)" $(2) + CFG_RUN_TARG=$(call CFG_RUN,,$(2)) + CFG_RUN_TEST=$(call CFG_RUN,$(call CFG_TESTLIB,$(1)),$(1)) ifndef CFG_ENABLE_MINGW_CROSS CFG_PATH_MUNGE := $(strip perl -i.bak -p \ diff --git a/mk/tests.mk b/mk/tests.mk index a135dcc313f..309b7d49423 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -6,189 +6,209 @@ ALL_TEST_INPUTS = $(wildcard $(S)src/test/*/*.rs \ $(S)src/test/*/*/*.rs \ $(S)src/test/*/*.rc) -ifneq ($(findstring check,$(MAKECMDGOALS)),) -XFAIL_INPUTS := $(shell grep -l xfail $(ALL_TEST_INPUTS)) -TEST_XFAILS_STAGE0 := $(shell grep -l xfail-stage0 $(XFAIL_INPUTS)) -TEST_XFAILS_STAGE1 := $(shell grep -l xfail-stage1 $(XFAIL_INPUTS)) -TEST_XFAILS_STAGE2 := $(shell grep -l xfail-stage2 $(XFAIL_INPUTS)) - -ifdef MINGW_CROSS -TEST_XFAILS_STAGE0 += $(S)src/test/run-pass/native-mod.rc -TEST_XFAILS_STAGE1 += $(S)src/test/run-pass/native-mod.rc -TEST_XFAILS_STAGE2 += $(S)src/test/run-pass/native-mod.rc -endif -ifdef CFG_WINDOWSY -TEST_XFAILS_STAGE0 += $(S)src/test/run-pass/native-mod.rc -TEST_XFAILS_STAGE1 += $(S)src/test/run-pass/native-mod.rc -TEST_XFAILS_STAGE2 += $(S)src/test/run-pass/native-mod.rc -endif -endif - - -BENCH_RS := $(wildcard $(S)src/test/bench/shootout/*.rs) \ - $(wildcard $(S)src/test/bench/99-bottles/*.rs) +BENCH_RS := $(wildcard $(S)src/test/bench/*.rs) \ RPASS_RC := $(wildcard $(S)src/test/run-pass/*.rc) -RPASS_RS := $(wildcard $(S)src/test/run-pass/*.rs) $(BENCH_RS) +RPASS_RS := $(wildcard $(S)src/test/run-pass/*.rs) RFAIL_RC := $(wildcard $(S)src/test/run-fail/*.rc) RFAIL_RS := $(wildcard $(S)src/test/run-fail/*.rs) CFAIL_RC := $(wildcard $(S)src/test/compile-fail/*.rc) CFAIL_RS := $(wildcard $(S)src/test/compile-fail/*.rs) -ifdef CHECK_XFAILS -TEST_RPASS_CRATES_STAGE0 := $(filter $(TEST_XFAILS_STAGE0), $(RPASS_RC)) -TEST_RPASS_CRATES_STAGE1 := $(filter $(TEST_XFAILS_STAGE1), $(RPASS_RC)) -TEST_RPASS_CRATES_STAGE2 := $(filter $(TEST_XFAILS_STAGE2), $(RPASS_RC)) -TEST_RPASS_SOURCES_STAGE0 := $(filter $(TEST_XFAILS_STAGE0), $(RPASS_RS)) -TEST_RPASS_SOURCES_STAGE1 := $(filter $(TEST_XFAILS_STAGE1), $(RPASS_RS)) -TEST_RPASS_SOURCES_STAGE2 := $(filter $(TEST_XFAILS_STAGE2), $(RPASS_RS)) -else -TEST_RPASS_CRATES_STAGE0 := $(filter-out $(TEST_XFAILS_STAGE0), $(RPASS_RC)) -TEST_RPASS_CRATES_STAGE1 := $(filter-out $(TEST_XFAILS_STAGE1), $(RPASS_RC)) -TEST_RPASS_CRATES_STAGE1 := $(filter-out $(TEST_XFAILS_STAGE2), $(RPASS_RC)) -TEST_RPASS_SOURCES_STAGE0 := $(filter-out $(TEST_XFAILS_STAGE0), $(RPASS_RS)) -TEST_RPASS_SOURCES_STAGE1 := $(filter-out $(TEST_XFAILS_STAGE1), $(RPASS_RS)) -TEST_RPASS_SOURCES_STAGE2 := $(filter-out $(TEST_XFAILS_STAGE2), $(RPASS_RS)) -endif - -TEST_RPASS_EXES_STAGE0 := \ - $(subst $(S)src/,,$(TEST_RPASS_CRATES_STAGE0:.rc=.stage0$(X))) \ - $(subst $(S)src/,,$(TEST_RPASS_SOURCES_STAGE0:.rs=.stage0$(X))) -TEST_RPASS_EXES_STAGE1 := \ - $(subst $(S)src/,,$(TEST_RPASS_CRATES_STAGE1:.rc=.stage1$(X))) \ - $(subst $(S)src/,,$(TEST_RPASS_SOURCES_STAGE1:.rs=.stage1$(X))) -TEST_RPASS_EXES_STAGE2 := \ - $(subst $(S)src/,,$(TEST_RPASS_CRATES_STAGE2:.rc=.stage2$(X))) \ - $(subst $(S)src/,,$(TEST_RPASS_SOURCES_STAGE2:.rs=.stage2$(X))) - -TEST_RPASS_OUTS_STAGE0 := \ - $(TEST_RPASS_EXES_STAGE0:.stage0$(X)=.stage0.out) -TEST_RPASS_OUTS_STAGE1 := \ - $(TEST_RPASS_EXES_STAGE1:.stage1$(X)=.stage1.out) -TEST_RPASS_OUTS_STAGE2 := \ - $(TEST_RPASS_EXES_STAGE2:.stage2$(X)=.stage2.out) - -TEST_RPASS_TMPS_STAGE0 := \ - $(TEST_RPASS_EXES_STAGE0:.stage0$(X)=.stage0$(X).tmp) -TEST_RPASS_TMPS_STAGE1 := \ - $(TEST_RPASS_EXES_STAGE1:.stage1$(X)=.stage1$(X).tmp) -TEST_RPASS_TMPS_STAGE2 := \ - $(TEST_RPASS_EXES_STAGE2:.stage2$(X)=.stage2$(X).tmp) - - -TEST_RFAIL_CRATES_STAGE0 := $(filter-out $(TEST_XFAILS_STAGE0), $(RFAIL_RC)) -TEST_RFAIL_CRATES_STAGE1 := $(filter-out $(TEST_XFAILS_STAGE1), $(RFAIL_RC)) -TEST_RFAIL_CRATES_STAGE2 := $(filter-out $(TEST_XFAILS_STAGE2), $(RFAIL_RC)) -TEST_RFAIL_SOURCES_STAGE0 := $(filter-out $(TEST_XFAILS_STAGE0), $(RFAIL_RS)) -TEST_RFAIL_SOURCES_STAGE1 := $(filter-out $(TEST_XFAILS_STAGE1), $(RFAIL_RS)) -TEST_RFAIL_SOURCES_STAGE2 := $(filter-out $(TEST_XFAILS_STAGE2), $(RFAIL_RS)) - -TEST_RFAIL_EXES_STAGE0 := \ - $(subst $(S)src/,,$(TEST_RFAIL_CRATES_STAGE0:.rc=.stage0$(X))) \ - $(subst $(S)src/,,$(TEST_RFAIL_SOURCES_STAGE0:.rs=.stage0$(X))) -TEST_RFAIL_EXES_STAGE1 := \ - $(subst $(S)src/,,$(TEST_RFAIL_CRATES_STAGE1:.rc=.stage1$(X))) \ - $(subst $(S)src/,,$(TEST_RFAIL_SOURCES_STAGE1:.rs=.stage1$(X))) -TEST_RFAIL_EXES_STAGE2 := \ - $(subst $(S)src/,,$(TEST_RFAIL_CRATES_STAGE2:.rc=.stage2$(X))) \ - $(subst $(S)src/,,$(TEST_RFAIL_SOURCES_STAGE2:.rs=.stage2$(X))) - -TEST_RFAIL_OUTS_STAGE0 := \ - $(TEST_RFAIL_EXES_STAGE0:.stage0$(X)=.stage0.out) -TEST_RFAIL_OUTS_STAGE1 := \ - $(TEST_RFAIL_EXES_STAGE1:.stage1$(X)=.stage1.out) -TEST_RFAIL_OUTS_STAGE2 := \ - $(TEST_RFAIL_EXES_STAGE2:.stage2$(X)=.stage2.out) - - -TEST_CFAIL_CRATES_STAGE0 := $(filter-out $(TEST_XFAILS_STAGE0), $(CFAIL_RC)) -TEST_CFAIL_CRATES_STAGE1 := $(filter-out $(TEST_XFAILS_STAGE1), $(CFAIL_RC)) -TEST_CFAIL_CRATES_STAGE2 := $(filter-out $(TEST_XFAILS_STAGE2), $(CFAIL_RC)) -TEST_CFAIL_SOURCES_STAGE0 := $(filter-out $(TEST_XFAILS_STAGE0), $(CFAIL_RS)) -TEST_CFAIL_SOURCES_STAGE1 := $(filter-out $(TEST_XFAILS_STAGE1), $(CFAIL_RS)) -TEST_CFAIL_SOURCES_STAGE2 := $(filter-out $(TEST_XFAILS_STAGE2), $(CFAIL_RS)) - -TEST_CFAIL_OUTS_STAGE0 := \ - $(subst $(S)src/,,$(TEST_CFAIL_CRATES_STAGE0:.rc=.stage0.out)) \ - $(subst $(S)src/,,$(TEST_CFAIL_SOURCES_STAGE0:.rs=.stage0.out)) -TEST_CFAIL_OUTS_STAGE1 := \ - $(subst $(S)src/,,$(TEST_CFAIL_CRATES_STAGE1:.rc=.stage1.out)) \ - $(subst $(S)src/,,$(TEST_CFAIL_SOURCES_STAGE1:.rs=.stage1.out)) -TEST_CFAIL_OUTS_STAGE2 := \ - $(subst $(S)src/,,$(TEST_CFAIL_CRATES_STAGE2:.rc=.stage2.out)) \ - $(subst $(S)src/,,$(TEST_CFAIL_SOURCES_STAGE2:.rs=.stage2.out)) - - -ALL_TEST_CRATES := $(TEST_CFAIL_CRATES_STAGE0) \ - $(TEST_RFAIL_CRATES_STAGE0) \ - $(TEST_RPASS_CRATES_STAGE0) \ - $(TEST_CFAIL_CRATES_STAGE1) \ - $(TEST_RFAIL_CRATES_STAGE1) \ - $(TEST_RPASS_CRATES_STAGE1) \ - $(TEST_CFAIL_CRATES_STAGE2) \ - $(TEST_RFAIL_CRATES_STAGE2) \ - $(TEST_RPASS_CRATES_STAGE2) - -ALL_TEST_SOURCES := $(TEST_CFAIL_SOURCES_STAGE0) \ - $(TEST_RFAIL_SOURCES_STAGE0) \ - $(TEST_RPASS_SOURCES_STAGE0) \ - $(TEST_CFAIL_SOURCES_STAGE1) \ - $(TEST_RFAIL_SOURCES_STAGE1) \ - $(TEST_RPASS_SOURCES_STAGE1) \ - $(TEST_CFAIL_SOURCES_STAGE2) \ - $(TEST_RFAIL_SOURCES_STAGE2) \ - $(TEST_RPASS_SOURCES_STAGE2) +RPASS_TESTS := $(RPASS_RC) $(RPASS_RS) +RFAIL_TESTS := $(RFAIL_RC) $(RFAIL_RS) +CFAIL_TESTS := $(CFAIL_RC) $(CFAIL_RS) FT := run_pass_stage2 FT_LIB := $(call CFG_LIB_NAME,$(FT)) FT_DRIVER := $(FT)_driver GENERATED += test/$(FT).rc test/$(FT_DRIVER).rs +# The arguments to all test runners +ifdef TESTNAME + TESTARGS += $(TESTNAME) +endif -check-nocompile: $(TEST_CFAIL_OUTS_STAGE0) \ - $(TEST_CFAIL_OUTS_STAGE1) \ - $(TEST_CFAIL_OUTS_STAGE2) +ifdef CHECK_XFAILS + TESTARGS += --ignored +endif -check-stage0: tidy \ - $(TEST_RPASS_EXES_STAGE0) $(TEST_RFAIL_EXES_STAGE0) \ - $(TEST_RPASS_OUTS_STAGE0) $(TEST_RFAIL_OUTS_STAGE0) \ - $(TEST_CFAIL_OUTS_STAGE0) \ +# Arguments to the cfail/rfail/rpass/bench tests +ifdef CFG_VALGRIND + CTEST_RUNTOOL = --runtool "$(CFG_VALGRIND)" +endif + +CTEST_TESTARGS := $(TESTARGS) + +ifdef VERBOSE + CTEST_TESTARGS += --verbose +endif + +# The test runner that runs the cfail/rfail/rpass and bench tests +COMPILETEST_CRATE := $(S)src/test/compiletest/compiletest.rc +COMPILETEST_INPUTS := $(wildcard $(S)src/test/compiletest/*rs) + +# The standard library test crate +STDTEST_CRATE := $(S)src/test/stdtest/stdtest.rc +STDTEST_INPUTS := $(wildcard $(S)src/test/stdtest/*rs) -check-stage1: tidy \ - $(TEST_RPASS_EXES_STAGE1) $(TEST_RFAIL_EXES_STAGE1) \ - $(TEST_RPASS_OUTS_STAGE1) $(TEST_RFAIL_OUTS_STAGE1) \ - $(TEST_CFAIL_OUTS_STAGE1) \ +###################################################################### +# Main test targets +###################################################################### +check: tidy check-stage2 \ -check-stage2: tidy \ - $(TEST_RPASS_EXES_STAGE2) $(TEST_RFAIL_EXES_STAGE2) \ - $(TEST_RPASS_OUTS_STAGE2) $(TEST_RFAIL_OUTS_STAGE2) \ - $(TEST_CFAIL_OUTS_STAGE2) \ - -check: tidy \ - $(TEST_RPASS_EXES_STAGE2) $(TEST_RFAIL_EXES_STAGE2) \ - $(TEST_RPASS_OUTS_STAGE2) $(TEST_RFAIL_OUTS_STAGE2) \ - $(TEST_CFAIL_OUTS_STAGE2) +check-full: tidy check-stage1 check-stage2 check-stage3 \ check-fast: tidy \ - test/$(FT_DRIVER).out + check-stage2-rustc check-stage2-std \ + test/$(FT_DRIVER).out \ -check-full: tidy \ - $(TEST_RPASS_EXES_STAGE0) $(TEST_RFAIL_EXES_STAGE0) \ - $(TEST_RPASS_OUTS_STAGE0) $(TEST_RFAIL_OUTS_STAGE0) \ - $(TEST_CFAIL_OUTS_STAGE0) \ - $(TEST_RPASS_EXES_STAGE1) $(TEST_RFAIL_EXES_STAGE1) \ - $(TEST_RPASS_OUTS_STAGE1) $(TEST_RFAIL_OUTS_STAGE1) \ - $(TEST_CFAIL_OUTS_STAGE1) \ - $(TEST_RPASS_EXES_STAGE2) $(TEST_RFAIL_EXES_STAGE2) \ - $(TEST_RPASS_OUTS_STAGE2) $(TEST_RFAIL_OUTS_STAGE2) \ - $(TEST_CFAIL_OUTS_STAGE2) +tidy: + @$(call E, check: formatting) + $(Q)echo \ + $(filter-out $(GENERATED) $(addprefix $(S)src/, $(GENERATED)) \ + $(addprefix $(S)src/, $(RUSTLLVM_LIB_CS) $(RUSTLLVM_OBJS_CS) \ + $(RUSTLLVM_HDR) $(PKG_3RDPARTY)) \ + $(S)src/etc/%, $(PKG_FILES)) \ + | xargs -n 10 python $(S)src/etc/tidy.py -check-compile: tidy \ - $(TEST_RPASS_EXES_STAGE0) $(TEST_RFAIL_EXES_STAGE0) \ - $(TEST_RPASS_EXES_STAGE1) $(TEST_RFAIL_EXES_STAGE1) \ - $(TEST_RPASS_EXES_STAGE2) $(TEST_RFAIL_EXES_STAGE2) +# Cancel the implicit .out rule in GNU make +%.out: % +%.out: %.out.tmp + $(Q)mv $< $@ + + +###################################################################### +# Rules for the test runners +###################################################################### + +# StageN template: to stay consistent with stageN.mk, arge 2 is the +# stage being tested, arg 1 is stage N-1 + +define TEST_STAGEN + +check-stage$(2): tidy \ + check-stage$(2)-rustc \ + check-stage$(2)-std \ + check-stage$(2)-rpass \ + check-stage$(2)-rfail \ + check-stage$(2)-cfail \ + check-stage$(2)-bench \ + + +# Rules for the standard library test runner + +check-stage$(2)-std: test/stdtest.stage$(2).out \ + +test/stdtest.stage$(2)$$(X): $$(STDTEST_CRATE) $$(STDTEST_INPUTS) \ + $$(SREQ$(2)) + @$$(call E, compile_and_link: $$@) + $$(STAGE1) -o $$@ $$< --test + +test/stdtest.stage$(2).out.tmp: test/stdtest.stage$(2)$$(X) + @$$(call E, run: $$<) + $$(Q)$$(call CFG_RUN_TEST,$$<) $$(TESTARGS) + $$(Q)touch $$@ + + +# Rules for the rustc test runner + +check-stage$(2)-rustc: test/rustctest.stage$(2).out \ + +test/rustctest.stage$(2)$$(X): $$(COMPILER_CRATE) $$(COMPILER_INPUTS) \ + stage$(2)/$$(CFG_RUNTIME) \ + $$(call CFG_STDLIB_DEFAULT,stage$(1),stage$(2)) \ + stage$(2)/$$(CFG_RUSTLLVM) \ + $$(SREQ$(1)) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(1)) -o $$@ $$< --test + +test/rustctest.stage$(2).out.tmp: test/rustctest.stage$(2)$$(X) + @$$(call E, run: $$<) + $$(Q)$$(call CFG_RUN,stage$(2),$$(CFG_VALGRIND) $$<) \ + $$(TESTARGS) + $$(Q)touch $$@ + + +# Rules for the cfail/rfail/rpass/bench test runner + +check-stage$(2)-cfail: test/compile-fail.stage$(2).out \ + +check-stage$(2)-rfail: test/run-fail.stage$(2).out \ + +check-stage$(2)-rpass: test/run-pass.stage$(2).out \ + +check-stage$(2)-bench: test/bench.stage$(2).out \ + +CTEST_COMMON_ARGS$(2) := --compile-lib-path stage$(2) \ + --run-lib-path stage$(2)/lib \ + --rustc-path stage$(2)/rustc$$(X) \ + --stage-id stage$(2) \ + --rustcflags "$$(CFG_RUSTC_FLAGS)" \ + $$(CTEST_TESTARGS) \ + +CFAIL_ARGS$(2) := $$(CTEST_COMMON_ARGS$(2)) \ + --src-base $$(S)src/test/compile-fail/ \ + --build-base test/compile-fail/ \ + --mode compile-fail \ + +# FIXME (236): run-fail should run under valgrind once unwinding works +RFAIL_ARGS$(2) := $$(CTEST_COMMON_ARGS$(2)) \ + --src-base $$(S)src/test/run-fail/ \ + --build-base test/run-fail/ \ + --mode run-fail \ + +RPASS_ARGS$(2) := $$(CTEST_COMMON_ARGS$(2)) \ + --src-base $(S)src/test/run-pass/ \ + --build-base test/run-pass/ \ + --mode run-pass \ + $$(CTEST_RUNTOOL) \ + +BENCH_ARGS$(2) := $$(CTEST_COMMON_ARGS$(2)) \ + --src-base $(S)src/test/bench/ \ + --build-base test/bench/ \ + --mode run-pass \ + $$(CTEST_RUNTOOL) \ + +test/compiletest.stage$(2)$$(X): $$(COMPILETEST_CRATE) \ + $$(COMPILETEST_INPUTS) \ + $$(SREQ$(2)) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(2)) -o $$@ $$< + +test/compile-fail.stage$(2).out.tmp: test/compiletest.stage$(2)$$(X) \ + $$(CFAIL_TESTS) + @$$(call E, run: $$<) + $$(Q)$$(call CFG_RUN_TEST,$$<) $$(CFAIL_ARGS$(2)) + $$(Q)touch $$@ + +test/run-fail.stage$(2).out.tmp: test/compiletest.stage$(2)$$(X) \ + $$(RFAIL_TESTS) + @$$(call E, run: $$<) + $$(Q)$$(call CFG_RUN_TEST,$$<) $$(RFAIL_ARGS$(2)) + $$(Q)touch $$@ + +test/run-pass.stage$(2).out.tmp: test/compiletest.stage$(2)$$(X) \ + $$(RPASS_TESTS) + @$$(call E, run: $$<) + $$(Q)$$(call CFG_RUN_TEST,$$<) $$(RPASS_ARGS$(2)) + $$(Q)touch $$@ + +test/bench.stage$(2).out.tmp: test/compiletest.stage$(2)$$(X) \ + $$(BENCH_TESTS) + @$$(call E, run: $$<) + $$(Q)$$(call CFG_RUN_TEST,$$<) $$(BENCH_ARGS$(2)) + $$(Q)touch $$@ + +endef + +# Instantiate the template for stage 1, 2, 3 + +$(eval $(call TEST_STAGEN,0,1)) +$(eval $(call TEST_STAGEN,1,2)) +$(eval $(call TEST_STAGEN,2,3)) ###################################################################### @@ -210,182 +230,3 @@ test/$(FT_DRIVER)$(X): test/$(FT_DRIVER).rs stage2/lib/$(FT_LIB) $(SREQ2) test/$(FT_DRIVER).out: test/$(FT_DRIVER)$(X) $(SREQ2) $(Q)$(call CFG_RUN_TEST, $<) | tee $@ - - -###################################################################### -# Testing rules -###################################################################### - -tidy: - @$(call E, check: formatting) - $(Q)echo \ - $(filter-out $(GENERATED) $(addprefix $(S)src/, $(GENERATED)) \ - $(addprefix $(S)src/, $(RUSTLLVM_LIB_CS) $(RUSTLLVM_OBJS_CS) \ - $(RUSTLLVM_HDR) $(PKG_3RDPARTY)) \ - $(S)src/etc/%, $(PKG_FILES)) \ - | xargs -n 10 python $(S)src/etc/tidy.py - -%.stage0$(X): %.rs $(SREQ0) - @$(call E, compile_and_link: $@) - $(STAGE0) -o $@ $< - -%.stage0$(X): %.rc $(SREQ0) - @$(call E, compile_and_link: $@) - $(STAGE0) -o $@ $< - -%.stage1$(X): %.rs $(SREQ1) - @$(call E, compile_and_link: $@) - $(STAGE1) -o $@ $< - -%.stage1$(X): %.rc $(SREQ1) - @$(call E, compile_and_link: $@) - $(STAGE1) -o $@ $< - -%.stage2$(X): %.rs $(SREQ2) - @$(call E, compile_and_link: $@) - $(STAGE2) -o $@ $< - -%.stage2$(X): %.rc $(SREQ2) - @$(call E, compile_and_link: $@) - $(STAGE2) -o $@ $< - -# Cancel the implicit .out rule in GNU make. -%.out: % - -%.out: %.out.tmp - $(Q)mv $< $@ - -test/run-pass/%.out.tmp: test/run-pass/%$(X) rt/$(CFG_RUNTIME) - $(Q)rm -f $<.tmp - @$(call E, run: $@) - $(Q)$(call CFG_RUN_TEST, $<) > $@ - -test/bench/shootout/%.out.tmp: test/bench/shootout/%$(X) \ - rt/$(CFG_RUNTIME) - $(Q)rm -f $<.tmp - @$(call E, run: $@) - $(Q)$(call CFG_RUN_TEST, $<) > $@ - -test/bench/99-bottles/%.out.tmp: test/bench/99-bottles/%$(X) \ - rt/$(CFG_RUNTIME) - $(Q)rm -f $<.tmp - @$(call E, run: $@) - $(Q)$(call CFG_RUN_TEST, $<) > $@ - -test/run-fail/%.out.tmp: test/run-fail/%$(X) \ - rt/$(CFG_RUNTIME) - $(Q)rm -f $<.tmp - @$(call E, run-fail: $@) - $(Q)grep -q error-pattern $(S)src/test/run-fail/$(basename $*).rs - $(Q)rm -f $@ - $(Q)$(call CFG_RUN_TEST, $<) >$@ 2>&1 ; X=$$? ; \ - if [ $$X -eq 0 ] ; then exit 1 ; else exit 0 ; fi - $(Q)grep --text --quiet \ - "$$(grep error-pattern $(S)src/test/run-fail/$(basename $*).rs \ - | cut -d : -f 2- | tr -d '\n\r')" $@ - -test/compile-fail/%.stage0.out.tmp: test/compile-fail/%.rs $(SREQ0) - @$(call E, compile-fail [stage0]: $@) - $(Q)grep -q error-pattern $< - $(Q)rm -f $@ - $(STAGE0) -c -o $(@:.o=$(X)) $< >$@ 2>&1; test $$? -ne 0 - $(Q)grep --text --quiet \ - "$$(grep error-pattern $< | cut -d : -f 2- | tr -d '\n\r')" $@ - -test/compile-fail/%.stage1.out.tmp: test/compile-fail/%.rs $(SREQ1) - @$(call E, compile-fail [stage1]: $@) - $(Q)grep -q error-pattern $< - $(Q)rm -f $@ - $(STAGE1) -c -o $(@:.o=$(X)) $< >$@ 2>&1; test $$? -ne 0 - $(Q)grep --text --quiet \ - "$$(grep error-pattern $< | cut -d : -f 2- | tr -d '\n\r')" $@ - -test/compile-fail/%.stage2.out.tmp: test/compile-fail/%.rs $(SREQ2) - @$(call E, compile-fail [stage2]: $@) - $(Q)grep -q error-pattern $< - $(Q)rm -f $@ - $(STAGE2) -c -o $(@:.o=$(X)) $< >$@ 2>&1; test $$? -ne 0 - $(Q)grep --text --quiet \ - "$$(grep error-pattern $< | cut -d : -f 2- | tr -d '\n\r')" $@ - -test/compile-fail/%.stage0.out.tmp: test/compile-fail/%.rc $(SREQ0) - @$(call E, compile-fail [stage0]: $@) - $(Q)grep -q error-pattern $< - $(Q)rm -f $@ - $(STAGE0) -c -o $(@:.o=$(X)) $< >$@ 2>&1; test $$? -ne 0 - $(Q)grep --text --quiet \ - "$$(grep error-pattern $< | cut -d : -f 2- | tr -d '\n\r')" $@ - -test/compile-fail/%.stage1.out.tmp: test/compile-fail/%.rc $(SREQ1) - @$(call E, compile-fail [stage1]: $@) - $(Q)grep -q error-pattern $< - $(Q)rm -f $@ - $(STAGE1) -c -o $(@:.o=$(X)) $< >$@ 2>&1; test $$? -ne 0 - $(Q)grep --text --quiet \ - "$$(grep error-pattern $< | cut -d : -f 2- | tr -d '\n\r')" $@ - -test/compile-fail/%.stage2.out.tmp: test/compile-fail/%.rc $(SREQ2) - @$(call E, compile-fail [stage2]: $@) - $(Q)grep -q error-pattern $< - $(Q)rm -f $@ - $(STAGE2) -c -o $(@:.o=$(X)) $< >$@ 2>&1; test $$? -ne 0 - $(Q)grep --text --quiet \ - "$$(grep error-pattern $< | cut -d : -f 2- | tr -d '\n\r')" $@ - -# Testing the stdtest crate - -STDTEST_CRATE := $(S)src/test/stdtest/stdtest.rc -STDTEST_INPUTS := $(wildcard $(S)src/test/stdtest/*rs) - -test/stdtest.stage1$(X): $(STDTEST_CRATE) $(STDTEST_INPUTS) $(SREQ1) - @$(call E, compile_and_link: $@) - $(STAGE1) -o $@ $< --test - -test/stdtest.stage2$(X): $(STDTEST_CRATE) $(STDTEST_INPUTS) $(SREQ2) - @$(call E, compile_and_link: $@) - $(STAGE2) -o $@ $< --test - -test/stdtest.stage3$(X): $(STDTEST_CRATE) $(STDTEST_INPUTS) $(SREQ3) - @$(call E, compile_and_link: $@) - $(STAGE3) -o $@ $< --test - -check-stage1-std:test/stdtest.stage1$(X) - @$(call E, run: $<) - $(Q)$(call CFG_RUN_TARG,stage1, $<) - -check-stage2-std:test/stdtest.stage2$(X) - @$(call E, run: $<) - $(Q)$(call CFG_RUN_TARG,stage2, $<) - -check-stage3-std:test/stdtest.stage3$(X) - @$(call E, run: $<) - $(Q)$(call CFG_RUN_TARG,stage3, $<) - -# Testing the rustctest crate - -test/rustctest.stage1$(X): $(COMPILER_CRATE) $(COMPILER_INPUTS) $(SREQ0) \ - stage0/intrinsics.bc - @$(call E, compile_and_link: $@) - $(STAGE0) -o $@ $< --test - -test/rustctest.stage2$(X): $(COMPILER_CRATE) $(COMPILER_INPUTS) $(SREQ1) \ - stage1/intrinsics.bc - @$(call E, compile_and_link: $@) - $(STAGE1) -o $@ $< --test - -test/rustctest.stage3$(X): $(COMPILER_CRATE) $(COMPILER_INPUTS) $(SREQ2) \ - stage2/intrinsics.bc - @$(call E, compile_and_link: $@) - $(STAGE2) -o $@ $< --test - -check-stage1-rustc: test/rustctest.stage1$(X) - @$(call E, run: $<) - $(Q)$(call CFG_RUN_TARG,stage1, $<) - -check-stage2-rustc: test/rustctest.stage2$(X) - @$(call E, run: $<) - $(Q)$(call CFG_RUN_TARG,stage2, $<) - -check-stage3-rustc: test/rustctest.stage3$(X) - @$(call E, run: $<) - $(Q)$(call CFG_RUN_TARG,stage2, $<) diff --git a/src/lib/test.rs b/src/lib/test.rs index 678c7ae07d9..37a2a2cb3e2 100644 --- a/src/lib/test.rs +++ b/src/lib/test.rs @@ -14,6 +14,7 @@ export test_opts; export tr_ok; export tr_failed; export tr_ignored; +export run_tests_console; export run_test; export filter_tests; export parse_opts; @@ -51,7 +52,7 @@ fn test_main(&vec[str] args, &test_desc[] tests) { either::left(?o) { o } either::right(?m) { fail m } }; - if (!run_tests(opts, tests)) { + if (!run_tests_console(opts, tests)) { fail "Some tests failed"; } } @@ -94,7 +95,7 @@ tag test_result { } // A simple console test runner -fn run_tests(&test_opts opts, &test_desc[] tests) -> bool { +fn run_tests_console(&test_opts opts, &test_desc[] tests) -> bool { auto filtered_tests = filter_tests(opts, tests); diff --git a/src/test/bench/99-bottles/99bob-iter.rs b/src/test/bench/99bob-iter.rs similarity index 100% rename from src/test/bench/99-bottles/99bob-iter.rs rename to src/test/bench/99bob-iter.rs diff --git a/src/test/bench/99-bottles/99bob-pattern.rs b/src/test/bench/99bob-pattern.rs similarity index 100% rename from src/test/bench/99-bottles/99bob-pattern.rs rename to src/test/bench/99bob-pattern.rs diff --git a/src/test/bench/99-bottles/99bob-simple.rs b/src/test/bench/99bob-simple.rs similarity index 100% rename from src/test/bench/99-bottles/99bob-simple.rs rename to src/test/bench/99bob-simple.rs diff --git a/src/test/bench/99-bottles/99bob-tail.rs b/src/test/bench/99bob-tail.rs similarity index 100% rename from src/test/bench/99-bottles/99bob-tail.rs rename to src/test/bench/99bob-tail.rs diff --git a/src/test/bench/shootout/ackermann.rs b/src/test/bench/shootout-ackermann.rs similarity index 100% rename from src/test/bench/shootout/ackermann.rs rename to src/test/bench/shootout-ackermann.rs diff --git a/src/test/bench/shootout/binarytrees.rs b/src/test/bench/shootout-binarytrees.rs similarity index 100% rename from src/test/bench/shootout/binarytrees.rs rename to src/test/bench/shootout-binarytrees.rs diff --git a/src/test/bench/shootout/fannkuchredux.rs b/src/test/bench/shootout-fannkuchredux.rs similarity index 100% rename from src/test/bench/shootout/fannkuchredux.rs rename to src/test/bench/shootout-fannkuchredux.rs diff --git a/src/test/bench/shootout/fasta.rs b/src/test/bench/shootout-fasta.rs similarity index 100% rename from src/test/bench/shootout/fasta.rs rename to src/test/bench/shootout-fasta.rs diff --git a/src/test/bench/shootout/fibo.rs b/src/test/bench/shootout-fibo.rs similarity index 100% rename from src/test/bench/shootout/fibo.rs rename to src/test/bench/shootout-fibo.rs diff --git a/src/test/bench/shootout/nbody.rs b/src/test/bench/shootout-nbody.rs similarity index 100% rename from src/test/bench/shootout/nbody.rs rename to src/test/bench/shootout-nbody.rs diff --git a/src/test/bench/task-perf/pfib.rs b/src/test/bench/shootout-pfib.rs similarity index 98% rename from src/test/bench/task-perf/pfib.rs rename to src/test/bench/shootout-pfib.rs index ce56eafeb21..09dcf6ec713 100644 --- a/src/test/bench/task-perf/pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -90,9 +90,7 @@ fn stress(int num_tasks) { fn main(vec[str] argv) { if(vec::len(argv) == 1u) { assert (fib(8) == 21); - assert (fib(15) == 610); log fib(8); - log fib(15); } else { // Interactive mode! Wooo!!!! diff --git a/src/test/bench/shootout/pfib.rs b/src/test/bench/shootout/pfib.rs deleted file mode 100644 index 44197a9acdb..00000000000 --- a/src/test/bench/shootout/pfib.rs +++ /dev/null @@ -1,69 +0,0 @@ -// -*- rust -*- - -/* - A parallel version of fibonacci numbers. -*/ - -use std; - -import std::vec; -import std::uint; -import std::time; -import std::str; - -fn recv[T](&port[T] p) -> T { - let T x; - p |> x; - ret x; -} - -fn fib(int n) -> int { - fn pfib(chan[int] c, int n) { - if (n == 0) { - c <| 0; - } - else if (n <= 2) { - c <| 1; - } - else { - let port[int] p = port(); - - auto t1 = spawn pfib(chan(p), n - 1); - auto t2 = spawn pfib(chan(p), n - 2); - - c <| recv(p) + recv(p); - } - } - - let port[int] p = port(); - auto t = spawn pfib(chan(p), n); - ret recv(p); -} - -fn main(vec[str] argv) { - if(vec::len(argv) == 1u) { - assert (fib(8) == 21); - //assert (fib(15) == 610); - log fib(8); - //log fib(15); - } - else { - // Interactive mode! Wooo!!!! - - auto n = uint::parse_buf(str::bytes(argv.(1)), 10u) as int; - auto start = time::precise_time_ns(); - auto fibn = fib(n); - auto stop = time::precise_time_ns(); - - assert(stop >= start); - - auto elapsed = stop - start; - auto us_task = elapsed / (fibn as u64) / (1000 as u64); - - log_err #fmt("Determined that fib(%d) = %d in %d%d ns (%d us / task)", - n, fibn, - (elapsed / (1000000 as u64)) as int, - (elapsed % (1000000 as u64)) as int, - us_task as int); - } -} diff --git a/src/test/bench/task-perf/word-count.rs b/src/test/bench/task-perf-word-count.rs similarity index 99% rename from src/test/bench/task-perf/word-count.rs rename to src/test/bench/task-perf-word-count.rs index a5b5641563b..e3cc3a3c409 100644 --- a/src/test/bench/task-perf/word-count.rs +++ b/src/test/bench/task-perf-word-count.rs @@ -1,3 +1,6 @@ +// xfail-stage1 +// xfail-stage2 +// xfail-stage3 /** A parallel word-frequency counting program. diff --git a/src/test/compile-fail/attr-bad-meta.rs b/src/test/compile-fail/attr-bad-meta.rs index 01ca127553d..85714affba6 100644 --- a/src/test/compile-fail/attr-bad-meta.rs +++ b/src/test/compile-fail/attr-bad-meta.rs @@ -1,5 +1,5 @@ // xfail-stage0 -// error-pattern:expecting \] +// error-pattern:expecting ] // asterisk is bogus #[attr*] diff --git a/src/test/compile-fail/binop-bitxor-str.rs b/src/test/compile-fail/binop-bitxor-str.rs index d66a3696638..b22b35cf28e 100644 --- a/src/test/compile-fail/binop-bitxor-str.rs +++ b/src/test/compile-fail/binop-bitxor-str.rs @@ -1,5 +1,5 @@ // xfail-stage0 -// error-pattern:\^ cannot be applied to type `str` +// error-pattern:^ cannot be applied to type `str` fn main() { auto x = "a" ^ "b"; diff --git a/src/test/compile-fail/binop-shift-port.rs b/src/test/compile-fail/binop-shift-port.rs index 8c06de847b0..e4a6f31e896 100644 --- a/src/test/compile-fail/binop-shift-port.rs +++ b/src/test/compile-fail/binop-shift-port.rs @@ -1,5 +1,5 @@ // xfail-stage0 -// error-pattern:>> cannot be applied to type `port\[int\]` +// error-pattern:>> cannot be applied to type `port[int]` fn main() { let port[int] p1 = port(); diff --git a/src/test/compile-fail/binop-sub-obj.rs b/src/test/compile-fail/binop-sub-obj.rs index 54f5584bb6f..3b68b0879b5 100644 --- a/src/test/compile-fail/binop-sub-obj.rs +++ b/src/test/compile-fail/binop-sub-obj.rs @@ -1,5 +1,5 @@ // xfail-stage0 -// error-pattern:\- cannot be applied to type `obj +// error-pattern:- cannot be applied to type `obj fn main() { auto x = obj(){} - obj(){}; diff --git a/src/test/compile-fail/ext-after-attrib.rs b/src/test/compile-fail/ext-after-attrib.rs index 31786fcaf65..446fb836717 100644 --- a/src/test/compile-fail/ext-after-attrib.rs +++ b/src/test/compile-fail/ext-after-attrib.rs @@ -1,5 +1,5 @@ // xfail-stage0 -// error-pattern:expecting \[, found fmt +// error-pattern:expecting [, found fmt // Don't know how to deal with a syntax extension appearing after an // item attribute. Probably could use a better error message. diff --git a/src/test/compile-fail/type-mismatch-multiple.rs b/src/test/compile-fail/type-mismatch-multiple.rs new file mode 100644 index 00000000000..10f7fc0e242 --- /dev/null +++ b/src/test/compile-fail/type-mismatch-multiple.rs @@ -0,0 +1,8 @@ +// Checking that the compiler reports multiple type errors at once +// error-pattern:mismatched types: expected bool +// error-pattern:mismatched types: expected int + +fn main() { + let bool a = 1; + let int b = true; +} \ No newline at end of file diff --git a/src/test/compile-fail/vec-field.rs b/src/test/compile-fail/vec-field.rs index f1e4cfbc0ee..8c3f0c30515 100644 --- a/src/test/compile-fail/vec-field.rs +++ b/src/test/compile-fail/vec-field.rs @@ -1,5 +1,5 @@ // xfail-stage0 -// error-pattern:attempted field access on type vec\[int\] +// error-pattern:attempted field access on type vec[int] // issue #367 fn f() { diff --git a/src/test/compiletest/compiletest.rc b/src/test/compiletest/compiletest.rc new file mode 100644 index 00000000000..b2c1f4662c2 --- /dev/null +++ b/src/test/compiletest/compiletest.rc @@ -0,0 +1,11 @@ +use std; + +mod compiletest; + +// Local Variables: +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: diff --git a/src/test/compiletest/compiletest.rs b/src/test/compiletest/compiletest.rs new file mode 100644 index 00000000000..ae6f229fc81 --- /dev/null +++ b/src/test/compiletest/compiletest.rs @@ -0,0 +1,529 @@ +import std::option; +import std::getopts; +import std::test; +import std::fs; +import std::str; +import std::vec; +import std::ivec; +import std::io; +import std::generic_os::setenv; +import std::generic_os::getenv; +import std::os; +import std::run; + +tag mode { + mode_compile_fail; + mode_run_fail; + mode_run_pass; +} + +type config = rec(// The library paths required for running the compiler + str compile_lib_path, + // The library paths required for running compiled programs + str run_lib_path, + // The rustc executable + str rustc_path, + // The directory containing the tests to run + str src_base, + // The directory where programs should be built + str build_base, + // The name of the stage being built (stage1, etc) + str stage_id, + // The test mode, compile-fail, run-fail, run-pass + mode mode, + // Run ignored tests + bool run_ignored, + // Only run tests that match this filter + option::t[str] filter, + // A command line to prefix program execution with, + // for running under valgrind + option::t[str] runtool, + // Flags to pass to the compiler + option::t[str] rustcflags, + // Explain what's going on + bool verbose); + +fn main(vec[str] args) { + + auto ivec_args = { + auto ivec_args = ~[]; + for (str arg in args) { + ivec_args += ~[arg]; + } + ivec_args + }; + + auto config = parse_config(ivec_args); + log_config(config); + run_tests(config); +} + +fn parse_config(&str[] args) -> config { + auto opts = ~[getopts::reqopt("compile-lib-path"), + getopts::reqopt("run-lib-path"), + getopts::reqopt("rustc-path"), + getopts::reqopt("src-base"), + getopts::reqopt("build-base"), + getopts::reqopt("stage-id"), + getopts::reqopt("mode"), + getopts::optflag("ignored"), + getopts::optopt("runtool"), + getopts::optopt("rustcflags"), + getopts::optflag("verbose")]; + + check ivec::is_not_empty(args); + auto args_ = ivec::tail(args); + auto match = alt (getopts::getopts_ivec(args_, opts)) { + getopts::success(?m) { m } + getopts::failure(?f) { + fail getopts::fail_str(f) + } + }; + + ret rec(compile_lib_path = getopts::opt_str(match, "compile-lib-path"), + run_lib_path = getopts::opt_str(match, "run-lib-path"), + rustc_path = getopts::opt_str(match, "rustc-path"), + src_base = getopts::opt_str(match, "src-base"), + build_base = getopts::opt_str(match, "build-base"), + stage_id = getopts::opt_str(match, "stage-id"), + mode = alt getopts::opt_str(match, "mode") { + "compile-fail" { mode_compile_fail } + "run-fail" { mode_run_fail } + "run-pass" { mode_run_pass } + _ { fail "invalid mode" } + }, + run_ignored = getopts::opt_present(match, "ignored"), + filter = if vec::len(match.free) > 0u { + option::some(match.free.(0)) + } else { + option::none + }, + runtool = getopts::opt_maybe_str(match, "runtool"), + rustcflags = getopts::opt_maybe_str(match, "rustcflags"), + verbose = getopts::opt_present(match, "verbose")); +} + +fn log_config(&config config) { + auto c = config; + logv(c, #fmt("configuration:")); + logv(c, #fmt("compile_lib_path: %s", config.compile_lib_path)); + logv(c, #fmt("run_lib_path: %s", config.run_lib_path)); + logv(c, #fmt("rustc_path: %s", config.rustc_path)); + logv(c, #fmt("src_base: %s", config.src_base));; + logv(c, #fmt("build_base: %s", config.build_base)); + logv(c, #fmt("stage_id: %s", config.stage_id)); + logv(c, #fmt("mode: %s", mode_str(config.mode))); + logv(c, #fmt("run_ignored: %b", config.run_ignored)); + logv(c, #fmt("filter: %s", alt (config.filter) { + option::some(?f) { f } + option::none { "(none)" } + })); + logv(c, #fmt("runtool: %s", alt (config.runtool) { + option::some(?s) { s } + option::none { "(none)" } + })); + logv(c, #fmt("rustcflags: %s", alt (config.rustcflags) { + option::some(?s) { s } + option::none { "(none)" } + })); + logv(c, #fmt("verbose: %b", config.verbose)); + logv(c, #fmt("\n")); +} + +fn mode_str(mode mode) -> str { + alt (mode) { + mode_compile_fail { "compile-fail" } + mode_run_fail { "run-fail" } + mode_run_pass { "run-pass" } + } +} + +fn run_tests(&config config) { + auto opts = test_opts(config); + auto tests = make_tests(config); + test::run_tests_console(opts, tests); +} + +fn test_opts(&config config) -> test::test_opts { + rec(filter = config.filter, + run_ignored = config.run_ignored) +} + +fn make_tests(&config config) -> test::test_desc[] { + log #fmt("making tests from %s", config.src_base); + auto tests = ~[]; + for (str file in fs::list_dir(config.src_base)) { + log #fmt("inspecting file %s", file); + if (is_test(file)) { + tests += ~[make_test(config, file)]; + } + } + ret tests; +} + +fn is_test(&str testfile) -> bool { + str::ends_with(testfile, ".rs") || str::ends_with(testfile, ".rc") +} + +fn make_test(&config config, &str testfile) -> test::test_desc { + rec(name = testfile, + fn = make_test_fn(config, testfile), + ignore = is_test_ignored(config, testfile)) +} + +fn is_test_ignored(&config config, &str testfile) -> bool { + auto found = false; + for each (str ln in iter_header(testfile)) { + // FIXME: Can't return or break from iterator + found = found || parse_name_directive(ln, "xfail-" + config.stage_id); + } + ret found; +} + +iter iter_header(&str testfile) -> str { + auto rdr = io::file_reader(testfile); + while !rdr.eof() { + auto ln = rdr.read_line(); + // Assume that any directives will be found before the + // first module or function. This doesn't seem to be an optimization + // with a warm page cache. Maybe with a cold one. + if str::starts_with(ln, "fn") || str::starts_with(ln, "mod") { + break; + } else { + put ln; + } + } +} + +fn make_test_fn(&config config, &str testfile) -> test::test_fn { + bind run_test(config, testfile) +} + +fn run_test(config config, str testfile) { + log #fmt("running %s", testfile); + auto props = load_props(testfile); + alt (config.mode) { + mode_compile_fail { + run_cfail_test(config, props, testfile); + } + mode_run_fail { + run_rfail_test(config, props, testfile); + } + mode_run_pass { + run_rpass_test(config, props, testfile); + } + } +} + +type test_props = rec(str[] error_patterns, + option::t[str] compile_flags); + +// Load any test directives embedded in the file +fn load_props(&str testfile) -> test_props { + auto error_patterns = ~[]; + auto compile_flags = option::none; + for each (str ln in iter_header(testfile)) { + alt parse_error_pattern(ln) { + option::some(?ep) { error_patterns += ~[ep]; } + option::none { } + } + + if option::is_none(compile_flags) { + compile_flags = parse_compile_flags(ln); + } + } + ret rec(error_patterns = error_patterns, + compile_flags = compile_flags); +} + +fn parse_error_pattern(&str line) -> option::t[str] { + parse_name_value_directive(line, "error-pattern") +} + +fn parse_compile_flags(&str line) -> option::t[str] { + parse_name_value_directive(line, "compile-flags") +} + +fn parse_name_directive(&str line, &str directive) -> bool { + str::find(line, directive) >= 0 +} + +fn parse_name_value_directive(&str line, &str directive) -> option::t[str] { + auto keycolon = directive + ":"; + if str::find(line, keycolon) >= 0 { + auto colon = str::find(line, keycolon) as uint; + auto value = str::slice(line, + colon + str::byte_len(keycolon), + str::byte_len(line)); + log #fmt("%s: %s", directive, value); + option::some(value) + } else { + option::none + } +} + +fn run_cfail_test(&config config, &test_props props, &str testfile) { + auto procres = compile_test(config, props, testfile); + + if (procres.status == 0) { + fatal_procres("compile-fail test compiled successfully!", procres); + } + + check_error_patterns(props, testfile, procres); +} + +fn run_rfail_test(&config config, &test_props props, &str testfile) { + auto procres = compile_test(config, props, testfile); + + if (procres.status != 0) { + fatal_procres("compilation failed!", procres); + } + + procres = exec_compiled_test(config, testfile); + + if (procres.status == 0) { + fatal_procres("run-fail test didn't produce an error!", + procres); + } + + check_error_patterns(props, testfile, procres); +} + +fn run_rpass_test(&config config, &test_props props, &str testfile) { + auto procres = compile_test(config, props, testfile); + + if (procres.status != 0) { + fatal_procres("compilation failed!", procres); + } + + procres = exec_compiled_test(config, testfile); + + if (procres.status != 0) { + fatal_procres("test run failed!", procres); + } +} + +fn check_error_patterns(&test_props props, &str testfile, + &procres procres) { + if ivec::is_empty(props.error_patterns) { + fatal("no error pattern specified in " + testfile); + } + + auto next_err_idx = 0u; + auto next_err_pat = props.error_patterns.(next_err_idx); + for (str line in str::split(procres.out, '\n' as u8)) { + if (str::find(line, next_err_pat) > 0) { + log #fmt("found error pattern %s", next_err_pat); + next_err_idx += 1u; + if next_err_idx == ivec::len(props.error_patterns) { + log "found all error patterns"; + ret; + } + next_err_pat = props.error_patterns.(next_err_idx); + } + } + + auto missing_patterns = ivec::slice(props.error_patterns, + next_err_idx, + ivec::len(props.error_patterns)); + if (ivec::len(missing_patterns) == 1u) { + fatal_procres(#fmt("error pattern '%s' not found!", + missing_patterns.(0)), + procres); + } else { + for (str pattern in missing_patterns) { + error(#fmt("error pattern '%s' not found!", pattern)); + } + fatal_procres("multiple error patterns not found", procres); + } +} + +type procargs = rec(str prog, vec[str] args); + +type procres = rec(int status, str out, str cmdline); + +fn compile_test(&config config, &test_props props, + &str testfile) -> procres { + compose_and_run(config, + testfile, + bind make_compile_args(_, props, _), + config.compile_lib_path) +} + +fn exec_compiled_test(&config config, &str testfile) -> procres { + compose_and_run(config, + testfile, + make_run_args, + config.run_lib_path) +} + +fn compose_and_run(&config config, &str testfile, + fn(&config, &str) -> procargs make_args, + &str lib_path) -> procres { + auto procargs = make_args(config, testfile); + ret program_output(config, testfile, lib_path, + procargs.prog, procargs.args); +} + +fn make_compile_args(&config config, &test_props props, + &str testfile) -> procargs { + auto prog = config.rustc_path; + auto args = [testfile, + "-o", make_exe_name(config, testfile)]; + args += split_maybe_args(config.rustcflags); + args += split_maybe_args(props.compile_flags); + ret rec(prog = prog, + args = args); +} + +fn make_run_args(&config config, &str testfile) -> procargs { + // If we've got another tool to run under (valgrind), + // then split apart its command + auto args = split_maybe_args(config.runtool) + + [make_exe_name(config, testfile)]; + ret rec(prog = args.(0), + args = vec::slice(args, 1u, vec::len(args))); +} + +fn split_maybe_args(&option::t[str] argstr) -> vec[str] { + alt (argstr) { + option::some(?s) { str::split(s, ' ' as u8) } + option::none { [] } + } +} + +fn program_output(&config config, &str testfile, + &str lib_path, &str prog, &vec[str] args) -> procres { + auto cmdline = { + auto cmdline = make_cmdline(lib_path, prog, args); + logv(config, #fmt("running %s", cmdline)); + cmdline + }; + auto res = with_lib_path(lib_path, + bind run::program_output(prog, args)); + dump_output(config, testfile, res.out); + ret rec(status = res.status, + out = res.out, + cmdline = cmdline); +} + +fn make_cmdline(&str libpath, &str prog, &vec[str] args) -> str { + #fmt("%s %s %s", + lib_path_cmd_prefix(libpath), + prog, + str::connect(args, " ")) +} + +// Build the LD_LIBRARY_PATH variable as it would be seen on the command line +// for diagnostic purposes +fn lib_path_cmd_prefix(&str path) -> str { + #fmt("%s=\"%s\"", lib_path_env_var(), make_new_path(path)) +} + +fn with_lib_path[T](&str path, fn() -> T f) -> T { + auto maybe_oldpath = getenv(lib_path_env_var()); + append_lib_path(path); + auto res = f(); + if option::is_some(maybe_oldpath) { + export_lib_path(option::get(maybe_oldpath)); + } else { + // FIXME: This should really be unset but we don't have that yet + export_lib_path(""); + } + ret res; +} + +fn append_lib_path(&str path) { + export_lib_path(make_new_path(path)); +} + +fn make_new_path(&str path) -> str { + // Windows just uses PATH as the library search path, so we have to + // maintain the current value while adding our own + alt getenv(lib_path_env_var()) { + option::some(?curr) { #fmt("%s:%s", path, curr) } + option::none { path } + } +} + +fn export_lib_path(&str path) { + setenv(lib_path_env_var(), path); +} + +#[cfg(target_os = "linux")] +fn lib_path_env_var() -> str { "LD_LIBRARY_PATH" } + +#[cfg(target_os = "macos")] +fn lib_path_env_var() -> str { "DYLD_LIBRARY_PATH" } + +#[cfg(target_os = "win32")] +fn lib_path_env_var() -> str { "PATH" } + +fn make_exe_name(&config config, &str testfile) -> str { + output_base_name(config, testfile) + os::exec_suffix() +} + +fn output_base_name(&config config, &str testfile) -> str { + auto base = config.build_base; + auto filename = { + auto parts = str::split(fs::basename(testfile), '.' as u8); + parts = vec::slice(parts, 0u, vec::len(parts) - 1u); + str::connect(parts, ".") + }; + #fmt("%s%s.%s", base, filename, config.stage_id) +} + +#[cfg(target_os = "win32")] +#[cfg(target_os = "linux")] +fn dump_output(&config config, &str testfile, &str out) { + auto outfile = make_out_name(config, testfile); + auto writer = io::file_writer(outfile, [io::create, io::truncate]); + writer.write_str(out); +} + +// FIXME (726): Can't use file_writer on mac +#[cfg(target_os = "macos")] +fn dump_output(&config config, &str testfile, &str out) { +} + +fn make_out_name(&config config, &str testfile) -> str { + output_base_name(config, testfile) + ".out" +} + +fn error(&str err) { + io::stdout().write_line(#fmt("\nerror: %s", err)); +} + +fn fatal(&str err) -> ! { + error(err); + fail; +} + +fn fatal_procres(&str err, procres procres) -> ! { + auto msg = #fmt("\n\ + error: %s\n\ + command: %s\n\ + output:\n\ + ------------------------------------------\n\ + %s\n\ + ------------------------------------------\n\ + \n", + err, procres.cmdline, procres.out); + io::stdout().write_str(msg); + fail; +} + +fn logv(&config config, &str s) { + log s; + if (config.verbose) { + io::stdout().write_line(s); + } +} + +// Local Variables: +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: diff --git a/src/test/run-pass/lib-int.rs b/src/test/run-pass/lib-int.rs deleted file mode 100644 index f5f52e2092b..00000000000 --- a/src/test/run-pass/lib-int.rs +++ /dev/null @@ -1,28 +0,0 @@ - -use std; -import std::int; -import std::str::eq; - -fn test_to_str() { - assert (eq(int::to_str(0, 10u), "0")); - assert (eq(int::to_str(1, 10u), "1")); - assert (eq(int::to_str(-1, 10u), "-1")); - assert (eq(int::to_str(255, 16u), "ff")); - assert (eq(int::to_str(100, 10u), "100")); -} - -fn test_pow() { - assert (int::pow(0, 0u) == 1); - assert (int::pow(0, 1u) == 0); - assert (int::pow(0, 2u) == 0); - assert (int::pow(-1, 0u) == 1); - assert (int::pow(1, 0u) == 1); - assert (int::pow(-3, 2u) == 9); - assert (int::pow(-3, 3u) == -27); - assert (int::pow(4, 9u) == 262144); -} - -fn main() { - test_to_str(); - test_pow(); -} \ No newline at end of file diff --git a/src/test/run-pass/lib-option.rs b/src/test/run-pass/lib-option.rs deleted file mode 100644 index 9b706cc60f8..00000000000 --- a/src/test/run-pass/lib-option.rs +++ /dev/null @@ -1,4 +0,0 @@ - -use std; - -fn main() { auto x = std::option::some[int](10); } \ No newline at end of file diff --git a/src/test/run-pass/lib-sha1.rs b/src/test/run-pass/lib-sha1.rs deleted file mode 100644 index bfb59453eb1..00000000000 --- a/src/test/run-pass/lib-sha1.rs +++ /dev/null @@ -1,90 +0,0 @@ - - -// -*- rust -*- - -// xfail-stage0 -use std; -import std::sha1; -import std::vec; -import std::str; - -fn main() { - type test = rec(str input, vec[u8] output); - - fn a_million_letter_a() -> str { - auto i = 0; - auto rs = ""; - while (i < 100000) { rs += "aaaaaaaaaa"; i += 1; } - ret rs; - } - // Test messages from FIPS 180-1 - - let vec[test] fips_180_1_tests = - [rec(input="abc", - output=[0xA9u8, 0x99u8, 0x3Eu8, 0x36u8, 0x47u8, 0x06u8, 0x81u8, - 0x6Au8, 0xBAu8, 0x3Eu8, 0x25u8, 0x71u8, 0x78u8, 0x50u8, - 0xC2u8, 0x6Cu8, 0x9Cu8, 0xD0u8, 0xD8u8, 0x9Du8]), - rec(input="abcdbcdecdefdefgefghfghighij" + - "hijkijkljklmklmnlmnomnopnopq", - output=[0x84u8, 0x98u8, 0x3Eu8, 0x44u8, 0x1Cu8, 0x3Bu8, 0xD2u8, - 0x6Eu8, 0xBAu8, 0xAEu8, 0x4Au8, 0xA1u8, 0xF9u8, 0x51u8, - 0x29u8, 0xE5u8, 0xE5u8, 0x46u8, 0x70u8, 0xF1u8]), - rec(input=a_million_letter_a(), - output=[0x34u8, 0xAAu8, 0x97u8, 0x3Cu8, 0xD4u8, 0xC4u8, 0xDAu8, - 0xA4u8, 0xF6u8, 0x1Eu8, 0xEBu8, 0x2Bu8, 0xDBu8, 0xADu8, - 0x27u8, 0x31u8, 0x65u8, 0x34u8, 0x01u8, 0x6Fu8])]; - // Examples from wikipedia - - let vec[test] wikipedia_tests = - [rec(input="The quick brown fox jumps over the lazy dog", - output=[0x2fu8, 0xd4u8, 0xe1u8, 0xc6u8, 0x7au8, 0x2du8, 0x28u8, - 0xfcu8, 0xedu8, 0x84u8, 0x9eu8, 0xe1u8, 0xbbu8, 0x76u8, - 0xe7u8, 0x39u8, 0x1bu8, 0x93u8, 0xebu8, 0x12u8]), - rec(input="The quick brown fox jumps over the lazy cog", - output=[0xdeu8, 0x9fu8, 0x2cu8, 0x7fu8, 0xd2u8, 0x5eu8, 0x1bu8, - 0x3au8, 0xfau8, 0xd3u8, 0xe8u8, 0x5au8, 0x0bu8, 0xd1u8, - 0x7du8, 0x9bu8, 0x10u8, 0x0du8, 0xb4u8, 0xb3u8])]; - auto tests = fips_180_1_tests + wikipedia_tests; - fn check_vec_eq(vec[u8] v0, vec[u8] v1) { - assert (vec::len[u8](v0) == vec::len[u8](v1)); - auto len = vec::len[u8](v0); - auto i = 0u; - while (i < len) { - auto a = v0.(i); - auto b = v1.(i); - assert (a == b); - i += 1u; - } - } - // Test that it works when accepting the message all at once - - auto sh = sha1::mk_sha1(); - for (test t in tests) { - sh.input_str(t.input); - auto out = sh.result(); - check_vec_eq(t.output, out); - sh.reset(); - } - - // Test that it works when accepting the message in pieces - for (test t in tests) { - auto len = str::byte_len(t.input); - auto left = len; - while (left > 0u) { - auto take = (left + 1u) / 2u; - sh.input_str(str::substr(t.input, len - left, take)); - left = left - take; - } - auto out = sh.result(); - check_vec_eq(t.output, out); - sh.reset(); - } -} -// Local Variables: -// mode: rust; -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; -// End: diff --git a/src/test/run-pass/test-runner-hides-main.rs b/src/test/run-pass/test-runner-hides-main.rs new file mode 100644 index 00000000000..2b48e450bef --- /dev/null +++ b/src/test/run-pass/test-runner-hides-main.rs @@ -0,0 +1,10 @@ +// compile-flags:--test +// xfail-fast + +use std; + +// Building as a test runner means that a synthetic main will be run, +// not ours +fn main() { + fail; +} \ No newline at end of file diff --git a/src/test/run-pass/lib-bitv.rs b/src/test/stdtest/bitv.rs similarity index 98% rename from src/test/run-pass/lib-bitv.rs rename to src/test/stdtest/bitv.rs index e92d47f52d6..a550136ec2c 100644 --- a/src/test/run-pass/lib-bitv.rs +++ b/src/test/stdtest/bitv.rs @@ -3,6 +3,7 @@ use std; import std::vec; import std::bitv; +#[test] fn test_0_elements() { auto act; auto exp; @@ -13,6 +14,7 @@ fn test_0_elements() { assert (bitv::eq_vec(act, exp)); } +#[test] fn test_1_element() { auto act; act = bitv::create(1u, false); @@ -21,6 +23,7 @@ fn test_1_element() { assert (bitv::eq_vec(act, [1u])); } +#[test] fn test_10_elements() { auto act; // all 0 @@ -59,6 +62,7 @@ fn test_10_elements() { assert (bitv::eq_vec(act, [1u, 0u, 0u, 1u, 0u, 0u, 1u, 0u, 0u, 1u])); } +#[test] fn test_31_elements() { auto act; // all 0 @@ -131,6 +135,7 @@ fn test_31_elements() { 0u, 0u, 0u, 0u, 1u])); } +#[test] fn test_32_elements() { auto act; // all 0 @@ -205,6 +210,7 @@ fn test_32_elements() { 0u, 0u, 0u, 0u, 1u, 1u])); } +#[test] fn test_33_elements() { auto act; // all 0 @@ -280,11 +286,3 @@ fn test_33_elements() { 0u, 0u, 0u, 0u, 1u, 1u, 1u])); } -fn main() { - test_0_elements(); - test_1_element(); - test_10_elements(); - test_31_elements(); - test_32_elements(); - test_33_elements(); -} \ No newline at end of file diff --git a/src/test/run-pass/lib-box.rs b/src/test/stdtest/box.rs similarity index 90% rename from src/test/run-pass/lib-box.rs rename to src/test/stdtest/box.rs index b054d217d4b..6b2d199ca6f 100644 --- a/src/test/run-pass/lib-box.rs +++ b/src/test/stdtest/box.rs @@ -2,7 +2,8 @@ use std; import std::box; -fn main() { +#[test] +fn test() { auto x = @3; auto y = @3; assert (box::ptr_eq[int](x, x)); diff --git a/src/test/run-pass/lib-deque.rs b/src/test/stdtest/deque.rs similarity index 98% rename from src/test/run-pass/lib-deque.rs rename to src/test/stdtest/deque.rs index e4aa41c27b0..0a66ab39daa 100644 --- a/src/test/run-pass/lib-deque.rs +++ b/src/test/stdtest/deque.rs @@ -4,6 +4,7 @@ use std; import std::deque; +#[test] fn test_simple() { let deque::t[int] d = deque::create[int](); assert (d.size() == 0u); @@ -116,7 +117,8 @@ tag taggypar[T] { onepar(int); twopar(int, int); threepar(int, int, int); } type reccy = rec(int x, int y, taggy t); -fn main() { +#[test] +fn test() { fn inteq(&int a, &int b) -> bool { ret a == b; } fn intboxeq(&@int a, &@int b) -> bool { ret a == b; } fn taggyeq(&taggy a, &taggy b) -> bool { @@ -170,10 +172,6 @@ fn main() { fn reccyeq(&reccy a, &reccy b) -> bool { ret a.x == b.x && a.y == b.y && taggyeq(a.t, b.t); } - log "*** starting"; - log "*** test simple"; - test_simple(); - log "*** end test simple"; log "*** test boxes"; test_boxes(@5, @72, @64, @175); log "*** end test boxes"; diff --git a/src/test/run-pass/lib-either.rs b/src/test/stdtest/either.rs similarity index 88% rename from src/test/run-pass/lib-either.rs rename to src/test/stdtest/either.rs index 047c7289670..0d1fd4353ea 100644 --- a/src/test/run-pass/lib-either.rs +++ b/src/test/stdtest/either.rs @@ -1,9 +1,8 @@ -// xfail-stage0 - use std; import std::either::*; import std::ivec::len; +#[test] fn test_either_left() { auto val = left(10); fn f_left(&int x) -> bool { x == 10 } @@ -11,6 +10,7 @@ fn test_either_left() { assert (either(f_left, f_right, val)); } +#[test] fn test_either_right() { auto val = right(10u); fn f_left(&int x) -> bool { false } @@ -18,6 +18,7 @@ fn test_either_right() { assert (either(f_left, f_right, val)); } +#[test] fn test_lefts() { auto input = ~[left(10), right(11), @@ -28,6 +29,7 @@ fn test_lefts() { assert (result == ~[10, 12, 14]); } +#[test] fn test_lefts_none() { let (t[int, int])[] input = ~[right(10), right(10)]; @@ -35,12 +37,14 @@ fn test_lefts_none() { assert (len(result) == 0u); } +#[test] fn test_lefts_empty() { let (t[int, int])[] input = ~[]; auto result = lefts(input); assert (len(result) == 0u); } +#[test] fn test_rights() { auto input = ~[left(10), right(11), @@ -51,6 +55,7 @@ fn test_rights() { assert (result == ~[11, 13]); } +#[test] fn test_rights_none() { let (t[int, int])[] input = ~[left(10), left(10)]; @@ -58,12 +63,14 @@ fn test_rights_none() { assert (len(result) == 0u); } +#[test] fn test_rights_empty() { let (t[int, int])[] input = ~[]; auto result = rights(input); assert (len(result) == 0u); } +#[test] fn test_partition() { auto input = ~[left(10), right(11), @@ -78,6 +85,7 @@ fn test_partition() { assert (result._1.(1) == 13); } +#[test] fn test_partition_no_lefts() { let (t[int, int])[] input = ~[right(10), right(11)]; @@ -86,6 +94,7 @@ fn test_partition_no_lefts() { assert (len(result._1) == 2u); } +#[test] fn test_partition_no_rights() { let (t[int, int])[] input = ~[left(10), left(11)]; @@ -94,24 +103,10 @@ fn test_partition_no_rights() { assert (len(result._1) == 0u); } +#[test] fn test_partition_empty() { let (t[int, int])[] input = ~[]; auto result = partition(input); assert (len(result._0) == 0u); assert (len(result._1) == 0u); } - -fn main() { - test_either_left(); - test_either_right(); - test_lefts(); - test_lefts_none(); - test_lefts_empty(); - test_rights(); - test_rights_none(); - test_rights_empty(); - test_partition(); - test_partition_no_lefts(); - test_partition_no_rights(); - test_partition_empty(); -} diff --git a/src/test/run-pass/lib-fs.rs b/src/test/stdtest/fs.rs similarity index 81% rename from src/test/run-pass/lib-fs.rs rename to src/test/stdtest/fs.rs index 8bc8989e563..76321fbb436 100644 --- a/src/test/run-pass/lib-fs.rs +++ b/src/test/stdtest/fs.rs @@ -2,6 +2,7 @@ use std; import std::fs; +#[test] fn test_connect() { auto slash = fs::path_sep(); log_err fs::connect("a", "b"); @@ -10,11 +11,8 @@ fn test_connect() { } // Issue #712 +#[test] fn test_list_dir_no_invalid_memory_access() { fs::list_dir("."); } -fn main() { - test_connect(); - test_list_dir_no_invalid_memory_access(); -} \ No newline at end of file diff --git a/src/test/run-pass/lib-getopts.rs b/src/test/stdtest/getopts.rs similarity index 91% rename from src/test/run-pass/lib-getopts.rs rename to src/test/stdtest/getopts.rs index 26d253e1d40..233e3a546fc 100644 --- a/src/test/run-pass/lib-getopts.rs +++ b/src/test/stdtest/getopts.rs @@ -29,6 +29,7 @@ fn check_fail_type(opt::fail_ f, fail_type ft) { // Tests for reqopt +#[test] fn test_reqopt_long() { auto args = ["--test=20"]; auto opts = [opt::reqopt("test")]; @@ -42,6 +43,7 @@ fn test_reqopt_long() { } } +#[test] fn test_reqopt_long_missing() { auto args = ["blah"]; auto opts = [opt::reqopt("test")]; @@ -52,6 +54,7 @@ fn test_reqopt_long_missing() { } } +#[test] fn test_reqopt_long_no_arg() { auto args = ["--test"]; auto opts = [opt::reqopt("test")]; @@ -62,6 +65,7 @@ fn test_reqopt_long_no_arg() { } } +#[test] fn test_reqopt_long_multi() { auto args = ["--test=20", "--test=30"]; auto opts = [opt::reqopt("test")]; @@ -72,6 +76,7 @@ fn test_reqopt_long_multi() { } } +#[test] fn test_reqopt_short() { auto args = ["-t", "20"]; auto opts = [opt::reqopt("t")]; @@ -85,6 +90,7 @@ fn test_reqopt_short() { } } +#[test] fn test_reqopt_short_missing() { auto args = ["blah"]; auto opts = [opt::reqopt("t")]; @@ -95,6 +101,7 @@ fn test_reqopt_short_missing() { } } +#[test] fn test_reqopt_short_no_arg() { auto args = ["-t"]; auto opts = [opt::reqopt("t")]; @@ -105,6 +112,7 @@ fn test_reqopt_short_no_arg() { } } +#[test] fn test_reqopt_short_multi() { auto args = ["-t", "20", "-t", "30"]; auto opts = [opt::reqopt("t")]; @@ -117,6 +125,7 @@ fn test_reqopt_short_multi() { // Tests for optopt +#[test] fn test_optopt_long() { auto args = ["--test=20"]; auto opts = [opt::optopt("test")]; @@ -130,6 +139,7 @@ fn test_optopt_long() { } } +#[test] fn test_optopt_long_missing() { auto args = ["blah"]; auto opts = [opt::optopt("test")]; @@ -140,6 +150,7 @@ fn test_optopt_long_missing() { } } +#[test] fn test_optopt_long_no_arg() { auto args = ["--test"]; auto opts = [opt::optopt("test")]; @@ -150,6 +161,7 @@ fn test_optopt_long_no_arg() { } } +#[test] fn test_optopt_long_multi() { auto args = ["--test=20", "--test=30"]; auto opts = [opt::optopt("test")]; @@ -160,6 +172,7 @@ fn test_optopt_long_multi() { } } +#[test] fn test_optopt_short() { auto args = ["-t", "20"]; auto opts = [opt::optopt("t")]; @@ -173,6 +186,7 @@ fn test_optopt_short() { } } +#[test] fn test_optopt_short_missing() { auto args = ["blah"]; auto opts = [opt::optopt("t")]; @@ -183,6 +197,7 @@ fn test_optopt_short_missing() { } } +#[test] fn test_optopt_short_no_arg() { auto args = ["-t"]; auto opts = [opt::optopt("t")]; @@ -193,6 +208,7 @@ fn test_optopt_short_no_arg() { } } +#[test] fn test_optopt_short_multi() { auto args = ["-t", "20", "-t", "30"]; auto opts = [opt::optopt("t")]; @@ -205,6 +221,7 @@ fn test_optopt_short_multi() { // Tests for optflag +#[test] fn test_optflag_long() { auto args = ["--test"]; auto opts = [opt::optflag("test")]; @@ -215,6 +232,7 @@ fn test_optflag_long() { } } +#[test] fn test_optflag_long_missing() { auto args = ["blah"]; auto opts = [opt::optflag("test")]; @@ -225,6 +243,7 @@ fn test_optflag_long_missing() { } } +#[test] fn test_optflag_long_arg() { auto args = ["--test=20"]; auto opts = [opt::optflag("test")]; @@ -238,6 +257,7 @@ fn test_optflag_long_arg() { } } +#[test] fn test_optflag_long_multi() { auto args = ["--test", "--test"]; auto opts = [opt::optflag("test")]; @@ -248,6 +268,7 @@ fn test_optflag_long_multi() { } } +#[test] fn test_optflag_short() { auto args = ["-t"]; auto opts = [opt::optflag("t")]; @@ -258,6 +279,7 @@ fn test_optflag_short() { } } +#[test] fn test_optflag_short_missing() { auto args = ["blah"]; auto opts = [opt::optflag("t")]; @@ -268,6 +290,7 @@ fn test_optflag_short_missing() { } } +#[test] fn test_optflag_short_arg() { auto args = ["-t", "20"]; auto opts = [opt::optflag("t")]; @@ -282,6 +305,7 @@ fn test_optflag_short_arg() { } } +#[test] fn test_optflag_short_multi() { auto args = ["-t", "-t"]; auto opts = [opt::optflag("t")]; @@ -294,6 +318,7 @@ fn test_optflag_short_multi() { // Tests for optmulti +#[test] fn test_optmulti_long() { auto args = ["--test=20"]; auto opts = [opt::optmulti("test")]; @@ -307,6 +332,7 @@ fn test_optmulti_long() { } } +#[test] fn test_optmulti_long_missing() { auto args = ["blah"]; auto opts = [opt::optmulti("test")]; @@ -317,6 +343,7 @@ fn test_optmulti_long_missing() { } } +#[test] fn test_optmulti_long_no_arg() { auto args = ["--test"]; auto opts = [opt::optmulti("test")]; @@ -327,6 +354,7 @@ fn test_optmulti_long_no_arg() { } } +#[test] fn test_optmulti_long_multi() { auto args = ["--test=20", "--test=30"]; auto opts = [opt::optmulti("test")]; @@ -342,6 +370,7 @@ fn test_optmulti_long_multi() { } } +#[test] fn test_optmulti_short() { auto args = ["-t", "20"]; auto opts = [opt::optmulti("t")]; @@ -355,6 +384,7 @@ fn test_optmulti_short() { } } +#[test] fn test_optmulti_short_missing() { auto args = ["blah"]; auto opts = [opt::optmulti("t")]; @@ -365,6 +395,7 @@ fn test_optmulti_short_missing() { } } +#[test] fn test_optmulti_short_no_arg() { auto args = ["-t"]; auto opts = [opt::optmulti("t")]; @@ -375,6 +406,7 @@ fn test_optmulti_short_no_arg() { } } +#[test] fn test_optmulti_short_multi() { auto args = ["-t", "20", "-t", "30"]; auto opts = [opt::optmulti("t")]; @@ -390,6 +422,7 @@ fn test_optmulti_short_multi() { } } +#[test] fn test_unrecognized_option_long() { auto args = ["--untest"]; auto opts = [opt::optmulti("t")]; @@ -400,6 +433,7 @@ fn test_unrecognized_option_long() { } } +#[test] fn test_unrecognized_option_short() { auto args = ["-t"]; auto opts = [opt::optmulti("test")]; @@ -410,6 +444,7 @@ fn test_unrecognized_option_short() { } } +#[test] fn test_combined() { auto args = ["prog", "free1", "-s", "20", "free2", "--flag", "--long=30", "-f", @@ -435,40 +470,3 @@ fn test_combined() { } } -fn main() { - test_reqopt_long(); - test_reqopt_long_missing(); - test_reqopt_long_no_arg(); - test_reqopt_long_multi(); - test_reqopt_short(); - test_reqopt_short_missing(); - test_reqopt_short_no_arg(); - test_reqopt_short_multi(); - test_optopt_long(); - test_optopt_long_missing(); - test_optopt_long_no_arg(); - test_optopt_long_multi(); - test_optopt_short(); - test_optopt_short_missing(); - test_optopt_short_no_arg(); - test_optopt_short_multi(); - test_optflag_long(); - test_optflag_long_missing(); - test_optflag_long_arg(); - test_optflag_long_multi(); - test_optflag_short(); - test_optflag_short_missing(); - test_optflag_short_arg(); - test_optflag_short_multi(); - test_optmulti_long(); - test_optmulti_long_missing(); - test_optmulti_long_no_arg(); - test_optmulti_long_multi(); - test_optmulti_short(); - test_optmulti_short_missing(); - test_optmulti_short_no_arg(); - test_optmulti_short_multi(); - test_unrecognized_option_long(); - test_unrecognized_option_short(); - test_combined(); -} \ No newline at end of file diff --git a/src/test/stdtest/int.rs b/src/test/stdtest/int.rs index d9432bc0722..61d3448a175 100644 --- a/src/test/stdtest/int.rs +++ b/src/test/stdtest/int.rs @@ -1,3 +1,5 @@ + +use std; import std::int; import std::str::eq; diff --git a/src/test/run-pass/lib-io.rs b/src/test/stdtest/io.rs similarity index 93% rename from src/test/run-pass/lib-io.rs rename to src/test/stdtest/io.rs index d2fada74c17..460d68b7569 100644 --- a/src/test/run-pass/lib-io.rs +++ b/src/test/stdtest/io.rs @@ -1,4 +1,3 @@ -// xfail-stage0 // -*- rust -*- use std; import std::io; @@ -6,6 +5,7 @@ import std::str; #[cfg(target_os = "linux")] #[cfg(target_os = "win32")] +#[test] fn test_simple() { let str tmpfile = "test/run-pass/lib-io-test-simple.tmp"; log tmpfile; @@ -24,8 +24,7 @@ fn test_simple() { // FIXME (726) #[cfg(target_os = "macos")] +#[test] +#[ignore] fn test_simple() {} -fn main() { - test_simple(); -} \ No newline at end of file diff --git a/src/test/run-pass/lib-ivec.rs b/src/test/stdtest/ivec.rs similarity index 92% rename from src/test/run-pass/lib-ivec.rs rename to src/test/stdtest/ivec.rs index 14fcd831399..945a8310bff 100644 --- a/src/test/run-pass/lib-ivec.rs +++ b/src/test/stdtest/ivec.rs @@ -1,4 +1,3 @@ -// xfail-stage0 use std; import std::ivec; @@ -18,6 +17,7 @@ fn square_if_odd(&uint n) -> option::t[uint] { fn add(&uint x, &uint y) -> uint { ret x + y; } +#[test] fn test_reserve_and_on_heap() { let int[] v = ~[ 1, 2 ]; assert (!ivec::on_heap(v)); @@ -25,6 +25,7 @@ fn test_reserve_and_on_heap() { assert (ivec::on_heap(v)); } +#[test] fn test_unsafe_ptrs() { // Test on-stack copy-from-buf. auto a = ~[ 1, 2, 3 ]; @@ -49,6 +50,7 @@ fn test_unsafe_ptrs() { assert (d.(4) == 5); } +#[test] fn test_init_fn() { // Test on-stack init_fn. auto v = ivec::init_fn(square, 3u); @@ -67,6 +69,7 @@ fn test_init_fn() { assert (v.(4) == 16u); } +#[test] fn test_init_elt() { // Test on-stack init_elt. auto v = ivec::init_elt(10u, 2u); @@ -84,22 +87,26 @@ fn test_init_elt() { assert (v.(5) == 20u); } +#[test] fn test_is_empty() { assert ivec::is_empty[int](~[]); assert !ivec::is_empty(~[0]); } +#[test] fn test_is_not_empty() { assert ivec::is_not_empty(~[0]); assert !ivec::is_not_empty[int](~[]); } +#[test] fn test_head() { auto a = ~[11, 12]; check ivec::is_not_empty(a); assert ivec::head(a) == 11; } +#[test] fn test_tail() { auto a = ~[11]; check ivec::is_not_empty(a); @@ -110,6 +117,7 @@ fn test_tail() { assert ivec::tail(a) == ~[12]; } +#[test] fn test_last() { auto n = ivec::last(~[]); assert (n == none); @@ -119,6 +127,7 @@ fn test_last() { assert (n == some(5)); } +#[test] fn test_slice() { // Test on-stack -> on-stack slice. auto v = ivec::slice(~[ 1, 2, 3 ], 1u, 3u); @@ -143,6 +152,7 @@ fn test_slice() { assert (v.(4) == 6); } +#[test] fn test_pop() { // Test on-stack pop. auto v = ~[ 1, 2, 3 ]; @@ -163,6 +173,7 @@ fn test_pop() { assert (e == 5); } +#[test] fn test_grow() { // Test on-stack grow(). auto v = ~[]; @@ -181,6 +192,7 @@ fn test_grow() { assert (v.(4) == 2); } +#[test] fn test_grow_fn() { auto v = ~[]; ivec::grow_fn(v, 3u, square); @@ -190,6 +202,7 @@ fn test_grow_fn() { assert (v.(2) == 4u); } +#[test] fn test_grow_set() { auto v = ~[ mutable 1, 2, 3 ]; ivec::grow_set(v, 4u, 4, 5); @@ -201,6 +214,7 @@ fn test_grow_set() { assert (v.(4) == 5); } +#[test] fn test_map() { // Test on-stack map. auto v = ~[ 1u, 2u, 3u ]; @@ -221,6 +235,7 @@ fn test_map() { assert (w.(4) == 25u); } +#[test] fn test_filter_map() { // Test on-stack filter-map. auto v = ~[ 1u, 2u, 3u ]; @@ -238,6 +253,7 @@ fn test_filter_map() { assert (w.(2) == 25u); } +#[test] fn test_foldl() { // Test on-stack fold. auto v = ~[ 1u, 2u, 3u ]; @@ -250,6 +266,7 @@ fn test_foldl() { assert (sum == 15u); } +#[test] fn test_any_and_all() { assert (ivec::any(is_three, ~[ 1u, 2u, 3u ])); assert (!ivec::any(is_three, ~[ 0u, 1u, 2u ])); @@ -279,38 +296,6 @@ fn test_zip_unzip() { assert tup(3, 6) == tup(u1._0.(2), u1._1.(2)); } -fn main() { - test_reserve_and_on_heap(); - test_unsafe_ptrs(); - - // Predicates - test_is_empty(); - test_is_not_empty(); - - // Accessors - test_init_fn(); - test_init_elt(); - test_head(); - test_tail(); - test_last(); - test_slice(); - - // Mutators - test_pop(); - - // Appending - test_grow(); - test_grow_fn(); - test_grow_set(); - - // Functional utilities - test_map(); - test_filter_map(); - test_foldl(); - test_any_and_all(); - test_zip_unzip(); -} - // Local Variables: // mode: rust; // fill-column: 78; diff --git a/src/test/run-pass/lib-list.rs b/src/test/stdtest/list.rs similarity index 90% rename from src/test/run-pass/lib-list.rs rename to src/test/stdtest/list.rs index d09243e98e6..3d937016b1f 100644 --- a/src/test/run-pass/lib-list.rs +++ b/src/test/stdtest/list.rs @@ -6,6 +6,7 @@ import std::list::cdr; import std::list::from_vec; import std::option; +#[test] fn test_from_vec() { auto l = from_vec([0, 1, 2]); assert (car(l) == 0); @@ -13,6 +14,7 @@ fn test_from_vec() { assert (car(cdr(cdr(l))) == 2); } +#[test] fn test_foldl() { auto l = from_vec([0, 1, 2, 3, 4]); fn add(&int a, &uint b) -> uint { ret (a as uint) + b; } @@ -20,6 +22,7 @@ fn test_foldl() { assert (rs == 10u); } +#[test] fn test_find_success() { auto l = from_vec([0, 1, 2]); fn match(&int i) -> option::t[int] { @@ -29,6 +32,7 @@ fn test_find_success() { assert (rs == option::some(2)); } +#[test] fn test_find_fail() { auto l = from_vec([0, 1, 2]); fn match(&int i) -> option::t[int] { ret option::none[int]; } @@ -36,6 +40,7 @@ fn test_find_fail() { assert (rs == option::none[int]); } +#[test] fn test_has() { auto l = from_vec([5, 8, 6]); auto empty = list::nil[int]; @@ -45,16 +50,9 @@ fn test_has() { assert (!list::has(empty, 5)); } +#[test] fn test_length() { auto l = from_vec([0, 1, 2]); assert (list::length(l) == 3u); } -fn main() { - test_from_vec(); - test_foldl(); - test_find_success(); - test_find_fail(); - test_length(); - test_has(); -} \ No newline at end of file diff --git a/src/test/run-pass/lib-map.rs b/src/test/stdtest/map.rs similarity index 98% rename from src/test/run-pass/lib-map.rs rename to src/test/stdtest/map.rs index 82a404755f7..da6d0630116 100644 --- a/src/test/run-pass/lib-map.rs +++ b/src/test/stdtest/map.rs @@ -7,6 +7,7 @@ import std::str; import std::uint; import std::util; +#[test] fn test_simple() { log "*** starting test_simple"; fn eq_uint(&uint x, &uint y) -> bool { ret x == y; } @@ -83,6 +84,7 @@ fn test_simple() { /** * Force map growth and rehashing. */ +#[test] fn test_growth() { log "*** starting test_growth"; let uint num_to_insert = 64u; @@ -162,6 +164,7 @@ fn test_growth() { log "*** finished test_growth"; } +#[test] fn test_removal() { log "*** starting test_removal"; let uint num_to_insert = 64u; @@ -262,6 +265,7 @@ fn test_removal() { log "*** finished test_removal"; } +#[test] fn test_contains_key() { auto key = "k"; auto map = map::mk_hashmap[str, str](str::hash, str::eq); @@ -270,6 +274,7 @@ fn test_contains_key() { assert (map.contains_key(key)); } +#[test] fn test_find() { auto key = "k"; auto map = map::mk_hashmap[str, str](str::hash, str::eq); @@ -277,11 +282,3 @@ fn test_find() { map.insert(key, "val"); assert (std::option::get(map.find(key)) == "val"); } - -fn main() { - test_simple(); - test_growth(); - test_removal(); - test_contains_key(); - test_find(); -} \ No newline at end of file diff --git a/src/test/stdtest/option.rs b/src/test/stdtest/option.rs new file mode 100644 index 00000000000..a22effc524a --- /dev/null +++ b/src/test/stdtest/option.rs @@ -0,0 +1,5 @@ + +use std; + +#[test] +fn test() { auto x = std::option::some[int](10); } \ No newline at end of file diff --git a/src/test/run-pass/lib-os.rs b/src/test/stdtest/os.rs similarity index 88% rename from src/test/run-pass/lib-os.rs rename to src/test/stdtest/os.rs index c3dc3e08dad..a47777d7739 100644 --- a/src/test/run-pass/lib-os.rs +++ b/src/test/stdtest/os.rs @@ -1,7 +1,3 @@ -// xfail-stage0 - -use std; - import std::generic_os::setenv; import std::generic_os::getenv; import std::option; @@ -33,12 +29,6 @@ fn test_getenv_big() { assert getenv("NAME") == option::some(s); } -fn main() { - test_setenv(); - test_setenv_overwrite(); - test_getenv_big(); -} - // Local Variables: // mode: rust; // fill-column: 78; diff --git a/src/test/run-pass/lib-path.rs b/src/test/stdtest/path.rs similarity index 90% rename from src/test/run-pass/lib-path.rs rename to src/test/stdtest/path.rs index fe4fcfef254..81fd74208f8 100644 --- a/src/test/run-pass/lib-path.rs +++ b/src/test/stdtest/path.rs @@ -1,4 +1,3 @@ -// xfail-stage0 // Testing a few of the path manipuation functions @@ -7,7 +6,8 @@ use std; import std::fs; import std::os; -fn main() { +#[test] +fn test() { assert(!fs::path_is_absolute("test-path")); log "Current working directory: " + os::getcwd(); diff --git a/src/test/run-pass/lib-ptr.rs b/src/test/stdtest/ptr.rs similarity index 94% rename from src/test/run-pass/lib-ptr.rs rename to src/test/stdtest/ptr.rs index 79a535fd966..bf9633e0686 100644 --- a/src/test/run-pass/lib-ptr.rs +++ b/src/test/stdtest/ptr.rs @@ -1,12 +1,11 @@ -// xfail-stage0 - use std; import std::ptr; import std::unsafe; type pair = rec(mutable int fst, mutable int snd); -fn main() { +#[test] +fn test() { auto p = rec(mutable fst=10, mutable snd=20); let *mutable pair pptr = ptr::addr_of(p); let *mutable int iptr = unsafe::reinterpret_cast(pptr); diff --git a/src/test/run-pass/lib-qsort.rs b/src/test/stdtest/qsort.rs similarity index 70% rename from src/test/run-pass/lib-qsort.rs rename to src/test/stdtest/qsort.rs index 64e143dfbad..1581cd42403 100644 --- a/src/test/run-pass/lib-qsort.rs +++ b/src/test/stdtest/qsort.rs @@ -1,6 +1,10 @@ use std; +import std::sort; +import std::ivec; +import std::int; + fn check_sort(vec[mutable int] v1, vec[mutable int] v2) { auto len = std::vec::len[int](v1); fn ltequal(&int a, &int b) -> bool { ret a <= b; } @@ -10,7 +14,8 @@ fn check_sort(vec[mutable int] v1, vec[mutable int] v2) { while (i < len) { log v2.(i); assert (v2.(i) == v1.(i)); i += 1u; } } -fn main() { +#[test] +fn test() { { auto v1 = [mutable 3, 7, 4, 5, 2, 9, 5, 8]; auto v2 = [mutable 2, 3, 4, 5, 5, 7, 8, 9]; @@ -33,6 +38,24 @@ fn main() { check_sort(v1, v2); } } + +// Regression test for #705 +#[test] +fn test_simple() { + auto names = ~[mutable 2, 1, 3]; + + auto expected = ~[1, 2, 3]; + + fn lteq(&int a, &int b) -> bool { int::le(a, b) } + sort::ivector::quick_sort(lteq, names); + + auto pairs = ivec::zip(expected, ivec::from_mut(names)); + for (tup(int, int) p in pairs) { + log #fmt("%d %d", p._0, p._1); + assert p._0 == p._1; + } +} + // Local Variables: // mode: rust; // fill-column: 78; diff --git a/src/test/run-pass/lib-qsort3.rs b/src/test/stdtest/qsort3.rs similarity index 98% rename from src/test/run-pass/lib-qsort3.rs rename to src/test/stdtest/qsort3.rs index 0a9535d77cb..58abf1bc8fa 100644 --- a/src/test/run-pass/lib-qsort3.rs +++ b/src/test/stdtest/qsort3.rs @@ -12,7 +12,8 @@ fn check_sort(vec[mutable int] v1, vec[mutable int] v2) { while (i < len) { log v2.(i); assert (v2.(i) == v1.(i)); i += 1u; } } -fn main() { +#[test] +fn test() { { auto v1 = [mutable 3, 7, 4, 5, 2, 9, 5, 8]; auto v2 = [mutable 2, 3, 4, 5, 5, 7, 8, 9]; diff --git a/src/test/run-pass/lib-rand.rs b/src/test/stdtest/rand.rs similarity index 95% rename from src/test/run-pass/lib-rand.rs rename to src/test/stdtest/rand.rs index f09b7eeddbb..8d7b26df04b 100644 --- a/src/test/run-pass/lib-rand.rs +++ b/src/test/stdtest/rand.rs @@ -4,7 +4,8 @@ use std; import std::rand; -fn main() { +#[test] +fn test() { let rand::rng r1 = rand::mk_rng(); log r1.next(); log r1.next(); diff --git a/src/test/run-pass/lib-run.rs b/src/test/stdtest/run.rs similarity index 75% rename from src/test/run-pass/lib-run.rs rename to src/test/stdtest/run.rs index ffaa61721c2..c86182d36c9 100644 --- a/src/test/run-pass/lib-run.rs +++ b/src/test/stdtest/run.rs @@ -1,22 +1,18 @@ -// xfail-stage0 - use std; import std::run; // Regression test for memory leaks -// FIXME (714) Why does this fail on win32? - #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] +#[test] fn test_leaks() { run::run_program("echo", []); run::start_program("echo", []); run::program_output("echo", []); } +// FIXME #[cfg(target_os = "win32")] +#[test] +#[ignore] fn test_leaks() {} - -fn main() { - test_leaks(); -} \ No newline at end of file diff --git a/src/test/stdtest/sha1.rs b/src/test/stdtest/sha1.rs index 4244ac4960a..038444552e0 100644 --- a/src/test/stdtest/sha1.rs +++ b/src/test/stdtest/sha1.rs @@ -1,3 +1,8 @@ + + +// -*- rust -*- + +use std; import std::sha1; import std::vec; import std::str; diff --git a/src/test/run-pass/lib-sort.rs b/src/test/stdtest/sort.rs similarity index 97% rename from src/test/run-pass/lib-sort.rs rename to src/test/stdtest/sort.rs index 20bbf6aefc5..aae679217bb 100644 --- a/src/test/run-pass/lib-sort.rs +++ b/src/test/stdtest/sort.rs @@ -10,7 +10,8 @@ fn check_sort(vec[int] v1, vec[int] v2) { while (i < len) { log v3.(i); assert (v3.(i) == v2.(i)); i += 1u; } } -fn main() { +#[test] +fn test() { { auto v1 = [3, 7, 4, 5, 2, 9, 5, 8]; auto v2 = [2, 3, 4, 5, 5, 7, 8, 9]; diff --git a/src/test/run-pass/lib-sort-ivec.rs b/src/test/stdtest/sort_ivec.rs similarity index 96% rename from src/test/run-pass/lib-sort-ivec.rs rename to src/test/stdtest/sort_ivec.rs index 6b957c8a4ab..dcc90a8edc9 100644 --- a/src/test/run-pass/lib-sort-ivec.rs +++ b/src/test/stdtest/sort_ivec.rs @@ -1,4 +1,3 @@ -// xfail-stage0 use std; @@ -11,7 +10,8 @@ fn check_sort(&int[] v1, &int[] v2) { while (i < len) { log v3.(i); assert (v3.(i) == v2.(i)); i += 1u; } } -fn main() { +#[test] +fn test() { { auto v1 = ~[3, 7, 4, 5, 2, 9, 5, 8]; auto v2 = ~[2, 3, 4, 5, 5, 7, 8, 9]; diff --git a/src/test/stdtest/stdtest.rc b/src/test/stdtest/stdtest.rc index 5bce1659179..e313b77bd0c 100644 --- a/src/test/stdtest/stdtest.rc +++ b/src/test/stdtest/stdtest.rc @@ -1,8 +1,35 @@ use std; -mod sha1; +mod bitv; +mod box; +mod deque; +mod either; +mod fs; +mod getopts; mod int; +mod io; +mod ivec; +mod list; +mod map; +mod option; +mod os; +mod path; +mod ptr; +mod qsort3; +mod qsort; +mod rand; +mod run; +mod sha1; +mod sort_ivec; +mod sort; +mod str_buf; +mod str; +mod task; mod test; +mod uint; +mod vec; +mod vec_str_conversions; + // Local Variables: // mode: rust // fill-column: 78; diff --git a/src/test/run-pass/lib-str.rs b/src/test/stdtest/str.rs similarity index 93% rename from src/test/run-pass/lib-str.rs rename to src/test/stdtest/str.rs index 52ec5b78add..063a0d9783c 100644 --- a/src/test/run-pass/lib-str.rs +++ b/src/test/stdtest/str.rs @@ -1,9 +1,7 @@ - - -// xfail-stage0 use std; import std::str; +#[test] fn test_bytes_len() { assert (str::byte_len("") == 0u); assert (str::byte_len("hello world") == 11u); @@ -14,6 +12,7 @@ fn test_bytes_len() { assert (str::byte_len("\U0001d11e") == 4u); } +#[test] fn test_index_and_rindex() { assert (str::index("hello", 'e' as u8) == 1); assert (str::index("hello", 'o' as u8) == 4); @@ -23,6 +22,7 @@ fn test_index_and_rindex() { assert (str::rindex("hello", 'z' as u8) == -1); } +#[test] fn test_split() { fn t(&str s, char c, int i, &str k) { log "splitting: " + s; @@ -42,6 +42,7 @@ fn test_split() { t("...hello.there.", '.', 5, ""); } +#[test] fn test_find() { fn t(&str haystack, &str needle, int i) { let int j = str::find(haystack, needle); @@ -56,6 +57,7 @@ fn test_find() { t("this", "simple", -1); } +#[test] fn test_substr() { fn t(&str a, &str b, int start) { assert (str::eq(str::substr(a, start as uint, str::byte_len(b)), b)); @@ -65,6 +67,7 @@ fn test_substr() { t("substr should not be a challenge", "not", 14); } +#[test] fn test_concat() { fn t(&vec[str] v, &str s) { assert (str::eq(str::concat(v), s)); } t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood"); @@ -73,6 +76,7 @@ fn test_concat() { t(["hi"], "hi"); } +#[test] fn test_connect() { fn t(&vec[str] v, &str sep, &str s) { assert (str::eq(str::connect(v, sep), s)); @@ -83,6 +87,7 @@ fn test_connect() { t(["hi"], " ", "hi"); } +#[test] fn test_to_upper() { // to_upper doesn't understand unicode yet, // but we need to at least preserve it @@ -94,6 +99,7 @@ fn test_to_upper() { assert (str::eq(expected, actual)); } +#[test] fn test_slice() { assert (str::eq("ab", str::slice("abc", 0u, 2u))); assert (str::eq("bc", str::slice("abc", 1u, 3u))); @@ -114,6 +120,7 @@ fn test_slice() { str::slice(a_million_letter_a(), 0u, 500000u))); } +#[test] fn test_ends_with() { assert (str::ends_with("", "")); assert (str::ends_with("abc", "")); @@ -122,16 +129,19 @@ fn test_ends_with() { assert (!str::ends_with("", "abc")); } +#[test] fn test_is_empty() { assert str::is_empty(""); assert !str::is_empty("a"); } +#[test] fn test_is_not_empty() { assert str::is_not_empty("a"); assert !str::is_not_empty(""); } +#[test] fn test_replace() { auto a = "a"; check str::is_not_empty(a); @@ -145,22 +155,6 @@ fn test_replace() { assert str::replace(" test test ", test, "") == " "; } -fn main() { - test_bytes_len(); - test_index_and_rindex(); - test_split(); - test_find(); - test_substr(); - test_concat(); - test_connect(); - test_to_upper(); - test_slice(); - test_ends_with(); - test_is_empty(); - test_is_not_empty(); - test_replace(); -} - // Local Variables: // mode: rust; diff --git a/src/test/run-pass/lib-str-buf.rs b/src/test/stdtest/str_buf.rs similarity index 92% rename from src/test/run-pass/lib-str-buf.rs rename to src/test/stdtest/str_buf.rs index a00862f6363..0bc005224c2 100644 --- a/src/test/run-pass/lib-str-buf.rs +++ b/src/test/stdtest/str_buf.rs @@ -4,7 +4,8 @@ use std; import std::str; -fn main() { +#[test] +fn test() { auto s = "hello"; auto sb = str::buf(s); auto s_cstr = str::str_from_cstr(sb); diff --git a/src/test/run-pass/lib-task.rs b/src/test/stdtest/task.rs similarity index 77% rename from src/test/run-pass/lib-task.rs rename to src/test/stdtest/task.rs index 52ea933a0ce..b100fc2a925 100644 --- a/src/test/run-pass/lib-task.rs +++ b/src/test/stdtest/task.rs @@ -1,12 +1,11 @@ - - -// xfail-stage0 - use std; import std::task; +#[test] +#[ignore] fn test_sleep() { task::sleep(1000000u); } +#[test] fn test_unsupervise() { fn f() { task::unsupervise(); @@ -15,6 +14,7 @@ fn test_unsupervise() { spawn f(); } +#[test] fn test_join() { fn winner() { } @@ -32,10 +32,3 @@ fn test_join() { assert task::join(failtask) == task::tr_failure; } - -fn main() { - // FIXME: Why aren't we running this? - //test_sleep(); - test_unsupervise(); - test_join(); -} \ No newline at end of file diff --git a/src/test/run-pass/lib-uint.rs b/src/test/stdtest/uint.rs similarity index 98% rename from src/test/run-pass/lib-uint.rs rename to src/test/stdtest/uint.rs index 4b001cb27db..8b450b8a5ff 100644 --- a/src/test/run-pass/lib-uint.rs +++ b/src/test/stdtest/uint.rs @@ -4,7 +4,8 @@ use std; import std::uint; -fn main() { +#[test] +fn test_next_power_of_two() { assert (uint::next_power_of_two(0u) == 0u); assert (uint::next_power_of_two(1u) == 1u); assert (uint::next_power_of_two(2u) == 2u); diff --git a/src/test/run-pass/lib-vec.rs b/src/test/stdtest/vec.rs similarity index 93% rename from src/test/run-pass/lib-vec.rs rename to src/test/stdtest/vec.rs index 24adaaa5972..5e140a783cc 100644 --- a/src/test/run-pass/lib-vec.rs +++ b/src/test/stdtest/vec.rs @@ -4,6 +4,7 @@ use std; import std::vec::*; import std::option; +#[test] fn test_init_elt() { let vec[uint] v = init_elt[uint](5u, 3u); assert (len[uint](v) == 3u); @@ -14,6 +15,7 @@ fn test_init_elt() { fn id(uint x) -> uint { ret x; } +#[test] fn test_init_fn() { let fn(uint) -> uint op = id; let vec[uint] v = init_fn[uint](op, 5u); @@ -25,6 +27,7 @@ fn test_init_fn() { assert (v.(4) == 4u); } +#[test] fn test_slice() { let vec[int] v = [1, 2, 3, 4, 5]; auto v2 = slice[int](v, 2u, 4u); @@ -33,6 +36,7 @@ fn test_slice() { assert (v2.(1) == 4); } +#[test] fn test_map() { fn square(&int x) -> int { ret x * x; } let option::operator[int, int] op = square; @@ -42,6 +46,7 @@ fn test_map() { while (i < 5) { assert (v.(i) * v.(i) == s.(i)); i += 1; } } +#[test] fn test_map2() { fn times(&int x, &int y) -> int { ret x * y; } auto f = times; @@ -52,6 +57,7 @@ fn test_map2() { while (i < 5) { assert (v0.(i) * v1.(i) == u.(i)); i += 1; } } +#[test] fn test_filter_map() { fn halve(&int i) -> option::t[int] { if (i % 2 == 0) { @@ -71,6 +77,7 @@ fn test_filter_map() { assert (filter_map(halve, mix) == mix_dest); } +#[test] fn test_position() { let vec[int] v1 = [1, 2, 3, 3, 2, 5]; assert (position(1, v1) == option::some[uint](0u)); @@ -79,6 +86,7 @@ fn test_position() { assert (position(4, v1) == option::none[uint]); } +#[test] fn test_position_pred() { fn less_than_three(&int i) -> bool { ret i <3; @@ -90,14 +98,3 @@ fn test_position_pred() { assert (position_pred(less_than_three, v1) == option::some[uint](3u)); assert (position_pred(is_eighteen, v1) == option::none[uint]); } - -fn main() { - test_init_elt(); - test_init_fn(); - test_slice(); - test_map(); - test_map2(); - test_filter_map(); - test_position(); - test_position_pred(); -} \ No newline at end of file diff --git a/src/test/run-pass/lib-vec-str-conversions.rs b/src/test/stdtest/vec_str_conversions.rs similarity index 96% rename from src/test/run-pass/lib-vec-str-conversions.rs rename to src/test/stdtest/vec_str_conversions.rs index 00ad2b84803..dddbb5b21be 100644 --- a/src/test/run-pass/lib-vec-str-conversions.rs +++ b/src/test/stdtest/vec_str_conversions.rs @@ -5,6 +5,7 @@ use std; import std::str; import std::vec; +#[test] fn test_simple() { let str s1 = "All mimsy were the borogoves"; /* @@ -31,5 +32,3 @@ fn test_simple() { log "refcnt is"; log str::refcount(s1); } - -fn main() { test_simple(); } \ No newline at end of file