mirror of
https://github.com/esphome/esphome.git
synced 2025-10-12 14:53:49 +01:00
uart grouping
This commit is contained in:
@@ -347,7 +347,7 @@ def final_validate_device_schema(
|
||||
|
||||
def validate_pin(opt, device):
|
||||
def validator(value):
|
||||
if opt in device:
|
||||
if opt in device and not CORE.testing_mode:
|
||||
raise cv.Invalid(
|
||||
f"The uart {opt} is used both by {name} and {device[opt]}, "
|
||||
f"but can only be used by one. Please create a new uart bus for {name}."
|
||||
|
@@ -50,16 +50,26 @@ VALID_BUS_CONFIGS = {
|
||||
"uart_9600_even",
|
||||
}
|
||||
|
||||
# Bus types that support component grouping
|
||||
# Bus types that support component grouping for config validation
|
||||
# I2C and SPI are shared buses with addressing/CS pins
|
||||
# BLE sensors scan independently and don't conflict
|
||||
# UART is point-to-point and components would conflict on the same bus
|
||||
# UART is point-to-point but can be grouped for testing since --testing-mode
|
||||
# bypasses the conflict validation (we only care that configs compile)
|
||||
GROUPABLE_BUS_TYPES = {
|
||||
"ble",
|
||||
"i2c",
|
||||
"i2c_low_freq",
|
||||
"qspi",
|
||||
"spi",
|
||||
"uart",
|
||||
"uart_115200",
|
||||
"uart_1200",
|
||||
"uart_1200_even",
|
||||
"uart_19200",
|
||||
"uart_38400",
|
||||
"uart_4800",
|
||||
"uart_4800_even",
|
||||
"uart_9600_even",
|
||||
}
|
||||
|
||||
|
||||
@@ -194,15 +204,15 @@ def create_grouping_signature(
|
||||
"""Create a signature string for grouping components.
|
||||
|
||||
Components with the same signature can be grouped together for testing.
|
||||
Only includes groupable bus types (I2C, SPI, BLE) - excludes point-to-point
|
||||
protocols like UART that can't be shared.
|
||||
Includes groupable bus types (I2C, SPI, BLE, UART) that can be validated
|
||||
together using --testing-mode to bypass runtime conflicts.
|
||||
|
||||
Args:
|
||||
platform_buses: Mapping of platform to list of buses
|
||||
platform: The specific platform to create signature for
|
||||
|
||||
Returns:
|
||||
Signature string (e.g., "i2c" or "spi") or empty if no groupable buses
|
||||
Signature string (e.g., "i2c" or "uart") or empty if no groupable buses
|
||||
"""
|
||||
buses = platform_buses.get(platform, [])
|
||||
if not buses:
|
||||
|
@@ -1,119 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
help() {
|
||||
echo "Usage: $0 [-e <config|compile|clean>] [-c <string>] [-t <string>] [-f]" 1>&2
|
||||
echo 1>&2
|
||||
echo " - e - Parameter for esphome command. Default compile. Common alternative is config." 1>&2
|
||||
echo " - c - Component folder name(s) to test. Default *. Supports comma-separated list. E.g. '-c logger' or '-c logger,api,ota'." 1>&2
|
||||
echo " - t - Target name to test. Put '-t list' to display all possibilities. E.g. '-t esp32-s2-idf-51'." 1>&2
|
||||
echo " - f - Continue on fail. Don't exit on first error." 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse parameter:
|
||||
# - `e` - Parameter for `esphome` command. Default `compile`. Common alternative is `config`.
|
||||
# - `c` - Component folder name to test. Default `*`.
|
||||
# - `f` - Continue on fail flag.
|
||||
esphome_command="compile"
|
||||
target_component="*"
|
||||
continue_on_fail=false
|
||||
while getopts e:c:t:f flag
|
||||
do
|
||||
case $flag in
|
||||
e) esphome_command=${OPTARG};;
|
||||
c) target_component=${OPTARG};;
|
||||
t) requested_target_platform=${OPTARG};;
|
||||
f) continue_on_fail=true;;
|
||||
\?) help;;
|
||||
esac
|
||||
done
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if ! [ -d "./tests/test_build_components/build" ]; then
|
||||
mkdir ./tests/test_build_components/build
|
||||
fi
|
||||
|
||||
start_esphome() {
|
||||
if [ -n "$requested_target_platform" ] && [ "$requested_target_platform" != "$target_platform_with_version" ]; then
|
||||
echo "Skipping $target_platform_with_version"
|
||||
return
|
||||
fi
|
||||
# create dynamic yaml file in `build` folder.
|
||||
# `./tests/test_build_components/build/[target_component].[test_name].[target_platform_with_version].yaml`
|
||||
component_test_file="./tests/test_build_components/build/$target_component.$test_name.$target_platform_with_version.yaml"
|
||||
|
||||
cp $target_platform_file $component_test_file
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# macOS sed is...different
|
||||
sed -i '' "s!\$component_test_file!../../.$f!g" $component_test_file
|
||||
else
|
||||
sed -i "s!\$component_test_file!../../.$f!g" $component_test_file
|
||||
fi
|
||||
|
||||
# Start esphome process
|
||||
echo "> [$target_component] [$test_name] [$target_platform_with_version]"
|
||||
set -x
|
||||
# TODO: Validate escape of Command line substitution value
|
||||
if [ "$continue_on_fail" = true ]; then
|
||||
python3 -m esphome -s component_name $target_component -s component_dir ../../components/$target_component -s test_name $test_name -s target_platform $target_platform $esphome_command $component_test_file || true
|
||||
else
|
||||
python3 -m esphome -s component_name $target_component -s component_dir ../../components/$target_component -s test_name $test_name -s target_platform $target_platform $esphome_command $component_test_file
|
||||
fi
|
||||
{ set +x; } 2>/dev/null
|
||||
}
|
||||
|
||||
# Split comma-separated components into array
|
||||
IFS=',' read -r -a component_list <<< "$target_component"
|
||||
|
||||
# Find all test yaml files.
|
||||
# - `./tests/components/[target_component]/[test_name].[target_platform].yaml`
|
||||
# - `./tests/components/[target_component]/[test_name].all.yaml`
|
||||
for component_pattern in "${component_list[@]}"; do
|
||||
for f in ./tests/components/$component_pattern/*.*.yaml; do
|
||||
[ -f "$f" ] || continue
|
||||
IFS='/' read -r -a folder_name <<< "$f"
|
||||
target_component="${folder_name[3]}"
|
||||
|
||||
IFS='.' read -r -a file_name <<< "${folder_name[4]}"
|
||||
test_name="${file_name[0]}"
|
||||
target_platform="${file_name[1]}"
|
||||
file_name_parts=${#file_name[@]}
|
||||
|
||||
if [ "$target_platform" = "all" ] || [ $file_name_parts = 2 ]; then
|
||||
# Test has *not* defined a specific target platform. Need to run tests for all possible target platforms.
|
||||
|
||||
for target_platform_file in ./tests/test_build_components/build_components_base.*.yaml; do
|
||||
IFS='/' read -r -a folder_name <<< "$target_platform_file"
|
||||
IFS='.' read -r -a file_name <<< "${folder_name[3]}"
|
||||
target_platform="${file_name[1]}"
|
||||
|
||||
start_esphome
|
||||
done
|
||||
|
||||
else
|
||||
# Test has defined a specific target platform.
|
||||
|
||||
# Validate we have a base test yaml for selected platform.
|
||||
# The target_platform is sourced from the following location.
|
||||
# 1. `./tests/test_build_components/build_components_base.[target_platform].yaml`
|
||||
# 2. `./tests/test_build_components/build_components_base.[target_platform]-ard.yaml`
|
||||
target_platform_file="./tests/test_build_components/build_components_base.$target_platform.yaml"
|
||||
if ! [ -f "$target_platform_file" ]; then
|
||||
echo "No base test file [./tests/test_build_components/build_components_base.$target_platform.yaml] for component test [$f] found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for target_platform_file in ./tests/test_build_components/build_components_base.$target_platform*.yaml; do
|
||||
# trim off "./tests/test_build_components/build_components_base." prefix
|
||||
target_platform_with_version=${target_platform_file:52}
|
||||
# ...now remove suffix starting with "." leaving just the test target hardware and software platform (possibly with version)
|
||||
# For example: "esp32-s3-idf-50"
|
||||
target_platform_with_version=${target_platform_with_version%.*}
|
||||
start_esphome
|
||||
done
|
||||
fi
|
||||
done
|
||||
done
|
1
script/test_build_components
Symbolic link
1
script/test_build_components
Symbolic link
@@ -0,0 +1 @@
|
||||
test_build_components.py
|
@@ -336,7 +336,7 @@ def run_grouped_component_tests(
|
||||
if buses:
|
||||
signature = create_grouping_signature({platform: buses}, platform)
|
||||
# Only add to grouped_components if signature is non-empty
|
||||
# (empty means only non-groupable buses like UART)
|
||||
# (empty means component has no groupable bus configurations)
|
||||
if signature:
|
||||
grouped_components[(platform, signature)].append(component)
|
||||
|
||||
|
Reference in New Issue
Block a user