mirror of
https://github.com/esphome/esphome.git
synced 2025-10-12 14:53:49 +01:00
test
This commit is contained in:
@@ -125,7 +125,7 @@ def run_esphome_test(
|
|||||||
esphome_command: str,
|
esphome_command: str,
|
||||||
continue_on_fail: bool,
|
continue_on_fail: bool,
|
||||||
use_testing_mode: bool = False,
|
use_testing_mode: bool = False,
|
||||||
) -> bool:
|
) -> tuple[bool, str]:
|
||||||
"""Run esphome test for a single component.
|
"""Run esphome test for a single component.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -140,7 +140,7 @@ def run_esphome_test(
|
|||||||
use_testing_mode: Whether to use --testing-mode flag
|
use_testing_mode: Whether to use --testing-mode flag
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if test passed, False otherwise
|
Tuple of (success status, command string)
|
||||||
"""
|
"""
|
||||||
test_name = test_file.stem.split(".")[0]
|
test_name = test_file.stem.split(".")[0]
|
||||||
|
|
||||||
@@ -187,6 +187,9 @@ def run_esphome_test(
|
|||||||
# Add command and config file
|
# Add command and config file
|
||||||
cmd.extend([esphome_command, str(output_file)])
|
cmd.extend([esphome_command, str(output_file)])
|
||||||
|
|
||||||
|
# Build command string for display/logging
|
||||||
|
cmd_str = " ".join(cmd)
|
||||||
|
|
||||||
# Run command
|
# Run command
|
||||||
print(f"> [{component}] [{test_name}] [{platform_with_version}]")
|
print(f"> [{component}] [{test_name}] [{platform_with_version}]")
|
||||||
if use_testing_mode:
|
if use_testing_mode:
|
||||||
@@ -194,11 +197,11 @@ def run_esphome_test(
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(cmd, check=not continue_on_fail)
|
result = subprocess.run(cmd, check=not continue_on_fail)
|
||||||
return result.returncode == 0
|
return result.returncode == 0, cmd_str
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
if not continue_on_fail:
|
if not continue_on_fail:
|
||||||
raise
|
raise
|
||||||
return False
|
return False, cmd_str
|
||||||
|
|
||||||
|
|
||||||
def run_grouped_test(
|
def run_grouped_test(
|
||||||
@@ -210,7 +213,7 @@ def run_grouped_test(
|
|||||||
tests_dir: Path,
|
tests_dir: Path,
|
||||||
esphome_command: str,
|
esphome_command: str,
|
||||||
continue_on_fail: bool,
|
continue_on_fail: bool,
|
||||||
) -> bool:
|
) -> tuple[bool, str]:
|
||||||
"""Run esphome test for a group of components with shared bus configs.
|
"""Run esphome test for a group of components with shared bus configs.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -224,7 +227,7 @@ def run_grouped_test(
|
|||||||
continue_on_fail: Whether to continue on failure
|
continue_on_fail: Whether to continue on failure
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if test passed, False otherwise
|
Tuple of (success status, command string)
|
||||||
"""
|
"""
|
||||||
# Create merged config
|
# Create merged config
|
||||||
group_name = "_".join(components[:3]) # Use first 3 components for name
|
group_name = "_".join(components[:3]) # Use first 3 components for name
|
||||||
@@ -251,7 +254,8 @@ def run_grouped_test(
|
|||||||
print(f"Error merging configs for {components}: {e}")
|
print(f"Error merging configs for {components}: {e}")
|
||||||
if not continue_on_fail:
|
if not continue_on_fail:
|
||||||
raise
|
raise
|
||||||
return False
|
# Return empty command string since we failed before building the command
|
||||||
|
return False, f"# Failed during config merge: {e}"
|
||||||
|
|
||||||
# Create test file that includes merged config
|
# Create test file that includes merged config
|
||||||
output_file = build_dir / f"test_{group_name}.{platform_with_version}.yaml"
|
output_file = build_dir / f"test_{group_name}.{platform_with_version}.yaml"
|
||||||
@@ -282,6 +286,9 @@ def run_grouped_test(
|
|||||||
str(output_file),
|
str(output_file),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Build command string for display/logging
|
||||||
|
cmd_str = " ".join(cmd)
|
||||||
|
|
||||||
# Run command
|
# Run command
|
||||||
components_str = ", ".join(components)
|
components_str = ", ".join(components)
|
||||||
print(f"> [GROUPED: {components_str}] [{platform_with_version}]")
|
print(f"> [GROUPED: {components_str}] [{platform_with_version}]")
|
||||||
@@ -289,11 +296,11 @@ def run_grouped_test(
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(cmd, check=not continue_on_fail)
|
result = subprocess.run(cmd, check=not continue_on_fail)
|
||||||
return result.returncode == 0
|
return result.returncode == 0, cmd_str
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
if not continue_on_fail:
|
if not continue_on_fail:
|
||||||
raise
|
raise
|
||||||
return False
|
return False, cmd_str
|
||||||
|
|
||||||
|
|
||||||
def run_grouped_component_tests(
|
def run_grouped_component_tests(
|
||||||
@@ -304,7 +311,7 @@ def run_grouped_component_tests(
|
|||||||
build_dir: Path,
|
build_dir: Path,
|
||||||
esphome_command: str,
|
esphome_command: str,
|
||||||
continue_on_fail: bool,
|
continue_on_fail: bool,
|
||||||
) -> tuple[set[tuple[str, str]], list[str], list[str]]:
|
) -> tuple[set[tuple[str, str]], list[str], list[str], dict[str, str]]:
|
||||||
"""Run grouped component tests.
|
"""Run grouped component tests.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -317,11 +324,12 @@ def run_grouped_component_tests(
|
|||||||
continue_on_fail: Whether to continue on failure
|
continue_on_fail: Whether to continue on failure
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Tuple of (tested_components, passed_tests, failed_tests)
|
Tuple of (tested_components, passed_tests, failed_tests, failed_commands)
|
||||||
"""
|
"""
|
||||||
tested_components = set()
|
tested_components = set()
|
||||||
passed_tests = []
|
passed_tests = []
|
||||||
failed_tests = []
|
failed_tests = []
|
||||||
|
failed_commands = {} # Map test_id to command string
|
||||||
|
|
||||||
# Group components by platform and bus signature
|
# Group components by platform and bus signature
|
||||||
grouped_components: dict[tuple[str, str], list[str]] = defaultdict(list)
|
grouped_components: dict[tuple[str, str], list[str]] = defaultdict(list)
|
||||||
@@ -524,7 +532,7 @@ def run_grouped_component_tests(
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Run grouped test
|
# Run grouped test
|
||||||
success = run_grouped_test(
|
success, cmd_str = run_grouped_test(
|
||||||
components=components_to_group,
|
components=components_to_group,
|
||||||
platform=platform,
|
platform=platform,
|
||||||
platform_with_version=platform_with_version,
|
platform_with_version=platform_with_version,
|
||||||
@@ -547,8 +555,9 @@ def run_grouped_component_tests(
|
|||||||
passed_tests.append(test_id)
|
passed_tests.append(test_id)
|
||||||
else:
|
else:
|
||||||
failed_tests.append(test_id)
|
failed_tests.append(test_id)
|
||||||
|
failed_commands[test_id] = cmd_str
|
||||||
|
|
||||||
return tested_components, passed_tests, failed_tests
|
return tested_components, passed_tests, failed_tests, failed_commands
|
||||||
|
|
||||||
|
|
||||||
def run_individual_component_test(
|
def run_individual_component_test(
|
||||||
@@ -563,6 +572,7 @@ def run_individual_component_test(
|
|||||||
tested_components: set[tuple[str, str]],
|
tested_components: set[tuple[str, str]],
|
||||||
passed_tests: list[str],
|
passed_tests: list[str],
|
||||||
failed_tests: list[str],
|
failed_tests: list[str],
|
||||||
|
failed_commands: dict[str, str],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Run an individual component test if not already tested in a group.
|
"""Run an individual component test if not already tested in a group.
|
||||||
|
|
||||||
@@ -578,13 +588,14 @@ def run_individual_component_test(
|
|||||||
tested_components: Set of already tested components
|
tested_components: Set of already tested components
|
||||||
passed_tests: List to append passed test IDs
|
passed_tests: List to append passed test IDs
|
||||||
failed_tests: List to append failed test IDs
|
failed_tests: List to append failed test IDs
|
||||||
|
failed_commands: Dict to store failed test commands
|
||||||
"""
|
"""
|
||||||
# Skip if already tested in a group
|
# Skip if already tested in a group
|
||||||
if (component, platform_with_version) in tested_components:
|
if (component, platform_with_version) in tested_components:
|
||||||
return
|
return
|
||||||
|
|
||||||
test_name = test_file.stem.split(".")[0]
|
test_name = test_file.stem.split(".")[0]
|
||||||
success = run_esphome_test(
|
success, cmd_str = run_esphome_test(
|
||||||
component=component,
|
component=component,
|
||||||
test_file=test_file,
|
test_file=test_file,
|
||||||
platform=platform,
|
platform=platform,
|
||||||
@@ -599,6 +610,7 @@ def run_individual_component_test(
|
|||||||
passed_tests.append(test_id)
|
passed_tests.append(test_id)
|
||||||
else:
|
else:
|
||||||
failed_tests.append(test_id)
|
failed_tests.append(test_id)
|
||||||
|
failed_commands[test_id] = cmd_str
|
||||||
|
|
||||||
|
|
||||||
def test_components(
|
def test_components(
|
||||||
@@ -645,10 +657,16 @@ def test_components(
|
|||||||
failed_tests = []
|
failed_tests = []
|
||||||
passed_tests = []
|
passed_tests = []
|
||||||
tested_components = set() # Track which components were tested in groups
|
tested_components = set() # Track which components were tested in groups
|
||||||
|
failed_commands = {} # Track commands for failed tests
|
||||||
|
|
||||||
# First, run grouped tests if grouping is enabled
|
# First, run grouped tests if grouping is enabled
|
||||||
if enable_grouping:
|
if enable_grouping:
|
||||||
tested_components, passed_tests, failed_tests = run_grouped_component_tests(
|
(
|
||||||
|
tested_components,
|
||||||
|
passed_tests,
|
||||||
|
failed_tests,
|
||||||
|
failed_commands,
|
||||||
|
) = run_grouped_component_tests(
|
||||||
all_tests=all_tests,
|
all_tests=all_tests,
|
||||||
platform_filter=platform_filter,
|
platform_filter=platform_filter,
|
||||||
platform_bases=platform_bases,
|
platform_bases=platform_bases,
|
||||||
@@ -684,6 +702,7 @@ def test_components(
|
|||||||
tested_components=tested_components,
|
tested_components=tested_components,
|
||||||
passed_tests=passed_tests,
|
passed_tests=passed_tests,
|
||||||
failed_tests=failed_tests,
|
failed_tests=failed_tests,
|
||||||
|
failed_commands=failed_commands,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Platform-specific test
|
# Platform-specific test
|
||||||
@@ -717,6 +736,7 @@ def test_components(
|
|||||||
tested_components=tested_components,
|
tested_components=tested_components,
|
||||||
passed_tests=passed_tests,
|
passed_tests=passed_tests,
|
||||||
failed_tests=failed_tests,
|
failed_tests=failed_tests,
|
||||||
|
failed_commands=failed_commands,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Print summary
|
# Print summary
|
||||||
@@ -728,6 +748,17 @@ def test_components(
|
|||||||
print("\nFailed tests:")
|
print("\nFailed tests:")
|
||||||
for test in failed_tests:
|
for test in failed_tests:
|
||||||
print(f" - {test}")
|
print(f" - {test}")
|
||||||
|
|
||||||
|
# Print failed commands at the end for easy copy-paste from CI logs
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("Failed test commands (copy-paste to reproduce locally):")
|
||||||
|
print("=" * 80)
|
||||||
|
for test in failed_tests:
|
||||||
|
if test in failed_commands:
|
||||||
|
print(f"\n# {test}")
|
||||||
|
print(failed_commands[test])
|
||||||
|
print()
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
Reference in New Issue
Block a user