mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #19546 from MrKevinWeiss/pr/reruntests
Enable compile_and_test_for_board to skip if nothing changed
This commit is contained in:
commit
ed44a43464
@ -44,6 +44,7 @@ usage: compile_and_test_for_board.py [-h] [--applications APPLICATIONS]
|
||||
[--test-targets TEST_TARGETS]
|
||||
[--test-available-targets TEST_AVAILABLE_TARGETS]
|
||||
[--report-xml] [--jobs JOBS]
|
||||
[--only-if-changed]
|
||||
riot_directory board [result_directory]
|
||||
|
||||
positional arguments:
|
||||
@ -84,6 +85,9 @@ optional arguments:
|
||||
(default: False)
|
||||
--jobs JOBS, -j JOBS Parallel building (0 means not limit, like '--jobs')
|
||||
(default: None)
|
||||
--only-if-changed, -c
|
||||
Only test if the application has changed since last
|
||||
test (default: False)
|
||||
```
|
||||
""" # noqa
|
||||
|
||||
@ -225,6 +229,7 @@ def is_in_directory(path, directory):
|
||||
return path.startswith(directory)
|
||||
|
||||
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
class RIOTApplication:
|
||||
"""RIOT Application representation.
|
||||
|
||||
@ -245,6 +250,7 @@ class RIOTApplication:
|
||||
)
|
||||
FLASH_TARGETS = ("flash-only",)
|
||||
TEST_TARGETS = ("test",)
|
||||
TEST_INPUT_HASH = ("test-input-hash-changed",)
|
||||
TEST_AVAILABLE_TARGETS = ("test/available",)
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
@ -252,6 +258,7 @@ class RIOTApplication:
|
||||
self.board = board
|
||||
self.riotdir = riotdir
|
||||
self.appdir = appdir
|
||||
self.hashdir = os.path.abspath(os.path.join(resultdir, "hashes", appdir))
|
||||
self.resultdir = os.path.join(resultdir, appdir)
|
||||
if junit:
|
||||
if not junit_xml:
|
||||
@ -368,8 +375,11 @@ class RIOTApplication:
|
||||
incremental=False,
|
||||
jobs=False,
|
||||
with_test_only=False,
|
||||
only_if_changed=False,
|
||||
):
|
||||
# pylint:disable=too-many-arguments
|
||||
# pylint:disable=too-many-nested-blocks
|
||||
# pylint:disable=too-many-branches
|
||||
"""Compile and execute test if available.
|
||||
|
||||
Checks for board supported/enough memory, compiles.
|
||||
@ -422,8 +432,28 @@ class RIOTApplication:
|
||||
if clean_after:
|
||||
self.clean_intermediates()
|
||||
|
||||
# pylint: disable=too-many-nested-blocks
|
||||
if runtest:
|
||||
if has_test:
|
||||
if only_if_changed:
|
||||
try:
|
||||
out = self.make(
|
||||
self.TEST_INPUT_HASH,
|
||||
env={"RIOT_TEST_HASH_DIR": self.hashdir},
|
||||
)
|
||||
hash_match = "hashes match" in out.lower()
|
||||
self.logger.info("Hashes match: %r", hash_match)
|
||||
if hash_match:
|
||||
self._skip(
|
||||
"bins_unchanged",
|
||||
f"{self.appdir} matched test input hashes.",
|
||||
)
|
||||
if clean_after:
|
||||
self.clean()
|
||||
self.logger.info("Success")
|
||||
return
|
||||
except subprocess.CalledProcessError as err:
|
||||
self._make_handle_error(self.TEST_INPUT_HASH[0], err)
|
||||
setuptasks = collections.OrderedDict([("flash", self.FLASH_TARGETS)])
|
||||
self.make_with_outfile(
|
||||
"test", self.TEST_TARGETS, save_output=True, setuptasks=setuptasks
|
||||
@ -732,7 +762,6 @@ PARSER.add_argument(
|
||||
default=False,
|
||||
help="Output results to report.xml in the " "result_directory",
|
||||
)
|
||||
|
||||
PARSER.add_argument(
|
||||
"--jobs",
|
||||
"-j",
|
||||
@ -740,6 +769,14 @@ PARSER.add_argument(
|
||||
default=None,
|
||||
help="Parallel building (0 means not limit, like '--jobs')",
|
||||
)
|
||||
# Arg that allows hashes of tests to be saved locally in a hashes folder
|
||||
# and used to skip tests if new hashes match.
|
||||
PARSER.add_argument(
|
||||
"--only-if-changed",
|
||||
"-c",
|
||||
action="store_true",
|
||||
help="Only test if the application has changed since last test",
|
||||
)
|
||||
|
||||
|
||||
def main(args):
|
||||
@ -798,6 +835,7 @@ def main(args):
|
||||
incremental=args.incremental,
|
||||
jobs=args.jobs,
|
||||
with_test_only=args.with_test_only,
|
||||
only_if_changed=args.only_if_changed,
|
||||
)
|
||||
for app in applications
|
||||
]
|
||||
|
@ -85,6 +85,9 @@ test-with-config/check-config:
|
||||
done; \
|
||||
${COLOR_ECHO} -n "${COLOR_RESET}"
|
||||
|
||||
|
||||
RIOT_TEST_HASH_DIR ?= $(BINDIR)
|
||||
|
||||
# this target only makes sense if an ELFFILE is actually created, thus guard by
|
||||
# RIOTNOLINK="".
|
||||
ifeq (,$(RIOTNOLINK))
|
||||
@ -92,10 +95,33 @@ ifeq (,$(RIOTNOLINK))
|
||||
$(error HASHFILE is empty for $(BOARD))
|
||||
endif
|
||||
test-input-hash: $(TESTS) $(TESTS_WITH_CONFIG) $(TESTS_AS_ROOT) $(HASHFILE) $(TEST_EXTRA_FILES)
|
||||
sha1sum $^ > $(BINDIR)/test-input-hash.sha1
|
||||
sha1sum $^ > $(RIOT_TEST_HASH_DIR)/test-input-hash.sha1
|
||||
else
|
||||
# .SECONDARY creates the bin folder, we depend on it to avoid writing to it
|
||||
# prior to it being created when concurrent building is used
|
||||
test-input-hash: .SECONDARY
|
||||
$(file >$(BINDIR)/test-input-hash.sha1,no binary generated due to RIOTNOLINK=1)
|
||||
$(file >$(RIOT_TEST_HASH_DIR)/test-input-hash.sha1,no binary generated due to RIOTNOLINK=1)
|
||||
endif
|
||||
|
||||
# Helper function to compare two strings
|
||||
define compare_strings
|
||||
$(and $(filter $1,$2),$(filter $2,$1))
|
||||
endef
|
||||
|
||||
# Target to test only if the input hash has changed
|
||||
.PHONY: test-input-hash-changed
|
||||
test-input-hash-changed:
|
||||
@if [ ! -f "$(RIOT_TEST_HASH_DIR)/test-input-hash.sha1" ]; then \
|
||||
echo "Old hash file doesn't exist. Generating hash and running tests..."; \
|
||||
mkdir -p $(RIOT_TEST_HASH_DIR); \
|
||||
$(MAKE) test-input-hash; \
|
||||
else \
|
||||
OLD_HASH=$$(cat $(RIOT_TEST_HASH_DIR)/test-input-hash.sha1); \
|
||||
$(MAKE) test-input-hash; \
|
||||
NEW_HASH=$$(cat $(RIOT_TEST_HASH_DIR)/test-input-hash.sha1); \
|
||||
if [ "$${OLD_HASH}" != "$${NEW_HASH}" ]; then \
|
||||
echo "Hashes do not match."; \
|
||||
else \
|
||||
echo "Hashes match."; \
|
||||
fi; \
|
||||
fi
|
||||
|
@ -46,6 +46,7 @@ export RIOTMAKE # Location of all supplemental Makefiles (such as t
|
||||
export RIOTKCONFIG # Location of all supplemental Kconfig files
|
||||
export BINDIRBASE # This is the folder where the application should be built in. For each BOARD a different subfolder is used.
|
||||
export BINDIR # This is the folder where the application should be built in.
|
||||
export RIOT_TEST_HASH_DIR # The dir to generate the test-input-hash.sha1 file for checking if a test has changed, uses BINDIR by default.
|
||||
export CARGO_TARGET_DIR # This is the folder where Rust parts of the application should be built in.
|
||||
export BUILD_DIR # This is the base folder to store common build files and artifacts, e.g. test results.
|
||||
export APPDIR # The base folder containing the application
|
||||
|
Loading…
Reference in New Issue
Block a user