SHELL := /bin/bash ESP8266_CORE_PATH ?= $(shell git rev-parse --show-toplevel) BUILD_DIR ?= $(PWD)/build BS_DIR ?= $(PWD)/libraries/BSTest PYTHON ?= python3 ESPTOOL ?= $(PYTHON) $(ESP8266_CORE_PATH)/tools/esptool/esptool.py VENV_PYTHON ?= $(BS_DIR)/virtualenv/bin/python VENV_JUNIT2HTML ?= $(BS_DIR)/virtualenv/bin/junit2html MKFS ?= $(ESP8266_CORE_PATH)/tools/mklittlefs/mklittlefs UPLOAD_PORT ?= $(shell ls /dev/tty* | grep -m 1 -i USB) UPLOAD_BAUD ?= 460800 TEST_BAUD ?= 115200 BUILD_TOOL ?= arduino-cli BUILD_BOARD ?= generic BUILD_CPU ?= 160 BUILD_SIZE ?= 4M1M BUILD_LWIP ?= lm2f BUILD_EXTRA ?= ,dbg=Serial,lvl=CORE FQBN ?= esp8266com:esp8266:$(BUILD_BOARD):xtal=$(BUILD_CPU),baud=$(TEST_BAUD),eesz=$(BUILD_SIZE),ip=$(BUILD_LWIP)$(BUILD_EXTRA) TEST_CONFIG := test_env.cfg TEST_RESULT_XML := test_result.xml TEST_REPORT_XML := test_report.xml TEST_REPORT_HTML := test_report.html TEST_LIST ?= $(wildcard test_*/*.ino) BUILD_FLAGS ?= BS_FLAGS ?= # To enable a test for mock testing, just rename dir+files to '*_sw_*' ifeq ("$(MOCK)", "1") TEST_LIST := $(filter test_sw_%.ino,$(TEST_LIST)) NO_UPLOAD := 1 NO_RUN := 1 endif # To enable verbose mode, call `make V=1` ... V ?= 0 ifeq ("$(V)", "1") BUILD_FLAGS += --verbose BS_FLAGS += --debug endif # ${sketch}.py helper script when building locally mock_script = \ `test -f $(addsuffix .py, $(basename $(1))) && echo "--mock $(addsuffix .py, $(basename $(1)))" || echo ""` help: @echo @echo 'make list - show list of tests' @echo 'make sometest/sometest.ino - run one test' @echo 'make all - run all tests' @echo 'make MOCK=1 all - run all emulation-on-host compatible tests' @echo 'make options: V=1 NO_BUILD=1 NO_UPLOAD=1 NO_RUN=1 MOCK=1' @echo list: showtestlist all: count tests test_report $(TEST_LIST): | virtualenv $(TEST_CONFIG) $(BUILD_DIR) $(HARDWARE_DIR) .NOTPARALLEL: $(TEST_LIST) tests: showtestlist $(TEST_LIST) showtestlist: @echo "-------------------------------- test list:" @printf '%s\n' $(TEST_LIST) @echo "--------------------------------" $(TEST_LIST): LOCAL_BUILD_DIR=$(BUILD_DIR)/$(notdir $@) $(TEST_LIST): LOCAL_DATA_IMG=data.img define build-arduino rm -f $(LOCAL_BUILD_DIR)/build.options.json $(BUILD_TOOL) compile \ $(BUILD_FLAGS) \ --libraries "$(PWD)/libraries" \ --warnings=all \ --build-path $(LOCAL_BUILD_DIR) \ --fqbn=$(FQBN) \ $@ endef define build-mock (cd $(ESP8266_CORE_PATH)/test/host; \ $(MAKE) D=$(V) ULIBDIRS=$(PWD)/libraries/BSTest $(PWD)/$(@:%.ino=%)) $(VENV_PYTHON) $(BS_DIR)/runner.py \ $(BS_FLAGS) \ --name $(basename $(notdir $@)) \ --output $(LOCAL_BUILD_DIR)/$(TEST_RESULT_XML) \ --env-file $(TEST_CONFIG) \ $(call mock_script,$@) \ executable "$(ESP8266_CORE_PATH)/tests/host/bin/$(@:%.ino=%)" || echo ""` endef define upload-data @test -n "$(UPLOAD_PORT)" \ || (echo "Failed to detect upload port, please export UPLOAD_PORT manually" && exit 1) @test ! \( -d $(dir $@)/data/ \) -a \( -e $(dir $@)/make_data.py \) && \ (cd $(dir $@) && ./make_data.py ) || echo "Filesystem creation skipped" @test -d $(dir $@)/data/ && ( \ $(MKFS) \ --create $(dir $@)/data/ \ --size 0xFB000 \ --block 8192 \ --page 256 \ $(LOCAL_BUILD_DIR)/$(LOCAL_DATA_IMG) && \ $(ESPTOOL) \ --chip esp8266 \ --port $(UPLOAD_PORT) \ --baud $(UPLOAD_BAUD) \ --after no_reset \ write_flash 0x300000 $(LOCAL_BUILD_DIR)/$(LOCAL_DATA_IMG) ) \ && (echo "Uploaded filesystem") \ || (echo "Filesystem upload skipped") endef define upload-binary @test -n "$(UPLOAD_PORT)" \ || (echo "Failed to detect upload port, please export UPLOAD_PORT manually" && exit 1) $(ESPTOOL) \ --chip esp8266 \ --port $(UPLOAD_PORT) \ --baud $(UPLOAD_BAUD) \ --after no_reset \ write_flash 0x0 $(LOCAL_BUILD_DIR)/$(notdir $@).bin endef define run-test @test -n "$(UPLOAD_PORT)" \ || (echo "Failed to detect upload port, please export UPLOAD_PORT manually" && exit 1) @echo Running tests $(ESPTOOL) \ --chip esp8266 \ --port $(UPLOAD_PORT) \ --baud $(UPLOAD_BAUD) \ read_flash_status # reset via implicit stub reboot $(VENV_PYTHON) $(BS_DIR)/runner.py \ $(BS_FLAGS) \ --name $(basename $(notdir $@)) \ --output $(LOCAL_BUILD_DIR)/$(TEST_RESULT_XML) \ --env-file $(TEST_CONFIG) \ $(call mock_script,$@) \ port $(UPLOAD_PORT) \ --baudrate $(TEST_BAUD) endef $(TEST_LIST): @echo "--------------------------------" @echo "Running test '$@' of $(words $(TEST_LIST)) tests" mkdir -p $(LOCAL_BUILD_DIR) ifneq ("$(NO_BUILD)","1") @echo Building $(notdir $@) ifeq ("$(MOCK)", "1") $(build-mock) else $(build-arduino) endif endif ifneq ("$(NO_UPLOAD)","1") $(upload-filesystem) $(upload-binary) endif ifneq ("$(NO_RUN)","1") $(run-test) endif $(TEST_REPORT_XML): virtualenv $(BS_DIR)/xunitmerge \ $(shell find $(BUILD_DIR) -name '$(TEST_RESULT_XML)' | xargs echo) \ $(TEST_REPORT_XML) $(TEST_REPORT_HTML): $(TEST_REPORT_XML) | virtualenv $(VENV_JUNIT2HTML) $< $@ test_report: $(TEST_REPORT_HTML) @echo "Test report generated in $(TEST_REPORT_HTML)" $(BUILD_DIR): @mkdir -p $(BUILD_DIR) virtualenv: @make -C $(BS_DIR) PYTHON=$(PYTHON) virtualenv clean: rm -rf $(BUILD_DIR) rm -rf $(BS_DIR)/virtualenv rm -f $(TEST_REPORT_HTML) $(TEST_REPORT_XML) distclean: clean rm -rf libraries/BSTest/virtualenv/ find . -name "*pyc" -exec rm -f {} \; $(TEST_CONFIG): @echo "****** " @echo "****** $(TEST_CONFIG) does not exist" @echo "****** Create one from $(TEST_CONFIG).template" @echo "****** " @false .PHONY: tests all count virtualenv test_report $(TEST_LIST)