From dad1bf6d535b99ce5a959fa8423c9635f3078c62 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 10 Oct 2025 01:00:49 -1000 Subject: [PATCH] docs --- .ai/instructions.md | 5 ++ script/test_component_grouping.py | 57 +++++++++++++++++++- tests/test_build_components/common/README.md | 36 +++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/.ai/instructions.md b/.ai/instructions.md index 1cd77b9136..d2e173472a 100644 --- a/.ai/instructions.md +++ b/.ai/instructions.md @@ -186,6 +186,11 @@ This document provides essential context for AI models interacting with this pro └── components/[component]/ # Component-specific tests ``` Run them using `script/test_build_components`. Use `-c ` to test specific components and `-t ` for specific platforms. + * **Testing All Components Together:** To verify that all components can be tested together without ID conflicts or configuration issues, use: + ```bash + ./script/test_component_grouping.py -e config --all + ``` + This tests all components in a single build to catch conflicts that might not appear when testing components individually. Use `-e config` for fast configuration validation, or `-e compile` for full compilation testing. * **Debugging and Troubleshooting:** * **Debug Tools:** - `esphome config .yaml` to validate configuration. diff --git a/script/test_component_grouping.py b/script/test_component_grouping.py index 69d043ad7c..a2cee6e888 100755 --- a/script/test_component_grouping.py +++ b/script/test_component_grouping.py @@ -24,6 +24,7 @@ from script.analyze_component_buses import ( def test_component_group( components: list[str], platform: str, + esphome_command: str = "compile", dry_run: bool = False, ) -> bool: """Test a group of components together. @@ -31,13 +32,22 @@ def test_component_group( Args: components: List of component names to test together platform: Platform to test on (e.g., "esp32-idf") + esphome_command: ESPHome command to run (config/compile/clean) dry_run: If True, only print the command without running it Returns: True if test passed, False otherwise """ components_str = ",".join(components) - cmd = ["./script/test_build_components", "-c", components_str, "-t", platform] + cmd = [ + "./script/test_build_components", + "-c", + components_str, + "-t", + platform, + "-e", + esphome_command, + ] print(f"\n{'=' * 80}") print(f"Testing {len(components)} components on {platform}:") @@ -69,6 +79,18 @@ def main() -> None: default="esp32-idf", help="Platform to test (default: esp32-idf)", ) + parser.add_argument( + "-e", + "--esphome-command", + default="compile", + choices=["config", "compile", "clean"], + help="ESPHome command to run (default: compile)", + ) + parser.add_argument( + "--all", + action="store_true", + help="Test all components (sets --min-size=1, --max-size=10000, --max-groups=10000)", + ) parser.add_argument( "--min-size", type=int, @@ -100,6 +122,35 @@ def main() -> None: args = parser.parse_args() + # If --all is specified, test all components without grouping + if args.all: + # Get all components from tests/components directory + components_dir = Path("tests/components") + all_components = sorted( + [d.name for d in components_dir.iterdir() if d.is_dir()] + ) + + if not all_components: + print(f"\nNo components found in {components_dir}") + return + + print(f"\nTesting all {len(all_components)} components together") + + success = test_component_group( + all_components, args.platform, args.esphome_command, args.dry_run + ) + + # Print summary + print(f"\n{'=' * 80}") + print("TEST SUMMARY") + print(f"{'=' * 80}") + status = "✅ PASS" if success else "❌ FAIL" + print(f"{status} All components: {len(all_components)} components") + + if not args.dry_run and not success: + sys.exit(1) + return + print("Analyzing all components...") components, non_groupable, _ = analyze_all_components(Path("tests/components")) @@ -150,7 +201,9 @@ def main() -> None: if len(comp_list) > args.max_size: comp_list = comp_list[: args.max_size] - success = test_component_group(comp_list, args.platform, args.dry_run) + success = test_component_group( + comp_list, args.platform, args.esphome_command, args.dry_run + ) results.append((signature, comp_list, success)) if not args.dry_run and not success: diff --git a/tests/test_build_components/common/README.md b/tests/test_build_components/common/README.md index c12941c6fe..76f14b8664 100644 --- a/tests/test_build_components/common/README.md +++ b/tests/test_build_components/common/README.md @@ -198,12 +198,48 @@ When platform-specific parameters are needed, inline the full configuration rath **Note**: Some components legitimately require `!extend` or `!remove` for platform-specific features (e.g., `adc` removing ESP32-only `attenuation` parameter on ESP8266). These are correctly identified as non-groupable. +## Testing Components + +### Testing Individual Components +Test specific components using `test_build_components`: +```bash +# Test a single component +./script/test_build_components -c bme280_i2c -t esp32-idf -e config + +# Test multiple components +./script/test_build_components -c bme280_i2c,bh1750,sht3xd -t esp32-idf -e compile +``` + +### Testing All Components Together +To verify that all components can be tested together without ID conflicts or configuration issues: +```bash +./script/test_component_grouping.py -e config --all +``` + +This tests all components in a single build to catch conflicts that might not appear when testing components individually. This is useful for: +- Detecting ID conflicts between components +- Validating that components can coexist in the same configuration +- Ensuring proper `i2c_id`, `spi_id`, `uart_id` specifications + +Use `-e config` for fast configuration validation, or `-e compile` for full compilation testing. + +### Testing Component Groups +Test specific groups of components by bus signature: +```bash +# Test all I2C components together +./script/test_component_grouping.py -s i2c -e config + +# Test with custom group sizes +./script/test_component_grouping.py --min-size 5 --max-size 20 --max-groups 3 +``` + ## Implementation Details ### Scripts - `script/analyze_component_buses.py`: Analyzes components to detect bus usage and grouping compatibility - `script/merge_component_configs.py`: Merges multiple component configs into a single test file - `script/test_build_components.py`: Main test runner with intelligent grouping +- `script/test_component_grouping.py`: Test component groups or all components together - `script/split_components_for_ci.py`: Splits components into batches for parallel CI execution ### Configuration