-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
242 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
name: Python Tests with Coverage | ||
on: | ||
push: | ||
branches: [main] | ||
paths: | ||
- "**.py" | ||
pull_request: | ||
branches: [main] | ||
paths: | ||
- "**.py" | ||
|
||
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs | ||
# `contents` is for permission to the contents of the repository. | ||
# `pull-requests` is for permission to pull request | ||
permissions: | ||
contents: write | ||
checks: write | ||
pull-requests: write | ||
|
||
jobs: | ||
test-python: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: ["3.8", "3.13"] | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install -e '.[test]' | ||
- name: Run tests with pytest and coverage | ||
run: | | ||
pytest --junitxml pytest.xml --cov-report term-missing:skip-covered --cov idf_ci tests/ | tee pytest-coverage.txt | ||
- name: Upload coverage report to PR (Python 3.13 only) | ||
if: matrix.python-version == '3.13' && github.event_name == 'pull_request' | ||
uses: MishaKav/pytest-coverage-comment@v1 | ||
with: | ||
pytest-coverage-path: ./pytest-coverage.txt | ||
junitxml-path: ./pytest.xml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import os | ||
from pathlib import Path | ||
|
||
import pytest | ||
from click.testing import CliRunner | ||
|
||
from idf_ci.cli import cli | ||
|
||
|
||
@pytest.fixture | ||
def runner(): | ||
return CliRunner() | ||
|
||
|
||
@pytest.fixture | ||
def temp_dir(tmp_path: Path) -> str: | ||
return str(tmp_path) | ||
|
||
|
||
def test_build_profile_init(runner, temp_dir): | ||
# Test init command with default path | ||
with runner.isolated_filesystem(): | ||
result = runner.invoke(cli, ['build-profile', 'init', '--path', temp_dir]) | ||
assert result.exit_code == 0 | ||
assert f'Created build profile at {os.path.join(temp_dir, ".idf_build_apps.toml")}' in result.output | ||
assert os.path.exists(os.path.join(temp_dir, '.idf_build_apps.toml')) | ||
|
||
# Test init command with specific file path | ||
specific_path = os.path.join(temp_dir, 'custom_build.toml') | ||
result = runner.invoke(cli, ['build-profile', 'init', '--path', specific_path]) | ||
assert result.exit_code == 0 | ||
assert f'Created build profile at {specific_path}' in result.output | ||
assert os.path.exists(specific_path) | ||
|
||
|
||
def test_ci_profile_init(runner, temp_dir): | ||
# Test init command with default path | ||
with runner.isolated_filesystem(): | ||
result = runner.invoke(cli, ['ci-profile', 'init', '--path', temp_dir]) | ||
assert result.exit_code == 0 | ||
assert f'Created CI profile at {os.path.join(temp_dir, ".idf_ci.toml")}' in result.output | ||
assert os.path.exists(os.path.join(temp_dir, '.idf_ci.toml')) | ||
|
||
# Test init command with specific file path | ||
specific_path = os.path.join(temp_dir, 'custom_ci.toml') | ||
result = runner.invoke(cli, ['ci-profile', 'init', '--path', specific_path]) | ||
assert result.exit_code == 0 | ||
assert f'Created CI profile at {specific_path}' in result.output | ||
assert os.path.exists(specific_path) | ||
|
||
|
||
def test_completions(runner): | ||
result = runner.invoke(cli, ['completions']) | ||
assert result.exit_code == 0 | ||
assert 'To enable autocomplete run the following command:' in result.output | ||
assert 'Bash:' in result.output | ||
assert 'Zsh:' in result.output | ||
assert 'Fish:' in result.output | ||
|
||
|
||
def test_profile_init_file_exists(runner, temp_dir): | ||
# Test that init doesn't fail if file already exists | ||
build_profile_path = os.path.join(temp_dir, '.idf_build_apps.toml') | ||
ci_profile_path = os.path.join(temp_dir, '.idf_ci.toml') | ||
|
||
# Create files first | ||
Path(build_profile_path).touch() | ||
Path(ci_profile_path).touch() | ||
|
||
# Try to init again | ||
result = runner.invoke(cli, ['build-profile', 'init', '--path', temp_dir]) | ||
assert result.exit_code == 0 | ||
|
||
result = runner.invoke(cli, ['ci-profile', 'init', '--path', temp_dir]) | ||
assert result.exit_code == 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import os | ||
|
||
import pytest | ||
|
||
from idf_ci.settings import CiSettings | ||
|
||
|
||
@pytest.fixture | ||
def default_settings(): | ||
return CiSettings() | ||
|
||
|
||
def test_default_component_mapping_regexes(default_settings): | ||
expected_regexes = [ | ||
'/components/(.+)/', | ||
'/common_components/(.+)/', | ||
] | ||
assert default_settings.component_mapping_regexes == expected_regexes | ||
|
||
|
||
def test_default_component_ignored_file_extensions(default_settings): | ||
expected_extensions = [ | ||
'.md', | ||
'.rst', | ||
'.yaml', | ||
'.yml', | ||
'.py', | ||
] | ||
assert default_settings.component_ignored_file_extensions == expected_extensions | ||
|
||
|
||
def test_get_modified_components(default_settings): | ||
test_files = [ | ||
'components/wifi/wifi.c', | ||
'components/bt/bt_main.c', | ||
'common_components/esp_common/test.c', | ||
'docs/example.md', # should be ignored | ||
'random/file.txt', # should not match any component | ||
] | ||
|
||
expected_components = {'wifi', 'bt', 'esp_common'} | ||
assert default_settings.get_modified_components(test_files) == expected_components | ||
|
||
|
||
def test_ignored_file_extensions(default_settings): | ||
test_files = [ | ||
'components/wifi/README.md', | ||
'components/bt/docs.rst', | ||
'components/esp_common/config.yaml', | ||
'components/test/test.yml', | ||
'components/utils/util.py', | ||
] | ||
|
||
assert default_settings.get_modified_components(test_files) == set() | ||
|
||
|
||
def test_extended_component_mapping_regexes(): | ||
settings = CiSettings( | ||
extend_component_mapping_regexes=[ | ||
'/custom/path/(.+)/', | ||
] | ||
) | ||
|
||
test_files = [ | ||
'custom/path/my_component/test.c', | ||
'components/wifi/wifi.c', | ||
] | ||
|
||
expected_components = {'my_component', 'wifi'} | ||
assert settings.get_modified_components(test_files) == expected_components | ||
|
||
|
||
def test_extended_ignored_extensions(): | ||
settings = CiSettings( | ||
extend_component_ignored_file_extensions=[ | ||
'.txt', | ||
'.json', | ||
] | ||
) | ||
|
||
test_files = [ | ||
'components/wifi/test.txt', | ||
'components/bt/config.json', | ||
'components/esp_common/main.c', | ||
] | ||
|
||
expected_components = {'esp_common'} | ||
assert settings.get_modified_components(test_files) == expected_components | ||
|
||
|
||
def test_build_profile_default(): | ||
settings = CiSettings() | ||
assert settings.build_profile == 'default' | ||
|
||
|
||
def test_build_profile_custom(): | ||
custom_profile = 'custom_profile' | ||
settings = CiSettings(build_profile=custom_profile) | ||
assert settings.build_profile == custom_profile | ||
|
||
|
||
def test_all_component_mapping_regexes(default_settings): | ||
patterns = default_settings.all_component_mapping_regexes | ||
assert len(patterns) == 2 | ||
|
||
test_path = '/components/test_component/test.c' | ||
for pattern in patterns: | ||
match = pattern.search(test_path) | ||
if '/components/(.+)/' in pattern.pattern: | ||
assert match is not None | ||
assert match.group(1) == 'test_component' | ||
|
||
|
||
def test_component_mapping_with_absolute_paths(default_settings): | ||
abs_path = os.path.abspath('components/wifi/wifi.c') | ||
components = default_settings.get_modified_components([abs_path]) | ||
assert components == {'wifi'} |