#!/usr/bin/env python3 import argparse from functools import partial import os from pathlib import Path import sys from build_helpers import ( PLATFORMIO_GOOGLE_TEST_LIB, build_and_run, load_test_manifest_overrides, ) from helpers import get_all_components, root_path # Path to /tests/components COMPONENTS_TESTS_DIR: Path = Path(root_path) / "tests" / "components" PLATFORMIO_OPTIONS = { "build_type": "debug", "build_unflags": [ "-Os", # remove size-opt flag ], "build_flags": [ "-Og", # optimize for debug "-DESPHOME_DEBUG", # enable debug assertions # Enable the address and undefined behavior sanitizers "-fsanitize=address", "-fsanitize=undefined", "-fno-omit-frame-pointer", ], "debug_build_flags": [ # only for debug builds "-g3", # max debug info "-ggdb3", ], } def run_tests(selected_components: list[str]) -> int: os.environ["ASAN_OPTIONS"] = "detect_leaks=0" return build_and_run( selected_components=selected_components, tests_dir=COMPONENTS_TESTS_DIR, manifest_override_loader=partial( load_test_manifest_overrides, tests_dir=COMPONENTS_TESTS_DIR ), config_prefix="cpptests", friendly_name="CPP Unit Tests", libraries=PLATFORMIO_GOOGLE_TEST_LIB, platformio_options=PLATFORMIO_OPTIONS, main_entry="main.cpp", label="unit tests", ) def main() -> None: parser = argparse.ArgumentParser( description="Run C++ unit tests for ESPHome components." ) parser.add_argument( "components", nargs="*", help="List of components to test. Use --all to test all known components.", ) parser.add_argument("--all", action="store_true", help="Test all known components.") args = parser.parse_args() if args.all: components: list[str] = get_all_components() else: components: list[str] = args.components sys.exit(run_tests(components)) if __name__ == "__main__": main()