Create script to zip up picamera tests and hashes of releavant source files
This commit is contained in:
parent
210c9ac975
commit
9f38b041a6
2 changed files with 143 additions and 0 deletions
120
picamera_tests.py
Executable file
120
picamera_tests.py
Executable file
|
|
@ -0,0 +1,120 @@
|
|||
#! /usr/bin/env python3
|
||||
"""Run the Piamera tests and archive the results in the git repository."""
|
||||
|
||||
import subprocess
|
||||
import shutil
|
||||
import os
|
||||
import posixpath
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
CAM_DIR = os.path.join("src", "openflexure_microscope_server", "things", "camera")
|
||||
ZIP_FILE = "picamera_coverage.zip"
|
||||
COVERAGE_FILE = ".coverage.picamera"
|
||||
HASH_FILE = "picamera_test_hashes.json"
|
||||
|
||||
# If any of the HASHED_FILES change, then the picamera tests need to be re-run.
|
||||
# System independent can be checked on windows even if running tests must be on a Pi
|
||||
HASHED_FILES = [
|
||||
os.path.join(CAM_DIR, "__init__.py"),
|
||||
os.path.join(CAM_DIR, "picamera.py"),
|
||||
os.path.join(CAM_DIR, "picamera_recalibrate_utils.py"),
|
||||
]
|
||||
|
||||
|
||||
def _get_hashes(include_coverage=False):
|
||||
"""Return a dictonary of Git hashes for the HASHED FILES.
|
||||
|
||||
The key is the posixpath to the file so matching works even if the dictionary is
|
||||
compared to a dictionary created on another system.
|
||||
|
||||
The coverage file is hashed when running for debug purposes.
|
||||
|
||||
Git hashes are so the files are line ending indpendent.
|
||||
"""
|
||||
hashes = {}
|
||||
filepaths = HASHED_FILES
|
||||
if include_coverage:
|
||||
filepaths.append(COVERAGE_FILE)
|
||||
for filepath in HASHED_FILES:
|
||||
if not os.path.isfile(filepath):
|
||||
# Sys exit rather than raise for better command line experience
|
||||
print(f"ERROR: {filepath} does not exist!")
|
||||
sys.exit(-1)
|
||||
# Create git hashes for file system independence
|
||||
file_hash = subprocess.check_output(["git", "hash-object", filepath])
|
||||
hashes[posixpath.normpath(filepath)] = file_hash.decode("utf-8").strip()
|
||||
return hashes
|
||||
|
||||
|
||||
def run_tests():
|
||||
"""Run the picamera tests, zip the coverage database, hash relevant source files."""
|
||||
subprocess.run(["pytest", "hardware-specific-tests"], check=True)
|
||||
shutil.copyfile(".coverage", COVERAGE_FILE)
|
||||
hash_dict = _get_hashes(include_coverage=True)
|
||||
with open(HASH_FILE, "w", encoding="utf-8") as json_file:
|
||||
json.dump(hash_dict, json_file)
|
||||
with zipfile.ZipFile(ZIP_FILE, "w") as zipf:
|
||||
zipf.write(COVERAGE_FILE)
|
||||
zipf.write(HASH_FILE)
|
||||
|
||||
|
||||
def unzip_coverage():
|
||||
"""Unzip coverage database if hashes match relevant source files."""
|
||||
if zipfile.is_zipfile(ZIP_FILE):
|
||||
with zipfile.ZipFile(ZIP_FILE, "r") as zip_obj:
|
||||
zip_obj.extractall()
|
||||
else:
|
||||
print("ERROR: Zipfile with coverage results not found.")
|
||||
sys.exit(-1)
|
||||
|
||||
hash_dict = _get_hashes()
|
||||
|
||||
if os.path.isfile(HASH_FILE):
|
||||
with open(HASH_FILE, "r", encoding="utf-8") as json_file:
|
||||
zipped_hash_dict = json.load(json_file)
|
||||
else:
|
||||
print("ERROR: JSON hashes not available. Zipfile is incomplete.")
|
||||
sys.exit(-1)
|
||||
del zipped_hash_dict[COVERAGE_FILE]
|
||||
|
||||
if hash_dict != zipped_hash_dict:
|
||||
# Sys exit rather than raise for better command line experience
|
||||
print(
|
||||
"ERROR: hashes don't match. This probably means the source has changed "
|
||||
"since the tests were last run on the Pi."
|
||||
)
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def main():
|
||||
"""Either run tests or unzip previous results."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"picamera_tests: run or validate PiCamera hardware test coverage.\n\n"
|
||||
"Use 'run' on the Pi to execute tests and package coverage data.\n"
|
||||
"Use 'unzip' on another machine to extract and verify that the test\n"
|
||||
"data matches the source code before unzipping it."
|
||||
),
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
)
|
||||
subparsers = parser.add_subparsers(dest="command", required=True)
|
||||
|
||||
subparsers.add_parser("run", help="Run hardware-specific tests on the PiCamera")
|
||||
|
||||
subparsers.add_parser(
|
||||
"unzip", help="Unzip and verify coverage data on another machine"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "run":
|
||||
run_tests()
|
||||
elif args.command == "unzip":
|
||||
unzip_coverage()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue