diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 6f9ca47fa5..8ff555fbdd 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -23,12 +23,15 @@ body: - bdc_motor - catch2 - cbor + - ccomp_timer - coap - coremark + - dhara - eigen + - esp_delta_ota - esp_encrypted_img - - esp_lcd_qemu_rgb - esp_jpeg + - esp_lcd_qemu_rgb - esp_serial_slave_link - expat - fmt @@ -38,15 +41,20 @@ body: - json_generator - json_parser - led_strip + - libpng - libsodium + - network_provisioning - nghttp - onewire_bus - pcap - pid_ctrl - qrcode + - quirc - sh2lib - - test_app + - spi_nand_flash + - supertinycron - thorvg + - zlib - Other validations: required: true diff --git a/.github/PULL_REQUEST_TEMPLATE/new_component.md b/.github/PULL_REQUEST_TEMPLATE/new_component.md index 4f91a6b668..f66952bb26 100644 --- a/.github/PULL_REQUEST_TEMPLATE/new_component.md +++ b/.github/PULL_REQUEST_TEMPLATE/new_component.md @@ -4,8 +4,8 @@ - [ ] Component contains README.md - [ ] Component contains idf_component.yml file with `url` field defined - [ ] Component was added to [upload job](https://github.com/espressif/idf-extra-components/blob/master/.github/workflows/upload_component.yml#L18) -- [ ] Component was added to [build job](https://github.com/espressif/idf-extra-components/blob/master/test_app/CMakeLists.txt#L8) -- [ ] _Optional:_ Component contains unit tests +- [ ] Component has an example project +- [ ] _Optional:_ Component has a test_app - [ ] CI passing # Change description diff --git a/.github/consistency_check.py b/.github/consistency_check.py new file mode 100644 index 0000000000..2eaecec479 --- /dev/null +++ b/.github/consistency_check.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# This script performs various consistency checks on the repository. +import argparse +import logging +import glob +import os +from pathlib import Path + +import yaml + + +LOG = logging.getLogger("consistency_check") +failures = 0 + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--root", default=".", help="Root directory of the repository") + args = parser.parse_args() + + logging.basicConfig(level=logging.INFO) + + check_build_manifests_added_to_config(args) + check_components_added_to_upload_job(args) + check_components_added_to_issue_template(args) + + if failures: + LOG.error(f"Found {failures} issues") + raise SystemExit(1) + + +#### Checks #### + +def check_build_manifests_added_to_config(args): + LOG.info("Checking that all .build-test-rules.yml files are added to .idf_build_apps.toml") + + build_manifests_from_repo = set(glob.glob(f"{args.root}/**/.build-test-rules.yml", recursive=True)) + # exclude the ones under 'managed_components' + build_manifests_from_repo = set([Path(f) for f in build_manifests_from_repo if "managed_components" not in f]) + + idf_build_apps_toml = load_toml(os.path.join(args.root, ".idf_build_apps.toml")) + build_manifests_from_config = set([Path(f) for f in idf_build_apps_toml.get("manifest_file", [])]) + + missing = build_manifests_from_repo - build_manifests_from_config + if missing: + LOG.error(f"Missing build manifests in .idf_build_apps.toml: {missing}") + add_failure() + + +def check_components_added_to_upload_job(args): + LOG.info("Checking that all components are added to the upload job") + + components_from_repo = set([Path(f).name for f in get_component_dirs(args)]) + + upload_job = load_yaml(os.path.join(args.root, ".github/workflows/upload_component.yml")) + upload_job_steps = upload_job.get("jobs", {}).get("upload_components", {}).get("steps", []) + upload_job_step = next((step for step in upload_job_steps if step.get("name") == "Upload components to component service"), None) + components_from_upload_job = set([name.strip() for name in upload_job_step.get("with", {}).get("directories", "").split(";")]) + + missing = components_from_repo - components_from_upload_job + if missing: + LOG.error(f"Missing components in upload job: {missing}") + add_failure() + + +def check_components_added_to_issue_template(args): + LOG.info("Checking that all components are added to the issue template") + + issue_template = load_yaml(os.path.join(args.root, ".github/ISSUE_TEMPLATE/bug-report.yml")) + issue_template_component = next((element for element in issue_template.get("body", []) if element.get("id") == "component"), None) + components_from_issue_template = set(issue_template_component.get("attributes", {}).get("options", [])) + + components_from_repo = set([Path(component).name for component in get_component_dirs(args)]) + missing = components_from_repo - components_from_issue_template + if missing: + LOG.error(f"Missing components in issue template: {missing}") + add_failure() + extra = components_from_issue_template - components_from_repo - set(["Other"]) + if extra: + LOG.error(f"Extra components in issue template: {extra}") + add_failure() + + +#### Utility functions #### + +def load_toml(filepath) -> dict: + try: + import tomllib # type: ignore # python 3.11 + + try: + with open(str(filepath), 'rb') as fr: + return tomllib.load(fr) + except Exception as e: + raise ValueError(f"Failed to load {filepath}: {e}") + except ImportError: + import toml + + try: + return toml.load(str(filepath)) + except Exception as e: + raise ValueError(f"Failed to load {filepath}: {e}") + + +def load_yaml(filepath) -> dict: + with open(filepath, "r") as f: + return yaml.safe_load(f) + + +def get_component_dirs(args): + """ + Returns a list of component paths in this repository. + """ + components_from_repo = set(glob.glob(f"{args.root}/*/idf_component.yml")) + components_from_repo = [Path(f).parent.name for f in components_from_repo] + return components_from_repo + +def add_failure(): + global failures + failures += 1 + + +if __name__ == "__main__": + main() diff --git a/.github/get_idf_build_apps_args.py b/.github/get_idf_build_apps_args.py new file mode 100644 index 0000000000..4957412a60 --- /dev/null +++ b/.github/get_idf_build_apps_args.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +import argparse +import os + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output') + parser.add_argument('modified_files_list', type=argparse.FileType('r'), help='Input file containing list of modified files') + parser.add_argument('idf_build_apps_args', type=argparse.FileType('w'), help='Output file containing idf-build-apps arguments') + args = parser.parse_args() + + modified_files = args.modified_files_list.read().splitlines() + idf_build_apps_args = [] + idf_build_apps_args += [ + '--modified-files', + ';'.join(modified_files) + ] + + if args.verbose: + print('Modified files:') + for file in sorted(modified_files): + print(f' - {file}') + + modified_components = set() + excluded_dirs = ['.github', 'test_app'] + for file in modified_files: + toplevel = file.split('/')[0] + if toplevel in excluded_dirs: + continue + if not os.path.isdir(toplevel): + continue + modified_components.add(toplevel) + + idf_build_apps_args += [ + '--modified-components', + ';'.join(modified_components) + ] + + args.idf_build_apps_args.write(' '.join(idf_build_apps_args)) + + if args.verbose: + print('Modified components:') + for component in sorted(modified_components): + print(f' - {component}') + + +if __name__ == '__main__': + main() diff --git a/.github/get_pytest_args.py b/.github/get_pytest_args.py new file mode 100644 index 0000000000..89f805cfa2 --- /dev/null +++ b/.github/get_pytest_args.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 + +import argparse +import json +import glob + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output') + parser.add_argument('--target', type=str, required=True, help='Target to run tests for') + parser.add_argument('build_info_json', type=str, help='Input file(s) containing build info generated by idf-build-apps. Accepts globs.') + parser.add_argument('pytest_args', type=argparse.FileType('w'), help='Output file containing pytest arguments') + + args = parser.parse_args() + pytest_args = [] + app_json_files = glob.glob(args.build_info_json) + if args.verbose: + print(f'Found {len(app_json_files)} app_json files') + for app_json_file in app_json_files: + print(f' - {app_json_file}') + for app_json_file in app_json_files: + with open(app_json_file, 'r') as build_info_json: + if args.verbose: + print(f'Processing {app_json_file}') + for app_json_line in build_info_json.readlines(): + app_json = json.loads(app_json_line) + skip = False + if app_json['target'] != args.target: + continue + if app_json['build_status'] == 'skipped': + if args.verbose: + print(f'Skipping {app_json["app_dir"]})') + pytest_args += [ + '--ignore', + app_json['app_dir'] + ] + else: + if args.verbose: + print(f'Not skipping {app_json["app_dir"]})') + + + args.pytest_args.write(' '.join(pytest_args)) + + +if __name__ == '__main__': + main() + diff --git a/.github/workflows/build_and_run_apps.yml b/.github/workflows/build_and_run_apps.yml new file mode 100644 index 0000000000..72e49c2c0c --- /dev/null +++ b/.github/workflows/build_and_run_apps.yml @@ -0,0 +1,147 @@ +name: Build and Run Apps + +on: + schedule: + - cron: '0 0 * * *' # Once per day at midnight + pull_request: + types: [opened, reopened, synchronize] + +jobs: + build: + name: Build Apps + strategy: + fail-fast: false + matrix: + idf_ver: + - "release-v5.0" + - "release-v5.1" + - "release-v5.2" + - "release-v5.3" + - "latest" + parallel_index: [1,2,3,4,5] # Update --parallel-count below when changing this + runs-on: ubuntu-22.04 + container: espressif/idf:${{ matrix.idf_ver }} + steps: + - uses: actions/checkout@v4 + with: + submodules: 'true' + - name: Install dependencies + shell: bash + run: | + . ${IDF_PATH}/export.sh + pip install --upgrade idf-component-manager 'idf-build-apps>=2.4,<2.5' + - name: Fix git repo permissions + # Needed by the next git diff step. + # See https://github.com/actions/runner/issues/2033 + if: github.event_name == 'pull_request' + run: | + build_dir=$PWD + cd / + git config --global --add safe.directory $build_dir + cd - + - name: Find files and component changed in PR + if: github.event_name == 'pull_request' + # For PRs only: + # - find the files changed in the PR + # - based on the files list, determine which components have changed + # - output both lists as a file of idf-build-apps arguments + run: | + git fetch --recurse-submodules=no origin ${{ github.base_ref }}:base_ref + git fetch --recurse-submodules=no origin pull/${{ github.event.pull_request.number }}/head:pr_ref + git diff --name-only -r base_ref pr_ref > changed_files.txt + python3 .github/get_idf_build_apps_args.py -v changed_files.txt idf_build_apps_args.txt + - name: Find apps + shell: bash + run: | + . ${IDF_PATH}/export.sh + idf-build-apps find + - name: Build apps + shell: bash + run: | + . ${IDF_PATH}/export.sh + export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function" + export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes" + export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}" + touch idf_build_apps_args.txt + idf-build-apps build --parallel-index ${{ matrix.parallel_index }} --parallel-count 5 --collect-app-info build_info_${{ matrix.idf_ver }}_${{ matrix.parallel_index }}.json $(cat idf_build_apps_args.txt) + - uses: actions/upload-artifact@v4 + with: + name: app_binaries_${{ matrix.idf_ver }}_${{ matrix.parallel_index }} + path: | + */examples/*/build_esp*/bootloader/bootloader.bin + */examples/*/build_esp*/partition_table/partition-table.bin + */examples/*/build_esp*/*.bin + */examples/*/build_esp*/flasher_args.json + */examples/*/build_esp*/config/sdkconfig.json + */test_apps/**/build_esp*/bootloader/bootloader.bin + */test_apps/**/build_esp*/partition_table/partition-table.bin + */test_apps/**/build_esp*/*.bin + */test_apps/**/build_esp*/flasher_args.json + */test_apps/**/build_esp*/config/sdkconfig.json + build_info*.json + + run-target: + name: Run apps on target + if: ${{ github.repository_owner == 'espressif' }} + needs: build + strategy: + fail-fast: false + matrix: + idf_ver: + - "release-v5.0" + - "release-v5.1" + - "release-v5.2" + - "release-v5.3" + - "latest" + runner: + - runs-on: "esp32" + marker: "generic" + target: "esp32" + - runs-on: "ESP32-ETHERNET-KIT" + marker: "ethernet" + target: "esp32" + env: + TEST_RESULT_NAME: test_results_${{ matrix.runner.target }}_${{ matrix.runner.marker }}_${{ matrix.idf_ver }} + TEST_RESULT_FILE: test_results_${{ matrix.runner.target }}_${{ matrix.runner.marker }}_${{ matrix.idf_ver }}.xml + runs-on: [self-hosted, linux, docker, "${{ matrix.runner.runs-on }}"] + container: + image: python:3.11-bookworm + options: --privileged # Privileged mode has access to serial ports + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + pattern: app_binaries_${{ matrix.idf_ver }}_* + merge-multiple: true + - name: Install Python packages + env: + PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/" + run: pip install --prefer-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf + - name: Run apps + run: | + python3 .github/get_pytest_args.py --target=${{ matrix.runner.target }} -v 'build_info*.json' pytest-args.txt + cat pytest-args.txt + pytest $(cat pytest-args.txt) --ignore-glob '*/managed_components/*' --ignore=test_app --ignore=.github --junit-xml=${{ env.TEST_RESULT_FILE }} --target=${{ matrix.runner.target }} -m ${{ matrix.runner.marker }} --build-dir=build_${{ matrix.runner.target }} + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: ${{ env.TEST_RESULT_NAME }} + path: ${{ env.TEST_RESULT_FILE }} + + publish-results: + name: Publish Test results + needs: + - run-target + if: ${{ always() && github.repository_owner == 'espressif' }} # Run even if the previous step failed + runs-on: ubuntu-22.04 + steps: + - name: Download Test results + uses: actions/download-artifact@v4 + with: + pattern: test_results_* + path: test_results + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 + with: + files: test_results/**/*.xml diff --git a/.github/workflows/build_and_run_examples.yml b/.github/workflows/build_and_run_examples.yml deleted file mode 100644 index 63e2af5474..0000000000 --- a/.github/workflows/build_and_run_examples.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: Build and Run Examples - -on: - schedule: - - cron: '0 0 * * *' # Once per day at midnight - pull_request: - types: [opened, reopened, synchronize] - -jobs: - build: - name: Build Examples - strategy: - fail-fast: false - matrix: - idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "latest"] - parallel_index: [1,2,3,4,5] # This must from 1 to 'parallel_count' defined in .idf_build_apps.toml - runs-on: ubuntu-20.04 - container: espressif/idf:${{ matrix.idf_ver }} - steps: - - uses: actions/checkout@v4 - with: - submodules: 'true' - - name: Build Examples - shell: bash - run: | - . ${IDF_PATH}/export.sh - pip install idf-component-manager idf-build-apps --upgrade - export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function" - export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes" - export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}" - idf-build-apps find --config sdkconfig.ci - idf-build-apps build --ignore-warning-file .ignore_build_warnings.txt --config sdkconfig.ci --parallel-index ${{ matrix.parallel_index }} - - uses: actions/upload-artifact@v4 - with: - name: example_binaries_${{ matrix.idf_ver }}_${{ matrix.parallel_index }} - path: | - */examples/*/build_esp*/bootloader/bootloader.bin - */examples/*/build_esp*/partition_table/partition-table.bin - */examples/*/build_esp*/*.bin - */examples/*/build_esp*/flasher_args.json - */examples/*/build_esp*/config/sdkconfig.json - - run-target: - name: Run examples on target - if: ${{ github.repository_owner == 'espressif' }} - needs: build - strategy: - fail-fast: false - matrix: - idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "latest"] - idf_target: ["esp32"] - runs-on: [self-hosted, linux, docker, "${{ matrix.idf_target }}"] - container: - image: python:3.11-bookworm - options: --privileged # Privileged mode has access to serial ports - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - pattern: example_binaries_${{ matrix.idf_ver }}_* - merge-multiple: true - - name: Install Python packages - env: - PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/" - run: pip install --prefer-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf - - name: Run examples - run: pytest --target=${{ matrix.idf_target }} -m generic --build-dir=build_${{ matrix.idf_target }} --ignore=test_app - - run-ethernet-based-examples: - name: Run examples on ethernet runners - if: ${{ github.repository_owner == 'espressif' }} - needs: build - strategy: - fail-fast: false - matrix: - # Some components that runs Ethernet tests are marked for IDF >= v5.0 only - # Hence, not considering IDF v4.x releases here. If we find a clean way - # to let pytest know about IDF release dependency then we may reintroduce - # the IDF v4.x in the list. - idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "latest"] - idf_target: ["esp32"] - runs-on: [self-hosted, ESP32-ETHERNET-KIT] - container: - image: python:3.11-bookworm - options: --privileged # Privileged mode has access to serial ports - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - pattern: example_binaries_${{ matrix.idf_ver }}_* - merge-multiple: true - - name: Install Python packages - env: - PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/" - run: pip install --only-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf - - name: Run examples - run: pytest --target=${{ matrix.idf_target }} -m ethernet --build-dir=build_${{ matrix.idf_target }} --ignore=test_app diff --git a/.github/workflows/build_and_run_test_app.yml b/.github/workflows/build_and_run_test_app.yml deleted file mode 100644 index efe9a3b87d..0000000000 --- a/.github/workflows/build_and_run_test_app.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: Build and Run Test Application - -on: - schedule: - - cron: '0 0 * * *' # Once per day at midnight - pull_request: - types: [opened, reopened, synchronize] - -jobs: - build: - name: Build Test App - strategy: - fail-fast: false - matrix: - idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "latest"] - idf_target: ["esp32", "esp32c3", "esp32s3"] # @todo ESP32S2 has less RAM and the test_app will not fit - runs-on: ubuntu-20.04 - container: espressif/idf:${{ matrix.idf_ver }} - steps: - - uses: actions/checkout@v1 - with: - submodules: 'true' - - name: Build Test Application - env: - IDF_TARGET: ${{ matrix.idf_target }} - shell: bash - working-directory: test_app - run: | - . ${IDF_PATH}/export.sh - export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function" - export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes" - export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}" - idf.py build - - uses: actions/upload-artifact@v4 - with: - name: test_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }} - path: | - test_app/build/bootloader/bootloader.bin - test_app/build/partition_table/partition-table.bin - test_app/build/idf_extra_test_app.bin - test_app/build/idf_extra_test_app.elf - test_app/build/flasher_args.json - - run-target: - name: Run Test App on target - if: ${{ github.repository_owner == 'espressif' }} - needs: build - strategy: - fail-fast: false - matrix: - idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "latest"] - idf_target: ["esp32", "esp32c3", "esp32s3"] - runs-on: [self-hosted, linux, docker, "${{ matrix.idf_target }}"] - container: - image: python:3.11-bookworm - options: --privileged # Privileged mode has access to serial ports - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - name: test_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }} - path: test_app/build - - name: Install Python packages - env: - PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/" - run: pip install --only-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf - - name: Run Test App on target - working-directory: test_app - run: pytest --junit-xml=./test_app_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}.xml --target=${{ matrix.idf_target }} - - uses: actions/upload-artifact@v4 - if: always() - with: - name: test_app_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }} - path: test_app/*.xml - - publish-results: - name: Publish Test App results - needs: run-target - if: ${{ always() && github.repository_owner == 'espressif' }} # Run even if the previous step failed - runs-on: ubuntu-20.04 - steps: - - name: Download Test results - uses: actions/download-artifact@v4 - with: - path: test_results - - name: Publish Test Results - uses: EnricoMi/publish-unit-test-result-action@v1 - with: - files: test_results/**/*.xml diff --git a/.gitignore b/.gitignore index ab46bd1fbe..78b419ba91 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ dependencies.lock **/managed_components/** .vscode/ doxygen/ +.cache diff --git a/.idf_build_apps.toml b/.idf_build_apps.toml index 3dbbc8131e..7166dbf79f 100644 --- a/.idf_build_apps.toml +++ b/.idf_build_apps.toml @@ -4,9 +4,29 @@ recursive = true exclude = [ "test_app", ] -manifest_file = ".build-test-rules.yml" +manifest_file = [ + "bdc_motor/.build-test-rules.yml", + "ccomp_timer/.build-test-rules.yml", + "coremark/.build-test-rules.yml", + "esp_encrypted_img/.build-test-rules.yml", + "esp_serial_slave_link/.build-test-rules.yml", + "expat/.build-test-rules.yml", + "jsmn/.build-test-rules.yml", + "json_generator/.build-test-rules.yml", + "json_parser/.build-test-rules.yml", + "libpng/.build-test-rules.yml", + "libsodium/.build-test-rules.yml", + "onewire_bus/.build-test-rules.yml", + "pcap/.build-test-rules.yml", + "pid_ctrl/.build-test-rules.yml", + "qrcode/.build-test-rules.yml", + "quirc/.build-test-rules.yml", + "zlib/.build-test-rules.yml", + ".build-test-rules.yml", +] check_warnings = true # build related options build_dir = "build_@t_@w" -parallel_count = 5 +config = "sdkconfig.ci" +ignore_warning_file = ".ignore_build_warnings.txt" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8596f813e4..81750cb7d1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,3 +5,14 @@ repos: - id: astyle_py args: ['--style=otbs', '--attach-namespaces', '--attach-classes', '--indent=spaces=4', '--convert-tabs', '--align-pointer=name', '--align-reference=name', '--keep-one-line-statements', '--pad-header', '--pad-oper'] exclude: 'network_provisioning/proto-c' +- repo: local + hooks: + - id: consistency_check + name: Repo consistency checks + language: python + entry: python .github/consistency_check.py + pass_filenames: false + additional_dependencies: + - "toml; python_version < '3.11'" + - pyyaml + diff --git a/bdc_motor/.build-test-rules.yml b/bdc_motor/.build-test-rules.yml new file mode 100644 index 0000000000..ab01637f92 --- /dev/null +++ b/bdc_motor/.build-test-rules.yml @@ -0,0 +1,4 @@ +bdc_motor/test_apps: + disable: + - if: SOC_MCPWM_SUPPORTED != 1 + reason: Only MCPWM backend is implemented diff --git a/bdc_motor/test_apps/CMakeLists.txt b/bdc_motor/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..b4d0127fc2 --- /dev/null +++ b/bdc_motor/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(bdc_motor_test) diff --git a/bdc_motor/test_apps/main/CMakeLists.txt b/bdc_motor/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..3b5319d92d --- /dev/null +++ b/bdc_motor/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "bdc_motor_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) diff --git a/bdc_motor/test_apps/main/bdc_motor_test.c b/bdc_motor/test_apps/main/bdc_motor_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/bdc_motor/test_apps/main/bdc_motor_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +} diff --git a/bdc_motor/test_apps/main/idf_component.yml b/bdc_motor/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..c135e8d283 --- /dev/null +++ b/bdc_motor/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/bdc_motor: + version: "*" + override_path: "../../" diff --git a/catch2/examples/catch2-console/pytest_catch2_console.py b/catch2/examples/catch2-console/pytest_catch2_console.py index c3c2ca6cbd..f08eb916cc 100644 --- a/catch2/examples/catch2-console/pytest_catch2_console.py +++ b/catch2/examples/catch2-console/pytest_catch2_console.py @@ -5,7 +5,6 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets @pytest.mark.generic def test_catch2_console_example(dut: Dut) -> None: dut.expect_exact('Type \'help\' to get the list of commands.') diff --git a/catch2/examples/catch2-test/pytest_catch2.py b/catch2/examples/catch2-test/pytest_catch2.py index 0d0241298a..dabc7ec465 100644 --- a/catch2/examples/catch2-test/pytest_catch2.py +++ b/catch2/examples/catch2-test/pytest_catch2.py @@ -5,7 +5,6 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets @pytest.mark.generic def test_catch2_example(dut: Dut) -> None: dut.expect_exact('All tests passed') diff --git a/cbor/examples/cbor/CMakeLists.txt b/cbor/examples/cbor/CMakeLists.txt index c25688f59f..7ffbcc3ad4 100644 --- a/cbor/examples/cbor/CMakeLists.txt +++ b/cbor/examples/cbor/CMakeLists.txt @@ -3,4 +3,5 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) project(cbor) diff --git a/cbor/examples/cbor/pytest_cbor.py b/cbor/examples/cbor/pytest_cbor.py index 2516396cfe..73fe9a67a2 100644 --- a/cbor/examples/cbor/pytest_cbor.py +++ b/cbor/examples/cbor/pytest_cbor.py @@ -8,7 +8,6 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets @pytest.mark.generic def test_examples_cbor(dut: Dut) -> None: @@ -20,23 +19,23 @@ def test_examples_cbor(dut: Dut) -> None: dut.expect('example: decode CBOR manually') dut.expect(textwrap.dedent(r''' - Array\[\s+ - Map{{\s+ - chip\s+ - {}\s+ - unicore\s+ - {}\s+ - ip\s+ - Array\[\s+ - {}\s+ - {}\s+ - {}\s+ - {}\s+ - \]\s+ - }}\s+ - 3.14\s+ - simple\(99\)\s+ - 2019-07-10 09:00:00\+0000\s+ - undefined\s+ + Array\[\s* + Map{{\s* + chip\s* + {}\s* + unicore\s* + {}\s* + ip\s* + Array\[\s* + {}\s* + {}\s* + {}\s* + {}\s* + \]\s* + }}\s* + 3.14\s* + simple\(99\)\s* + 2019-07-10 09:00:00\+0000\s* + undefined\s* \]'''.format(parsed_info[1].decode(), parsed_info[2].decode(), parsed_info[3].decode(), parsed_info[4].decode(), parsed_info[5].decode(),parsed_info[6].decode())).replace('{', r'\{').replace('}', r'\}')) diff --git a/ccomp_timer/.build-test-rules.yml b/ccomp_timer/.build-test-rules.yml new file mode 100644 index 0000000000..681df61911 --- /dev/null +++ b/ccomp_timer/.build-test-rules.yml @@ -0,0 +1,4 @@ +ccomp_timer/test_apps: + enable: + - if: IDF_TARGET in ["esp32", "esp32s2", "esp32c3"] + reason: "Testing on these targets is sufficient (xtensa, risc-v, single/dual core)." diff --git a/ccomp_timer/test/CMakeLists.txt b/ccomp_timer/test/CMakeLists.txt deleted file mode 100644 index 1983fd5ee7..0000000000 --- a/ccomp_timer/test/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -idf_build_get_property(arch IDF_TARGET_ARCH) - -set(priv_requires esp_timer ccomp_timer unity) -if("${arch}" STREQUAL "xtensa") - list(APPEND priv_requires perfmon) -endif() - -idf_component_register(SRC_DIRS "." - PRIV_INCLUDE_DIRS "." - PRIV_REQUIRES ${priv_requires}) diff --git a/ccomp_timer/test_apps/CMakeLists.txt b/ccomp_timer/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..21428f7306 --- /dev/null +++ b/ccomp_timer/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(ccomp_timer_test) diff --git a/ccomp_timer/test_apps/main/CMakeLists.txt b/ccomp_timer/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..a86cf89f14 --- /dev/null +++ b/ccomp_timer/test_apps/main/CMakeLists.txt @@ -0,0 +1,14 @@ +idf_build_get_property(arch IDF_TARGET_ARCH) + +set(priv_requires esp_timer unity) +if("${arch}" STREQUAL "xtensa") + list(APPEND priv_requires perfmon) +endif() + +idf_component_register(SRCS "ccomp_timer_test.c" + "ccomp_timer_test_api.c" + "ccomp_timer_test_data.c" + "ccomp_timer_test_inst.c" + PRIV_INCLUDE_DIRS "." + PRIV_REQUIRES ${priv_requires} + WHOLE_ARCHIVE) diff --git a/ccomp_timer/test_apps/main/ccomp_timer_test.c b/ccomp_timer/test_apps/main/ccomp_timer_test.c new file mode 100644 index 0000000000..4b8ec7628f --- /dev/null +++ b/ccomp_timer/test_apps/main/ccomp_timer_test.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" +#include "esp_newlib.h" +#include "unity_test_utils_memory.h" + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(50); +} + +void app_main(void) +{ + printf("Running ccomp_timer component tests\n"); + unity_run_menu(); +} diff --git a/ccomp_timer/test/ccomp_timer_test_api.c b/ccomp_timer/test_apps/main/ccomp_timer_test_api.c similarity index 100% rename from ccomp_timer/test/ccomp_timer_test_api.c rename to ccomp_timer/test_apps/main/ccomp_timer_test_api.c diff --git a/ccomp_timer/test/ccomp_timer_test_data.c b/ccomp_timer/test_apps/main/ccomp_timer_test_data.c similarity index 100% rename from ccomp_timer/test/ccomp_timer_test_data.c rename to ccomp_timer/test_apps/main/ccomp_timer_test_data.c diff --git a/ccomp_timer/test/ccomp_timer_test_inst.c b/ccomp_timer/test_apps/main/ccomp_timer_test_inst.c similarity index 100% rename from ccomp_timer/test/ccomp_timer_test_inst.c rename to ccomp_timer/test_apps/main/ccomp_timer_test_inst.c diff --git a/ccomp_timer/test_apps/main/idf_component.yml b/ccomp_timer/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..5d787ab316 --- /dev/null +++ b/ccomp_timer/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/ccomp_timer: + version: "*" + override_path: ../../ diff --git a/ccomp_timer/test_apps/pytest_ccomp_timer.py b/ccomp_timer/test_apps/pytest_ccomp_timer.py new file mode 100644 index 0000000000..67244b1968 --- /dev/null +++ b/ccomp_timer/test_apps/pytest_ccomp_timer.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.mark.generic +def test_ccomp_timer(dut) -> None: + dut.run_all_single_board_cases() diff --git a/ccomp_timer/test_apps/sdkconfig.defaults b/ccomp_timer/test_apps/sdkconfig.defaults new file mode 100644 index 0000000000..ef5e06c6b0 --- /dev/null +++ b/ccomp_timer/test_apps/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_ESP_TASK_WDT_INIT=n diff --git a/coap/examples/coap_client/CMakeLists.txt b/coap/examples/coap_client/CMakeLists.txt index 0d90604b74..1c77e0b08e 100644 --- a/coap/examples/coap_client/CMakeLists.txt +++ b/coap/examples/coap_client/CMakeLists.txt @@ -2,9 +2,6 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) -# (Not part of the boilerplate) -# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) - include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main esp_eth) project(coap_client) diff --git a/coap/examples/coap_client/main/idf_component.yml b/coap/examples/coap_client/main/idf_component.yml index 352e7134f0..52eaa68a6b 100644 --- a/coap/examples/coap_client/main/idf_component.yml +++ b/coap/examples/coap_client/main/idf_component.yml @@ -4,3 +4,5 @@ dependencies: espressif/coap: version: "^4.3.0" override_path: '../../../' + protocol_examples_common: + path: ${IDF_PATH}/examples/common_components/protocol_examples_common diff --git a/coap/examples/coap_client/pytest_coap_client_example.py b/coap/examples/coap_client/pytest_coap_client_example.py index 6e70feb74c..e9f92e6f3e 100644 --- a/coap/examples/coap_client/pytest_coap_client_example.py +++ b/coap/examples/coap_client/pytest_coap_client_example.py @@ -5,7 +5,6 @@ from pytest_embedded import Dut -@pytest.mark.esp32 @pytest.mark.ethernet def test_coap_example(dut: Dut) -> None: dut.expect('Loaded app from partition at offset', timeout=30) diff --git a/coap/examples/coap_server/CMakeLists.txt b/coap/examples/coap_server/CMakeLists.txt index 32186b0906..9f4c39a63a 100644 --- a/coap/examples/coap_server/CMakeLists.txt +++ b/coap/examples/coap_server/CMakeLists.txt @@ -2,9 +2,6 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) -# (Not part of the boilerplate) -# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) - include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main esp_eth) project(coap_server) diff --git a/coap/examples/coap_server/main/idf_component.yml b/coap/examples/coap_server/main/idf_component.yml index 32b2b02bd7..f2a1604629 100644 --- a/coap/examples/coap_server/main/idf_component.yml +++ b/coap/examples/coap_server/main/idf_component.yml @@ -4,3 +4,5 @@ dependencies: espressif/coap: version: "^4.3.0" override_path: '../../../' + protocol_examples_common: + path: ${IDF_PATH}/examples/common_components/protocol_examples_common diff --git a/coremark/.build-test-rules.yml b/coremark/.build-test-rules.yml new file mode 100644 index 0000000000..fe9bf75136 --- /dev/null +++ b/coremark/.build-test-rules.yml @@ -0,0 +1,4 @@ +coremark/examples: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3"] + reason: "Sufficient to test on one Xtensa and one RISC-V target." diff --git a/coremark/examples/coremark_example/pytest_coremark.py b/coremark/examples/coremark_example/pytest_coremark.py new file mode 100644 index 0000000000..722b1e3a12 --- /dev/null +++ b/coremark/examples/coremark_example/pytest_coremark.py @@ -0,0 +1,7 @@ +import pytest + + +@pytest.mark.generic +def test_coremark(dut): + dut.expect_exact("Running coremark...") + dut.expect_exact("Correct operation validated", timeout=30) diff --git a/coremark/examples/coremark_example/sdkconfig.defaults.esp32 b/coremark/examples/coremark_example/sdkconfig.defaults.esp32 index 53ddd0870c..7382da578e 100644 --- a/coremark/examples/coremark_example/sdkconfig.defaults.esp32 +++ b/coremark/examples/coremark_example/sdkconfig.defaults.esp32 @@ -1,3 +1 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y -# for IDF v4.4.x compatibility -CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y diff --git a/coremark/examples/coremark_example/sdkconfig.defaults.esp32s2 b/coremark/examples/coremark_example/sdkconfig.defaults.esp32s2 index f21989ebb5..7382da578e 100644 --- a/coremark/examples/coremark_example/sdkconfig.defaults.esp32s2 +++ b/coremark/examples/coremark_example/sdkconfig.defaults.esp32s2 @@ -1,3 +1 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y -# for IDF v4.4.x compatibility -CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240=y diff --git a/coremark/examples/coremark_example/sdkconfig.defaults.esp32s3 b/coremark/examples/coremark_example/sdkconfig.defaults.esp32s3 index 3ac48bd812..7382da578e 100644 --- a/coremark/examples/coremark_example/sdkconfig.defaults.esp32s3 +++ b/coremark/examples/coremark_example/sdkconfig.defaults.esp32s3 @@ -1,3 +1 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y -# for IDF v4.4.x compatibility -CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y diff --git a/eigen/examples/svd/CMakeLists.txt b/eigen/examples/svd/CMakeLists.txt index f97875ea62..ef1aef576c 100644 --- a/eigen/examples/svd/CMakeLists.txt +++ b/eigen/examples/svd/CMakeLists.txt @@ -2,5 +2,6 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) project(Eigen_SVD) diff --git a/esp_delta_ota/examples/https_delta_ota/CMakeLists.txt b/esp_delta_ota/examples/https_delta_ota/CMakeLists.txt index f36eff783c..b7d8384e3f 100644 --- a/esp_delta_ota/examples/https_delta_ota/CMakeLists.txt +++ b/esp_delta_ota/examples/https_delta_ota/CMakeLists.txt @@ -1,7 +1,7 @@ # The following lines of boilerplate have to be in your project's CMakeLists # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) project(https_delta_ota) diff --git a/esp_delta_ota/examples/https_delta_ota/main/CMakeLists.txt b/esp_delta_ota/examples/https_delta_ota/main/CMakeLists.txt index 13c9bd5af3..537ed5ccb2 100644 --- a/esp_delta_ota/examples/https_delta_ota/main/CMakeLists.txt +++ b/esp_delta_ota/examples/https_delta_ota/main/CMakeLists.txt @@ -1,3 +1,4 @@ idf_component_register(SRCS "main.c" INCLUDE_DIRS "." - EMBED_TXTFILES ca_cert.pem) + EMBED_TXTFILES ca_cert.pem + PRIV_REQUIRES esp_http_client esp_partition nvs_flash app_update esp_timer esp_wifi console) diff --git a/esp_delta_ota/examples/https_delta_ota/main/idf_component.yml b/esp_delta_ota/examples/https_delta_ota/main/idf_component.yml index 1100ef1d35..9d6c96525f 100644 --- a/esp_delta_ota/examples/https_delta_ota/main/idf_component.yml +++ b/esp_delta_ota/examples/https_delta_ota/main/idf_component.yml @@ -5,3 +5,5 @@ dependencies: espressif/esp_delta_ota: version: '1.*' override_path: '../../../' + protocol_examples_common: + path: ${IDF_PATH}/examples/common_components/protocol_examples_common diff --git a/esp_encrypted_img/.build-test-rules.yml b/esp_encrypted_img/.build-test-rules.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esp_encrypted_img/test/CMakeLists.txt b/esp_encrypted_img/test/CMakeLists.txt deleted file mode 100644 index 58df9d67ea..0000000000 --- a/esp_encrypted_img/test/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -idf_component_register(SRC_DIRS "." - PRIV_INCLUDE_DIRS "." - REQUIRES unity - PRIV_REQUIRES cmock esp_encrypted_img - EMBED_TXTFILES certs/test_rsa_private_key.pem - EMBED_FILES image.bin) diff --git a/esp_encrypted_img/test_apps/CMakeLists.txt b/esp_encrypted_img/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..8d5d7c5911 --- /dev/null +++ b/esp_encrypted_img/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(esp_encrypted_img_test) diff --git a/esp_encrypted_img/test_apps/main/CMakeLists.txt b/esp_encrypted_img/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..fe1845240c --- /dev/null +++ b/esp_encrypted_img/test_apps/main/CMakeLists.txt @@ -0,0 +1,6 @@ +idf_component_register(SRCS "esp_encrypted_img_test.c" "test.c" + PRIV_INCLUDE_DIRS "." + PRIV_REQUIRES unity + EMBED_TXTFILES certs/test_rsa_private_key.pem + EMBED_FILES image.bin + WHOLE_ARCHIVE) diff --git a/esp_encrypted_img/test/certs/test_rsa_private_key.pem b/esp_encrypted_img/test_apps/main/certs/test_rsa_private_key.pem similarity index 100% rename from esp_encrypted_img/test/certs/test_rsa_private_key.pem rename to esp_encrypted_img/test_apps/main/certs/test_rsa_private_key.pem diff --git a/esp_encrypted_img/test_apps/main/esp_encrypted_img_test.c b/esp_encrypted_img/test_apps/main/esp_encrypted_img_test.c new file mode 100644 index 0000000000..5c3bbcd581 --- /dev/null +++ b/esp_encrypted_img/test_apps/main/esp_encrypted_img_test.c @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" +#include "esp_newlib.h" + +#include "unity_test_utils_memory.h" + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(200); +} + +void app_main(void) +{ + printf("Running esp_encrypted_img component tests\n"); + unity_run_menu(); +} diff --git a/esp_encrypted_img/test_apps/main/idf_component.yml b/esp_encrypted_img/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..7913337845 --- /dev/null +++ b/esp_encrypted_img/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/esp_encrypted_img: + version: "*" + override_path: "../.." diff --git a/esp_encrypted_img/test/image.bin b/esp_encrypted_img/test_apps/main/image.bin similarity index 100% rename from esp_encrypted_img/test/image.bin rename to esp_encrypted_img/test_apps/main/image.bin diff --git a/esp_encrypted_img/test/test.c b/esp_encrypted_img/test_apps/main/test.c similarity index 100% rename from esp_encrypted_img/test/test.c rename to esp_encrypted_img/test_apps/main/test.c diff --git a/esp_encrypted_img/test_apps/pytest_esp_encrypted_img.py b/esp_encrypted_img/test_apps/pytest_esp_encrypted_img.py new file mode 100644 index 0000000000..4d84ddd5fc --- /dev/null +++ b/esp_encrypted_img/test_apps/pytest_esp_encrypted_img.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.mark.generic +def test_esp_encrypted_img(dut) -> None: + dut.run_all_single_board_cases() diff --git a/esp_encrypted_img/test_apps/sdkconfig.defaults b/esp_encrypted_img/test_apps/sdkconfig.defaults new file mode 100644 index 0000000000..ef5e06c6b0 --- /dev/null +++ b/esp_encrypted_img/test_apps/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_ESP_TASK_WDT_INIT=n diff --git a/esp_jpeg/examples/get_started/CMakeLists.txt b/esp_jpeg/examples/get_started/CMakeLists.txt index 0355a698b5..0f3677cf00 100644 --- a/esp_jpeg/examples/get_started/CMakeLists.txt +++ b/esp_jpeg/examples/get_started/CMakeLists.txt @@ -3,4 +3,5 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) project(lcd_tjpgd) diff --git a/esp_jpeg/examples/get_started/main/CMakeLists.txt b/esp_jpeg/examples/get_started/main/CMakeLists.txt index 8abed53131..4dd03e9a4e 100644 --- a/esp_jpeg/examples/get_started/main/CMakeLists.txt +++ b/esp_jpeg/examples/get_started/main/CMakeLists.txt @@ -5,4 +5,5 @@ set(srcs "pretty_effect.c" idf_component_register(SRCS ${srcs} INCLUDE_DIRS "." - EMBED_FILES image.jpg) + EMBED_FILES image.jpg + PRIV_REQUIRES esp_lcd) diff --git a/esp_lcd_qemu_rgb/examples/lcd_qemu_rgb_panel/CMakeLists.txt b/esp_lcd_qemu_rgb/examples/lcd_qemu_rgb_panel/CMakeLists.txt index 5962c7b200..d549504818 100644 --- a/esp_lcd_qemu_rgb/examples/lcd_qemu_rgb_panel/CMakeLists.txt +++ b/esp_lcd_qemu_rgb/examples/lcd_qemu_rgb_panel/CMakeLists.txt @@ -5,4 +5,5 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) project(lcd_qemu_rgb_panel) diff --git a/esp_serial_slave_link/.build-test-rules.yml b/esp_serial_slave_link/.build-test-rules.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esp_serial_slave_link/test_apps/CMakeLists.txt b/esp_serial_slave_link/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..39ed931782 --- /dev/null +++ b/esp_serial_slave_link/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(essl_test) diff --git a/esp_serial_slave_link/test_apps/main/CMakeLists.txt b/esp_serial_slave_link/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..58dc64a4cd --- /dev/null +++ b/esp_serial_slave_link/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "essl_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) diff --git a/esp_serial_slave_link/test_apps/main/essl_test.c b/esp_serial_slave_link/test_apps/main/essl_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/esp_serial_slave_link/test_apps/main/essl_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +} diff --git a/esp_serial_slave_link/test_apps/main/idf_component.yml b/esp_serial_slave_link/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..979aed8623 --- /dev/null +++ b/esp_serial_slave_link/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/esp_serial_slave_link: + version: "*" + override_path: "../.." diff --git a/expat/.build-test-rules.yml b/expat/.build-test-rules.yml new file mode 100644 index 0000000000..c07bfc88e1 --- /dev/null +++ b/expat/.build-test-rules.yml @@ -0,0 +1,4 @@ +expat/test_apps: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3"] + reason: "Sufficient to test on one Xtensa and one RISC-V target" diff --git a/expat/test/CMakeLists.txt b/expat/test/CMakeLists.txt deleted file mode 100644 index d60400be37..0000000000 --- a/expat/test/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRC_DIRS "." - PRIV_INCLUDE_DIRS "." - PRIV_REQUIRES cmock expat) diff --git a/expat/test_apps/CMakeLists.txt b/expat/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..4aad97fc63 --- /dev/null +++ b/expat/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(expat_test) diff --git a/expat/test_apps/main/CMakeLists.txt b/expat/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..b5da137e5e --- /dev/null +++ b/expat/test_apps/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "test_expat.c" "test_main.c" + PRIV_INCLUDE_DIRS "." + PRIV_REQUIRES unity + WHOLE_ARCHIVE) diff --git a/expat/test_apps/main/idf_component.yml b/expat/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..40a54a77f2 --- /dev/null +++ b/expat/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/expat: + version: "*" + override_path: "../.." diff --git a/expat/test/test_expat.c b/expat/test_apps/main/test_expat.c similarity index 100% rename from expat/test/test_expat.c rename to expat/test_apps/main/test_expat.c diff --git a/expat/test_apps/main/test_main.c b/expat/test_apps/main/test_main.c new file mode 100644 index 0000000000..6c9976e565 --- /dev/null +++ b/expat/test_apps/main/test_main.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" +#include "esp_newlib.h" +#include "unity_test_utils_memory.h" + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(0); +} + +void app_main(void) +{ + printf("Running expat component tests\n"); + unity_run_menu(); +} diff --git a/expat/test_apps/pytest_expat.py b/expat/test_apps/pytest_expat.py new file mode 100644 index 0000000000..c7152ea51f --- /dev/null +++ b/expat/test_apps/pytest_expat.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.mark.generic +def test_expat(dut) -> None: + dut.run_all_single_board_cases() diff --git a/expat/test_apps/sdkconfig.defaults b/expat/test_apps/sdkconfig.defaults new file mode 100644 index 0000000000..ef5e06c6b0 --- /dev/null +++ b/expat/test_apps/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_ESP_TASK_WDT_INIT=n diff --git a/fmt/examples/hello_fmt/pytest_fmt.py b/fmt/examples/hello_fmt/pytest_fmt.py index c422944366..484ae175b0 100644 --- a/fmt/examples/hello_fmt/pytest_fmt.py +++ b/fmt/examples/hello_fmt/pytest_fmt.py @@ -5,7 +5,6 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets @pytest.mark.generic def test_fmt_example(dut: Dut) -> None: dut.expect_exact('Hello, fmt!') diff --git a/freetype/examples/freetype-example/pytest_freetype.py b/freetype/examples/freetype-example/pytest_freetype.py index d0c0170b57..959af33322 100644 --- a/freetype/examples/freetype-example/pytest_freetype.py +++ b/freetype/examples/freetype-example/pytest_freetype.py @@ -8,7 +8,6 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets @pytest.mark.generic def test_freetype_example(dut: Dut) -> None: dut.expect_exact('FreeType library initialized') diff --git a/iqmath/examples/get_started/CMakeLists.txt b/iqmath/examples/get_started/CMakeLists.txt index 8cc9a37c52..21a8db91c2 100644 --- a/iqmath/examples/get_started/CMakeLists.txt +++ b/iqmath/examples/get_started/CMakeLists.txt @@ -5,4 +5,5 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) project(iqmath_get_started) diff --git a/jsmn/.build-test-rules.yml b/jsmn/.build-test-rules.yml new file mode 100644 index 0000000000..8dbdaa46fd --- /dev/null +++ b/jsmn/.build-test-rules.yml @@ -0,0 +1,4 @@ +jsmn/test_apps: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3"] + reason: "Sufficient to test on one Xtensa and one RISC-V target" diff --git a/jsmn/test_apps/CMakeLists.txt b/jsmn/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..c9b32825db --- /dev/null +++ b/jsmn/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(jsmn_test) diff --git a/jsmn/test_apps/main/CMakeLists.txt b/jsmn/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..b432d2b0d4 --- /dev/null +++ b/jsmn/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "jsmn_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) diff --git a/jsmn/test_apps/main/idf_component.yml b/jsmn/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..22f0c97d26 --- /dev/null +++ b/jsmn/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/jsmn: + version: "*" + override_path: "../.." diff --git a/jsmn/test_apps/main/jsmn_test.c b/jsmn/test_apps/main/jsmn_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/jsmn/test_apps/main/jsmn_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +} diff --git a/json_generator/.build-test-rules.yml b/json_generator/.build-test-rules.yml new file mode 100644 index 0000000000..e25226f454 --- /dev/null +++ b/json_generator/.build-test-rules.yml @@ -0,0 +1,4 @@ +json_generator/test_apps: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3"] + reason: "Sufficient to test on one Xtensa and one RISC-V target" diff --git a/json_generator/test_apps/CMakeLists.txt b/json_generator/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..cd5cb85487 --- /dev/null +++ b/json_generator/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(json_generator_test) diff --git a/json_generator/test_apps/main/CMakeLists.txt b/json_generator/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..eb19d03f82 --- /dev/null +++ b/json_generator/test_apps/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "json_generator_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) + diff --git a/json_generator/test_apps/main/idf_component.yml b/json_generator/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..9a5d85b844 --- /dev/null +++ b/json_generator/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/json_generator: + version: "*" + override_path: "../.." diff --git a/json_generator/test_apps/main/json_generator_test.c b/json_generator/test_apps/main/json_generator_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/json_generator/test_apps/main/json_generator_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +} diff --git a/json_parser/.build-test-rules.yml b/json_parser/.build-test-rules.yml new file mode 100644 index 0000000000..f99704fadd --- /dev/null +++ b/json_parser/.build-test-rules.yml @@ -0,0 +1,4 @@ +json_parser/test_apps: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3"] + reason: "Sufficient to test on one Xtensa and one RISC-V target" diff --git a/json_parser/test/CMakeLists.txt b/json_parser/test/CMakeLists.txt deleted file mode 100644 index 7d79f100f1..0000000000 --- a/json_parser/test/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS test_json_parser.c - PRIV_REQUIRES json_parser unity) diff --git a/json_parser/test_apps/CMakeLists.txt b/json_parser/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..1eb9b2ef1d --- /dev/null +++ b/json_parser/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(json_parser_test) diff --git a/json_parser/test_apps/main/CMakeLists.txt b/json_parser/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..27f65d6a51 --- /dev/null +++ b/json_parser/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS test_main.c test_json_parser.c + PRIV_REQUIRES unity + WHOLE_ARCHIVE) diff --git a/json_parser/test_apps/main/idf_component.yml b/json_parser/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..ce8d1dd36b --- /dev/null +++ b/json_parser/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/json_parser: + version: "*" + override_path: "../.." diff --git a/json_parser/test/test_json_parser.c b/json_parser/test_apps/main/test_json_parser.c similarity index 100% rename from json_parser/test/test_json_parser.c rename to json_parser/test_apps/main/test_json_parser.c diff --git a/json_parser/test_apps/main/test_main.c b/json_parser/test_apps/main/test_main.c new file mode 100644 index 0000000000..c8646a32f4 --- /dev/null +++ b/json_parser/test_apps/main/test_main.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" +#include "esp_newlib.h" +#include "unity_test_utils_memory.h" + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(0); +} + +void app_main(void) +{ + printf("Running json_parser component tests\n"); + unity_run_menu(); +} diff --git a/json_parser/test_apps/pytest_json_parser.py b/json_parser/test_apps/pytest_json_parser.py new file mode 100644 index 0000000000..7b79befacc --- /dev/null +++ b/json_parser/test_apps/pytest_json_parser.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.mark.generic +def test_json_parser(dut) -> None: + dut.run_all_single_board_cases() diff --git a/json_parser/test_apps/sdkconfig.defaults b/json_parser/test_apps/sdkconfig.defaults new file mode 100644 index 0000000000..ef5e06c6b0 --- /dev/null +++ b/json_parser/test_apps/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_ESP_TASK_WDT_INIT=n diff --git a/libpng/.build-test-rules.yml b/libpng/.build-test-rules.yml new file mode 100644 index 0000000000..ccb801289b --- /dev/null +++ b/libpng/.build-test-rules.yml @@ -0,0 +1,4 @@ +libpng/test_apps: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3"] + reason: "Sufficient to test on one Xtensa and one RISC-V target" diff --git a/libpng/test_apps/CMakeLists.txt b/libpng/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..d7a7b861ae --- /dev/null +++ b/libpng/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(libpng_test) diff --git a/libpng/test_apps/main/CMakeLists.txt b/libpng/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..315da9c9ac --- /dev/null +++ b/libpng/test_apps/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS test_libpng.c test_main.c + PRIV_REQUIRES unity + WHOLE_ARCHIVE + EMBED_FILES "in.png" "out.pgm") diff --git a/libpng/test_apps/main/idf_component.yml b/libpng/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..0a2e6ac3be --- /dev/null +++ b/libpng/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/libpng: + version: "*" + override_path: "../.." diff --git a/libpng/test_apps/main/in.png b/libpng/test_apps/main/in.png new file mode 100644 index 0000000000..1d12985898 Binary files /dev/null and b/libpng/test_apps/main/in.png differ diff --git a/libpng/test_apps/main/out.pgm b/libpng/test_apps/main/out.pgm new file mode 100644 index 0000000000..993e63fc6d --- /dev/null +++ b/libpng/test_apps/main/out.pgm @@ -0,0 +1,4 @@ +P5 +522 52 +255 +وووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووآ¶¶×ووو঒رووووغ¶¶آووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو_YYآوووگYYbهووو¨YY|وووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووومââهوووووووووووووووووووووووووووووووووووووووووââمووووووووووووووووووووضYYYلوووkYYYزووو†YYœووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووàحوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووàحووووووووووووووووووووووووووووووووووووووووووووووووووو„YY¤ووووووووووووووووووووووووووووووووووووووووشYY]وووووووووووووووووووو´YYiوووو،YYkووووiYY¾ووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووصZZŒوووح_Z„ووووgZpووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووٹZkوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووونjZگوووووووووووووووووووووووووووووووووووووووووح_Z„ووووووووووووووووووووووووووووووووووووووووووووووووووgYY¼وووووووووووووووووووووووووووووووووووووووو²YYnوووووووووووووووووووو‘YYˆوووووئ¸موووàYYYكوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو´ZZ‍وووڑZZZâووعZZپوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووصZZ¤وووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو±ZZةوووووووووووووووووووووووووووووووووووووووووڑZZZâووووووووووووووووووووووووووووووووووووووووووووووووàYYYـوووووووووووووووووووووووووووووووووووووووو‘YYچووووووووووووووووووووrYYھوووووووووووہYYfووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو“ZZہوووإZZzووو؛ZZ،وووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووچZbلووهc_tووووووووووووووووووووووووووووووووووووو§__¸ووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووهjZ|ووووووووووووووووووووووووووووووووووووووووووإZZzوووووووووووووووووووووووووووووووووووووووووووووووووآYYcووووووووووووàووووووووووووووومâوووووووووووsYY¯وووووووووووووووووووهZYYثووووووووووو‍YYƒووونàوووووووووووووووووملووووووووووووووووهكووووووووووووووومâووووووووووووووووووووووووووممووووووووووووووووووووووووuZZكووووس¾مووو™ZZہوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو×ZZ ووودZZ‡وووووووووووووووووووووووووووووووووووووƒZZسوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو¶ZZئوووووووووووووووووووووووووووووووووووووووووووس¾مووووووووووووووووووووووووووووووووووووووووووووووةkkbYYYkkkبووووظ‌|bY_§موووووووو؛…iYYf´ووووو‹kkYYYbkkٹووووووووووووووووحYYZهووو´kk،وووو|YY¤ظ‘rYY]†سووووووو‡knظز‘nYY]چظووووووغkkƒو¬iYYcˆئوووووووووہچkYY_گ×واkk—ووووووووووووووه²s_YYj‡ئوووووووووووووووووووونZZjوووووووووووzZZكووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووگZ_àووو°ZZ§وووووووووووووووووووووووووووووووووووووgZbوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووmZzووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو¤YYYYYYYYYدوووہ]YYYYYYY{موووووه“YYYYYYYYٹâووو]YYYYYYYY€ووووووووووووووووھYYrووووˆYYœووووbYY¨bYYYYYYbصوووووهZYY¶ZYYYYYYgغووووو؛YYwڈYYYYYYZؤووووووه–YYYYYYY]ا YYگوووووووووووووزgYYYYYYYYںهووووووووووووووووووثZZ‡ووووضضàوووه_Zjووغ؛ہâووووووووظضàووà¾؛àووووووووـضـووâ¾¼àوووووووووووـ¼¶حوووغضفوووووووعZZ›ومضضŒZZ¶ضضنووووووص¶آâوووووووووووص¶؛×ووووووـضدZZpضضـووووووووووووووووووـآ²تمووووووونضضمووظ·أمووووووووظضàووà¾؛àوووووووووونح²آقووووووووووو؛ZZآوومضضمونأµثوووووص¸¼كووووووووووـآ²تمووووووووضضàوووو×ضàووـ¶ؤموووووووووووووووووووووووووووووووووو‍nnYYYjnntووو YYYYbsZYYYzمووووˆYYYfƒƒfYYYڈووـnn_YY]nnn¯وووووووووووووووو‰YY‘ووووiYYہوووظYYYYYY_r]YYYfغووووثYYYYYYbr]YYYkàوووو—YYYYY_r_YYYZغووووâvYYYYcr]YYb|YY²ووووووووووووا]YYYYnkYYYYœووووووووووووووووووھZZ¨وووصZZٹووورZZ‡آgZZZZ~غووووونZZحpZZZZvدووووووpZeصzZZZZzفووووووو¯iZZZZpتوiZnووووووو–Z_فو¾ZZZZZZZZ¶وووàٹbZZZZwصووووووه›_ZZZZb²ووووtZZZZZZZkووووووووووووووووہiZZZZZ}غوووووئZZ¥¶gZZZ_ƒàووووونZZحpZZZZvدووووووكƒZZZZZmتوووووووووpZuووو؛ZZ­œbZZZvقوةpZZZZ‡مووووووہiZZZZZ}غوووووصZZٹوووàZZ‡¾pZZZ_گهووووووووووووووووووووووووووووووووووظYYYâوووووتYYYiدوونڑYYYھوووظYYY‍هووه YYZàووووٹYY–ووووووووووووووووووووjYY´ووولYYYàووو¶YYYYtدووه‌YYY—ووووھYYYY|شووم”YYY¤ووووwYYYfحووم“YYY²وووو‌YYY~غووهœYYYYYصوووووووووووàbYYYھâووزrYY]âوووووووووووووووووٹZZبووو´ZZ§ووو¯ZZmZZZZZZZpàووووثZZk_ZZZZZZcصوووومZZkeZZZZZZpàوووومڈZZZZZZZ_ہZZٹووووووـ_Z—ووںZZZZZZZZسووحiZZZZZZZgصووووâ|ZZZZZZZZ”وونZZZZZZZZ‡ووووووووووووووو—ZZZZZZZZcزوووو¤ZZvZZZZZZZzمووووثZZk_ZZZZZZcصووووزgZZZZZZZZ¶ووووووو¾ZZ¾وووڑZZZZZZZZ‡أZZZZZZZ„ووووو—ZZZZZZZZcزوووو´ZZ§وووآZZzZZZZZZZگوووووووووووووووووووووووووووووووووو·YYkووووووuYYnفووووو€YYrوووہYY_ووووووƒkk¾ووووjYY¸وووووووووووووووووووâYYYصوووءYYgوووو”YYY†مووووو†YYsووووˆYYYگهووووو{YYوووو]YYiغووووهkYY‹وووغZYY“وووووو‘YYY_ووووووووووووچYYZآوووووà_YYھوووووووووووووووووkZZمووو”ZZاوووگZZZZ‘؛ث¨_ZZ†ووووھZZZZ†²ح´gZZmوووواZZZZ—ہتڑZZZ±ووووچZZZ•¼ث­bZbZZھوووووو™ZZغووضة­ZZ„ةةةوو×_ZZt¯خ¶vZZjوووو¶ZZj¾كظ­_ZZصونةةpZZآةةطووووووووووووووثZZ_‌تئ‍iZZڑوووو„ZZZZ–¼ت¤_ZZ‘ووووھZZZZ†²ح´gZZmووووگZZ}تâس–ZZgهووووووuZpوووو{ZZZ؛؛پZZZ_Zٹ¾µwZZZàوووثZZ_‌تئ‍iZZڑوووو”ZZاووو،ZZZe£اؤƒZZZ×ووووووووووووووووووووووووووووووووو”YYٹووووو»YYYحووووووµYY]وووہYYYسووووووووووووâYYYغوووووووووووووووووووآYY_ووووںYY…ووووtYYfهووووووتYYZنوووiYYnووووووو¾YY_وووزYYY¹ووووووڈYY€وووڈYYbمووووووكYYY{وووووووووووàYYYœوووووووھ††¶ووووووووووووووووàZZsووووuZZموووpZZ_آووووحZZbووووٹZZZ­ووووـbZZ×ووو§ZZ_آوووو„ZZٹوووخZZ_آووووظ_ZZZثوووووق_Z”ووووو§ZZ¯وووووٹZZâوووàmZZصووو‡ZZسوووو¶ZZ،ووووbZgوووووووووووووووووو‡bb¶ووووصZZpووووgZZbبووووأZZiووووٹZZZ­ووووـbZZ×وووeZeهووووگZZئوووووآZZ؛ووووbZZ–ووووpZZZ£ووومbZZ¼ووو‡bb¶ووووصZZpووووuZZموووپZZjضووونcZZ±وووووووووووووووووووووووووووووووووtYY¬وووووˆYYnغغغغغغغاYYYنووظYYYZ‍كووووووووووآYYbوووووووووووووووووووو YY{وووو~YY§وووهZYY²ووووووولYYYزوولYYYہوووووووشYYYكوو°YYbهووووووڈYYڈوووfYY­ووووووووbYYœووووووووووو­YY]àوووووووووووووووووووووووووووآZZگووونZZpووومZZZ¾ووووووZZخوووkZZ£ووووووڑZZ´ووو†ZZ ووووو¼ZZwووو~ZZھووووووںZZZنوووووœZZطووووو‡ZZدووووحZZcمووووو¨ZZ¯وووvZZبوووووووووووسZZƒوووووووووووووووووووووووووووbZgوووـZZZبووووووvZZظوووkZZ£ووووووڑZZ´وونZZbâوووووووووووووwZnووووزZZcموووو،ZZmوووووژZZ¸ووووووووووووbZgووونZZpووووcZZئووووو–ZZœووووووووووووووووووووووووووووووووهZYYخوووووrYYYYYYYYYYYYYYهوووچYYYYYw­مووووووو YY~ووووووووووووووووووووYY›ووووbYYبوووخYYbووووووووغYYYâووآYYjووووووووخYYZوووڈYYڈوووووووsYY¬وونYYYعووووووووbYYہوووووووووووƒYYˆوووووووووووووووووووووووووووو،ZZ±وووثZZگووواZZwووووووو—ZZ´ووàZZcâوووووو´ZZ—وووiZZغووووورZZƒووâZZgموووووو¾ZZvوووووà_ZگووووووiZ_هوووو—ZZ—ــــــ¼ZZڈوووٹZZb§âووووووووو²ZZ¤وووووووووووووووووووووووâغصئZZzووو¼ZZپوووووووژZZ¾ووàZZcâوووووو´ZZ—وووgZZk؛نووووووووووإZZ¶وووو²ZZœوووووœZZ­وووووٹZZحووووووووâغصئZZzوووثZZگووو×ZZnووووووھZZھووووووووووووووووووووووووووووووووخYYZهووووو_YYYYYYYYYYYYYZووووه–YYYYYY]±وووووو~YY ووووووووووووووووووووbYY¾وووعYYYنووو¬YYwووووووووؤYYbووو YYƒوووووووو¸YYkوووnYY°ووووووهZYYخوودYYZوووووووومYYYàوووووووووووrYY ووووووووووووووووووووووووووووپZZزوووھZZ°ووو§ZZ¸ووووووو“ZZأووآZZœووووووو¯ZZ§ووفZZwوووووو¶ZZںووحZZچوووووووہZZ•ووووو،ZZصوووووفZZzوووووپZZZZZZZZZZZZچوووز_ZZZZپ¶نوووووو‘ZZأووووووووووووووووووم­ƒiZZZZZZZ™ووو›ZZأوووووووٹZZحووآZZœووووووو¯ZZ§ووو²ZZZZbچبوووووووو|ZkهووووگZZأووووو~ZZصوووووkZZنوووم­ƒiZZZZZZZ™وووھZZ°ووو·ZZœووووووگZZإوووووووووووووووووووووووووووووووو¬YYtوووووàYYY§§§§§§§§§§§±ووووووظڑiYYYYY±وووووbYYآوووووووووووووووووووغYYYكووو·YYnوووو‹YYڈوووووووو­YYvووو~YY›وووووووو YY‚وومYYYسووووووحYYZهوو·YYgووووووووحYYiووووووووووووcYYµووووووووووووووووووووووووووووcZbووووٹZZرووو†ZZزووووووو~ZZغوو،ZZ¶وووووووڑZZہوو¾ZZ—وووووو–ZZہوو¶ZZ¢ووووووو©ZZ¶ووووâbZŒوووووو¾ZZ—وووووkZZZZZZZZZZZZ—ووووخvZZZZZjحوووووsZZâوووووووووووووووووبgZZZZZZZZZZ؛ووو|ZZفوووووووuZZموو،ZZ¶وووووووڑZZہوووو¸gZZZZZ~قوووووبZZ±وووووsZZâوووووbZcوووووàZZuوووبgZZZZZZZZZZ؛وووٹZZرووو—ZZ½ووووووpZZâووووووووووووووووووووووووووووووووٹYY“وووووصYYYصووووووووووووووووووووزٹYYYbووووعYYYلووووووووووووووووووو¸YYfوووو”YYڈووووkYY—ووووووووrYYڈوووbYY¤وووووووهiYYڑوواYY]ووووووو¬YYsووو»YY]وووووووو‹YY‡ووووووووووووbYY§ووووووووووووووووووووووووووو×ZZ{ووووkZ_ووووiZZنووووووهgZ_وووپZZحووووووو~ZZضووœZZ·ووووووwZZàوو،ZZ­وووووووŒZZ×وووو¥ZZسووووووœZZ¸ووووهZZjخخخخخخخخخخـووووووث—iZZZcلووومZZnوووووووووووووووووظbZZk،؛اخصtZZغوووbZbووووووومbZgوووپZZحووووووو~ZZضوووووه½ٹbZZZ~وووووZiنوووومZZmوووووصZZ~وووووآZZ“ووظbZZk،؛اخصtZZغوووkZ_ووووwZZـووووومZZpوووووووووووووووووووووووووووووووووkYY¶ووووومYYY±وووووووووووووووووووووو²YYYقووو·YYiوووووووووووووووووووو–YY„ووووuYY±وووâYYY‚وووووووآYYYحووعYYYچووووووو¶YYYصوو¦YYwوووووووٹYY“وووكYYYسووووووزYYY©ووووووووووووnYY‰وووووووàكàووووووووووووووووو·ZZڑوووàZZzوووفZZZموووووو¶ZZzوووeZZةوووووورZZcووو}ZZ×ووووون_Zjووو²ZZ›ووووووصZZcوووومcZ‡ووووووو}ZZظوووووZZZمووووووووووووووووووو¶bZZ²وووبZZچووووووووووووووووو‍ZZ‡هووووâ_ZeوووسZZ_ووووووو­ZZƒوووeZZةوووووورZZcوووووووووâ‍ZZZظوووحZZ­وووووبZZچووووو¶ZZںووووو،ZZ´وو‍ZZ‡هووووâ_ZeوووàZZzوووه_ZiوووووواZZژوووووووووووووووووووووووووووووووونYYYثووووووbYY‚ووووووہڈڈگووشpnsغووووو×YYYظوووکYY|ووووووووووووووووووووvYY¤وووهZYYسوووؤYYYZظوووووغjYYƒووو·YYY]قوووووضcYYڈووو…YYکوووووووkYY¶ووووiYY~وووووزgYYYثووووظàوووووو‡YY_غووووو·YYY×وووووووووووووووو—ZZ؛وووآZZ™ووو¾ZZZأووووومnZZأووطZZZ§وووووو†ZZ¨وووbZcووووووحZZˆوووضZZiموووونپZZپوووو©ZZدوووووووbZcووووووgZZبووووومططلووح؛؛غووووو،ZZ ووو¨ZZھوووووووووووووووووZZحووووو¤ZZƒووو²ZZZحوووووâgZZحووطZZZ§وووووو†ZZ¨ووأ؛¼نووووو|ZZئوووƒZeمووووو¨ZZ­ووووو•ZZہوووووپZZشووZZحووووو¤ZZƒوووآZZ™وووخZZ†وووووو§ZZ¯ووووووووووووووووووووووووووووووووـYYY،ووووووکYYYگوووو¾YYY†ووم]YYvهوووهچYY]ووووŒYY]موووووووووووووووووووZYYاووودYY]وووو¢YYYYtغوووسcYYYسووو–YYYY|كوووحbYYZغوووfYY؛ووووووâYYY×وووو‘YYY{حمح¤ZYYYZهووو‰YZ¨وووووہYYYpâووواZYY€وووووووووووووووووwZZغووو،ZZ؛وووœZZZpâووول|ZZ}ووو¸ZZZbظوووهگZZgمووصZZپوووووو­ZZ¨ووووeZZٹâووظwZZZ،ووومeZƒوووووووàZZ_âوووووگZZtكوووâ{ZZڑوو«ZZvنووووچZZہووو”ZZ،وووووووووووووووووٹZZ‌ووووہ_ZZ£ووو‘ZZZzموووفuZZ‡ووو¸ZZZbظوووهگZZgموو†ZZ™وووونjZZلوودZZھوووووو‡ZZحوووووvZZàوووووeZbوووٹZZ‌ووووہ_ZZ£ووو،ZZ؛ووو­ZZ§وووووو†ZZخووووووووووووووووووووووووووووووووهZYYYt‹سوووـjYYYc…پbYYYZظووو’YYYbˆھکkYYYœوووو YYYb…¤وووووووووووووووورYYYمووو­YYwووووپYY~YY]ƒٹnYYYY©ووووuYYwYY_…ƒkYYYY²وووكYYYـووووووأYYbووووومvYYYYYYYYYYYsوووخYYY_هووووو‹YYYZz…bYYYYدووووووووووووووووه_ZgووووپZZغووو}ZZcZjھ¶ڑjZZ_خووو—ZZgZb¤·،tZZZ؛ووو´ZZ،ووووووچZZبوووو؛ZZZbujZZZZZآووو­ZZحووووووومZZZپ±حووود_ZZk¢¶کnZZbقووà_ZZ|¯حآ‡ZZbنووو›ZZb ¸موووووووووووووو´ZZ_“½¶گZZZZأوووsZZeZn­¶—gZZcصووو—ZZgZb¤·،tZZZ؛وووآZZZژ¸خ؛pZZپووو‡ZcمووووووjZ_نوووون_ZjوووووظZZ}ووو´ZZ_“½¶گZZZZأوووپZZغوووژZZئووووووiZ_هوووووووووووووووووووووووووووووووووٹYYYYYحووووفnYYYYYYYYbآووووà‚YYYYYYYYY‌هوووورZYYYY~وووووووووووووووو¯YYnوووو‹YYکووووcYYش€YYYYYYYZ½ووووهZYYحzYYYYYYY]ؤوووو¾YYbووووووو YY|وووووولpYYYYYYگگYY“ووودYYY_هوووووه…YYYYYYYYbأوووووووووووووووووخZZƒووووeZeووووbZu؛ZZZZZZZiزووووwZZح_ZZZZZZ_آوووو”ZZآووووووmZZمووووو²ZZZZZZژwZZلوونiZووووووووو|ZZZZگووووتbZZZZZZZb¾وووو¯ZZZZZZZZbہووووئZZZZZغووووووووووووووàsZZZZZZ_eZZلوومZZm¶ZZZZZZZnضووووwZZح_ZZZZZZ_آوووووگZZZZZZZZpشووسZZ¥ووووووكZZvوووووحZZˆووووو¸ZZ›وووàsZZZZZZ_eZZلوووeZeووووpZZموووووفZZwووووووووووووووووووووووووووووووووووم“ZYYZهوووووàڈiYYYYfگلووووووو¬jYYYY]tآوووووووأpYYY‍وووووووووووووووو“YYچووووsYY؛وووâYY_وو§]YYYYzخووووودYYZههœZYYYY~شووووو¤YYپووووووو†YY‌ووووووون´…s€،ئوnYY¶ووووŒYZھوووووووه—]YYYYfŒàوووووووووووووووووو´ZZ¤وووكZZƒوووغZZ”وإmZZZjگفووووه_ZiوزwZZZc†زوووووzZZàووووونZZsوووووووشھپ{ڑ¾ن_Zmووو±ZZةوووووووووغ–kZZ¯وووووحپbZZZeٹـووووووخz_ZZZcƒطوووووو¸_Zgووووووووووووووووâ†_ZZZخjZmوووةZZچو¾gZZZk“àووووه_ZiوزwZZZc†زووووووو¸nZZZZi•موووŒZbâووووووإZZ•ووووو±ZZ¨ووووو‌ZZ¼ووووâ†_ZZZخjZmوووكZZƒوووهZZpووووووأZZ—وووووووووووووووووووووووووووووووووووووفظàوووووووووكأةâوووووووووووومث½ضوووووووووووومغظهوووووووووووووووووووووووووووووووووووووووشئئفووووووو­YYsوووهرؤبكووووووووووووووووووووووووووووووووووووصYYYظوووووàâوووووووووومد¾ؤàووووووووووووووووووووووووووووووووووووووووووـاعوووووووخZZ‡وووàإسوووووووووووووووووووووووووووووووووو­ZZچووهjZ|وووووووووووووكغووووووووورةكووووووووووووشأغووووووووووومغâوووووووووووووووووونحةàوووووووو¨ZZ­وووظأغوووووووخZZ‡وووàإسوووووووووووومحئلوووووصZZ،ووووووووووووووووووووووووووووووووووونحةàوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووھssssssssssssssسووووووووووووووووووووووووووووووووووو‹YY“وووووووووووووووووووووووووووووووووڑrr¤وووووووچYYrووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو¯ZZ¨ووووووووووووووووووووووووووووووٹeeأوووووـbZZأوو¶ZZئووووووووووووووووووووووووووووووووووووووووووووووووووووووووپgggggggggggg­ووووووووووووووووˆZZخووووووووووووو¯ZZ¨وووووووووووووووووووووووووووگZbàووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووwYYYYYYYYYYYYYYâوووووووووووووووووووووووووووووووووووkYY¶ووووووووووووووووووووووووووووووووو§YYZؤووووه YYY°وووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووژZZةوووووووووووووووووووووووووووووو¶ZZe¼لووس{ZZmوووmZwوووووووووووووووووووووووووووووووووووووووووووووووووووووووومZZZZZZZZZZZZZآووووووووووووووووjZ_هوووووووووووووژZZةووووووووووووووووووووووووووطZZœوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووکٹٹٹٹٹٹٹٹٹٹٹٹٹکووووووووووووووووووووووووووووووووووومYYYظوووووووووووووووووووووووووووووووووàZYYYfٹ¤’gYYY{نوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووpZZموووووووووووووووووووووووووووووومpZZZZniZZZcسوو؛ZZآوووووووووووووووووووووووووووووووووووووووووووووووووووووووونإإإإإإإإإإإإإموووووووووووووووكZZzووووووووووووووpZZموووووووووووووووووووووووووو”Z_كوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووئYYbوووووووووووووووووووووووووووووووووووتcYYYYYYYYYwموووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووهc_zوووووووووووووووووووووووووووووووومگZZZZZZZروووغابوووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووب__œوووووووووووووهc_zوووووووووووووووووووووووووووسارووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووز™™°ووووووووووووووووووووووووووووووووووووàŒfYYYYYr»وووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووسµ—ˆ”¨حووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووولؤ¾زمووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووووو \ No newline at end of file diff --git a/libpng/test_apps/main/test_libpng.c b/libpng/test_apps/main/test_libpng.c new file mode 100644 index 0000000000..61e82aba6e --- /dev/null +++ b/libpng/test_apps/main/test_libpng.c @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "unity.h" +#include "png.h" + +extern const uint8_t in_png_start[] asm("_binary_in_png_start"); +extern const uint8_t in_png_end[] asm("_binary_in_png_end"); + +extern const uint8_t out_pgm_start[] asm("_binary_out_pgm_start"); +extern const uint8_t out_pgm_end[] asm("_binary_out_pgm_end"); + +TEST_CASE("load a png image", "[libpng]") +{ + png_image image; + memset(&image, 0, (sizeof image)); + image.version = PNG_IMAGE_VERSION; + + const uint8_t *buf = &in_png_start[0]; + const size_t buf_len = in_png_end - in_png_start; + + const size_t expected_width = 522; + const size_t expected_height = 52; + + TEST_ASSERT(png_image_begin_read_from_memory(&image, buf, buf_len)); + + image.format = PNG_FORMAT_GRAY; + int stride = PNG_IMAGE_ROW_STRIDE(image); + int buf_size = PNG_IMAGE_SIZE(image); + + TEST_ASSERT_EQUAL(expected_width, image.width); + TEST_ASSERT_EQUAL(expected_height, image.height); + + png_bytep buffer = malloc(buf_size); + TEST_ASSERT_NOT_NULL(buffer); + + TEST_ASSERT(png_image_finish_read(&image, NULL, buffer, stride, NULL)); + + FILE *expected = fmemopen((void *)out_pgm_start, out_pgm_end - out_pgm_start, "r"); + TEST_ASSERT_NOT_NULL(expected); + // skip the header + fscanf(expected, "P5\n%*d %*d\n%*d\n"); + // check the binary data + for (int i = 0; i < buf_size; i++) { + uint8_t expected_byte; + TEST_ASSERT_EQUAL(1, fread(&expected_byte, 1, 1, expected)); + TEST_ASSERT_EQUAL(expected_byte, buffer[i]); + } + fclose(expected); + + free(buffer); +} \ No newline at end of file diff --git a/libpng/test_apps/main/test_main.c b/libpng/test_apps/main/test_main.c new file mode 100644 index 0000000000..077f813e3f --- /dev/null +++ b/libpng/test_apps/main/test_main.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" +#include "esp_newlib.h" +#include "unity_test_utils_memory.h" + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(0); +} + +void app_main(void) +{ + printf("Running libpng component tests\n"); + unity_run_menu(); +} diff --git a/libpng/test_apps/pytest_libpng.py b/libpng/test_apps/pytest_libpng.py new file mode 100644 index 0000000000..09d1b3f23d --- /dev/null +++ b/libpng/test_apps/pytest_libpng.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.mark.generic +def test_libpng(dut) -> None: + dut.run_all_single_board_cases() diff --git a/libpng/test_apps/sdkconfig.defaults b/libpng/test_apps/sdkconfig.defaults new file mode 100644 index 0000000000..ef5e06c6b0 --- /dev/null +++ b/libpng/test_apps/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_ESP_TASK_WDT_INIT=n diff --git a/libsodium/.build-test-rules.yml b/libsodium/.build-test-rules.yml new file mode 100644 index 0000000000..ac2444510e --- /dev/null +++ b/libsodium/.build-test-rules.yml @@ -0,0 +1,4 @@ +libsodium/test_apps: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3"] + reason: "Sufficient to test on one Xtensa and one RISC-V target" diff --git a/libsodium/test/CMakeLists.txt b/libsodium/test/CMakeLists.txt deleted file mode 100644 index 41de273958..0000000000 --- a/libsodium/test/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -if(TESTS_ALL EQUAL 1) - message("not linking libsodium tests, use '-T libsodium' to test it") -else() - get_filename_component(LS_TESTDIR "${CMAKE_CURRENT_LIST_DIR}/../libsodium/test/default" ABSOLUTE) - - set(TEST_CASES "chacha20;aead_chacha20poly1305;box;box2;ed25519_convert;sign;hash") - - foreach(test_case ${TEST_CASES}) - file(GLOB test_case_file "${LS_TESTDIR}/${test_case}.c") - list(APPEND TEST_CASES_FILES ${test_case_file}) - endforeach() - - idf_component_register(SRCS "${TEST_CASES_FILES}" "test_sodium.c" - PRIV_INCLUDE_DIRS "." "${LS_TESTDIR}/../quirks" - PRIV_REQUIRES cmock libsodium) - - # The libsodium test suite is designed to be run each test case as an executable on a desktop computer and uses - # filesytem to write & then compare contents of each file. - # - # For now, use their "BROWSER_TEST" mode with these hacks so that - # multiple test cases can be combined into one ELF file. - # - # Run each test case from test_sodium.c as CASENAME_xmain(). - foreach(test_case_file ${TEST_CASES_FILES}) - get_filename_component(test_case ${test_case_file} NAME_WE) - set_source_files_properties(${test_case_file} - PROPERTIES COMPILE_FLAGS - # This would generate 'warning "main" redefined' warnings at runtime, which are - # silenced here. Only other solution involves patching libsodium's cmptest.h. - "-Dxmain=${test_case}_xmain -Dmain=${test_case}_main -Wp,-w") - endforeach() - - # this seems odd, but it prevents the libsodium test harness from - # trying to write to a file! - add_definitions(-DBROWSER_TESTS) -endif() diff --git a/libsodium/test_apps/CMakeLists.txt b/libsodium/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..4ba6ed027a --- /dev/null +++ b/libsodium/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(libsodium_test) diff --git a/libsodium/test_apps/main/CMakeLists.txt b/libsodium/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..b8eada9a41 --- /dev/null +++ b/libsodium/test_apps/main/CMakeLists.txt @@ -0,0 +1,36 @@ +get_filename_component(LS_TESTDIR "${CMAKE_CURRENT_LIST_DIR}/../../libsodium/test/default" ABSOLUTE) + +set(TEST_CASES "chacha20;aead_chacha20poly1305;box;box2;ed25519_convert;sign;hash") + +foreach(test_case ${TEST_CASES}) + file(GLOB test_case_file "${LS_TESTDIR}/${test_case}.c") + list(APPEND TEST_CASES_FILES ${test_case_file}) + file(GLOB test_case_expected_output "${LS_TESTDIR}/${test_case}.exp") + list(APPEND TEST_CASES_EXP_FILES ${test_case_expected_output}) +endforeach() + +idf_component_register(SRCS "${TEST_CASES_FILES}" "test_sodium.c" "test_main.c" + PRIV_INCLUDE_DIRS "." "${LS_TESTDIR}/../quirks" + PRIV_REQUIRES unity + EMBED_TXTFILES ${TEST_CASES_EXP_FILES} + WHOLE_ARCHIVE) + +# The libsodium test suite is designed to be run each test case as an executable on a desktop computer and uses +# filesytem to write & then compare contents of each file. +# +# For now, use their "BROWSER_TEST" mode with these hacks so that +# multiple test cases can be combined into one ELF file. +# +# Run each test case from test_sodium.c as CASENAME_xmain(). +foreach(test_case_file ${TEST_CASES_FILES}) + get_filename_component(test_case ${test_case_file} NAME_WE) + set_source_files_properties(${test_case_file} + PROPERTIES COMPILE_FLAGS + # This would generate 'warning "main" redefined' warnings at runtime, which are + # silenced here. Only other solution involves patching libsodium's cmptest.h. + "-Dxmain=${test_case}_xmain -Dmain=${test_case}_main -Wp,-w") +endforeach() + +# this seems odd, but it prevents the libsodium test harness from +# trying to write to a file! +add_definitions(-DBROWSER_TESTS) diff --git a/libsodium/test_apps/main/idf_component.yml b/libsodium/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..a082f9ccf2 --- /dev/null +++ b/libsodium/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/libsodium: + version: "*" + override_path: "../.." diff --git a/libsodium/test_apps/main/test_main.c b/libsodium/test_apps/main/test_main.c new file mode 100644 index 0000000000..1be3247da3 --- /dev/null +++ b/libsodium/test_apps/main/test_main.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" +#include "esp_newlib.h" +#include "unity_test_utils_memory.h" + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(0); +} + +void app_main(void) +{ + printf("Running libsodium component tests\n"); + unity_run_menu(); +} diff --git a/libsodium/test/test_sodium.c b/libsodium/test_apps/main/test_sodium.c similarity index 63% rename from libsodium/test/test_sodium.c rename to libsodium/test_apps/main/test_sodium.c index 7b8582b7f4..5d87a177cb 100644 --- a/libsodium/test/test_sodium.c +++ b/libsodium/test_apps/main/test_sodium.c @@ -1,70 +1,42 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include #include "unity.h" #include "sodium/crypto_hash_sha256.h" #include "sodium/crypto_hash_sha512.h" -/* Note: a lot of these libsodium test programs assert() things, but they're not complete unit tests - most expect - output to be compared to the matching .exp file. - We don't do this automatically yet, maybe once we have more options for - internal filesystem storage. -*/ +#define LIBSODIUM_TEST(name_) \ + extern int name_ ## _xmain(void); \ + extern const uint8_t name_ ## _exp_start[] asm("_binary_" #name_ "_exp_start"); \ + extern const uint8_t name_ ## _exp_end[] asm("_binary_" #name_ "_exp_end"); \ + TEST_CASE("" #name_ " test vectors", "[libsodium]") { \ + printf("Running " #name_ "\n"); \ + FILE* old_stdout = stdout; \ + char* test_output; \ + size_t test_output_size; \ + FILE* test_output_stream = open_memstream(&test_output, &test_output_size); \ + stdout = test_output_stream; \ + TEST_ASSERT_EQUAL(0, name_ ## _xmain()); \ + fclose(test_output_stream); \ + stdout = old_stdout; \ + const char *expected = (const char*) &name_ ## _exp_start[0]; \ + TEST_ASSERT_EQUAL_STRING(expected, test_output); \ + free(test_output); \ + } + + +LIBSODIUM_TEST(aead_chacha20poly1305) +LIBSODIUM_TEST(chacha20) +LIBSODIUM_TEST(box) +LIBSODIUM_TEST(box2) +LIBSODIUM_TEST(ed25519_convert) +LIBSODIUM_TEST(hash) +LIBSODIUM_TEST(sign) -extern int aead_chacha20poly1305_xmain(void); - -TEST_CASE("aead_chacha20poly1305 test vectors", "[libsodium]") -{ - printf("Running aead_chacha20poly1305\n"); - TEST_ASSERT_EQUAL(0, aead_chacha20poly1305_xmain()); -} - -extern int chacha20_xmain(void); - -TEST_CASE("chacha20 test vectors", "[libsodium]") -{ - printf("Running chacha20\n"); - TEST_ASSERT_EQUAL(0, chacha20_xmain()); -} - -extern int box_xmain(void); -extern int box2_xmain(void); - -TEST_CASE("box tests", "[libsodium]") -{ - printf("Running box\n"); - TEST_ASSERT_EQUAL(0, box_xmain()); - - printf("Running box2\n"); - TEST_ASSERT_EQUAL(0, box2_xmain()); -} - -extern int ed25519_convert_xmain(void); - -TEST_CASE("ed25519_convert tests", "[libsodium][timeout=60]") -{ - printf("Running ed25519_convert\n"); - TEST_ASSERT_EQUAL(0, ed25519_convert_xmain() ); -} - -extern int sign_xmain(void); - -TEST_CASE("sign tests", "[libsodium]") -{ - printf("Running sign\n"); - TEST_ASSERT_EQUAL(0, sign_xmain() ); -} - -extern int hash_xmain(void); - -TEST_CASE("hash tests", "[libsodium]") -{ - printf("Running hash\n"); - TEST_ASSERT_EQUAL(0, hash_xmain() ); -} TEST_CASE("sha256 sanity check", "[libsodium]") { diff --git a/libsodium/test_apps/pytest_libsodium.py b/libsodium/test_apps/pytest_libsodium.py new file mode 100644 index 0000000000..29f3a5deb0 --- /dev/null +++ b/libsodium/test_apps/pytest_libsodium.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.mark.generic +def test_libsodium(dut) -> None: + dut.run_all_single_board_cases(timeout=120) diff --git a/libsodium/test_apps/sdkconfig.defaults b/libsodium/test_apps/sdkconfig.defaults new file mode 100644 index 0000000000..c6ae459d93 --- /dev/null +++ b/libsodium/test_apps/sdkconfig.defaults @@ -0,0 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 +CONFIG_ESP_TASK_WDT_INIT=n diff --git a/network_provisioning/examples/wifi_prov/CMakeLists.txt b/network_provisioning/examples/wifi_prov/CMakeLists.txt index a80c22a1a1..6df4dd77c0 100644 --- a/network_provisioning/examples/wifi_prov/CMakeLists.txt +++ b/network_provisioning/examples/wifi_prov/CMakeLists.txt @@ -3,4 +3,5 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) project(wifi_prov) diff --git a/onewire_bus/.build-test-rules.yml b/onewire_bus/.build-test-rules.yml new file mode 100644 index 0000000000..0e046b0375 --- /dev/null +++ b/onewire_bus/.build-test-rules.yml @@ -0,0 +1,4 @@ +onewire_bus/test_apps: + disable: + - if: SOC_RTM_SUPPORTED != 1 + reason: Only RMT backend is implemented diff --git a/onewire_bus/test_apps/CMakeLists.txt b/onewire_bus/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..61074aa467 --- /dev/null +++ b/onewire_bus/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(onewire_bus_test) diff --git a/onewire_bus/test_apps/main/CMakeLists.txt b/onewire_bus/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..e17608450b --- /dev/null +++ b/onewire_bus/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "onewire_bus_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) diff --git a/onewire_bus/test_apps/main/idf_component.yml b/onewire_bus/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..a769d09c68 --- /dev/null +++ b/onewire_bus/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/onewire_bus: + version: "*" + override_path: "../.." diff --git a/onewire_bus/test_apps/main/onewire_bus_test.c b/onewire_bus/test_apps/main/onewire_bus_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/onewire_bus/test_apps/main/onewire_bus_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +} diff --git a/pcap/.build-test-rules.yml b/pcap/.build-test-rules.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pcap/test_apps/CMakeLists.txt b/pcap/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..68ec211416 --- /dev/null +++ b/pcap/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(pcap_test) diff --git a/pcap/test_apps/main/CMakeLists.txt b/pcap/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..35ef4be083 --- /dev/null +++ b/pcap/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "pcap_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) diff --git a/pcap/test_apps/main/idf_component.yml b/pcap/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..ea3b1bbb56 --- /dev/null +++ b/pcap/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/pcap: + version: "*" + override_path: "../.." diff --git a/pcap/test_apps/main/pcap_test.c b/pcap/test_apps/main/pcap_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/pcap/test_apps/main/pcap_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +} diff --git a/pid_ctrl/.build-test-rules.yml b/pid_ctrl/.build-test-rules.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pid_ctrl/test_apps/CMakeLists.txt b/pid_ctrl/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..28c0a07e59 --- /dev/null +++ b/pid_ctrl/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(pid_ctrl_test) diff --git a/pid_ctrl/test_apps/main/CMakeLists.txt b/pid_ctrl/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..62b42795a4 --- /dev/null +++ b/pid_ctrl/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "pid_ctrl_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) diff --git a/pid_ctrl/test_apps/main/idf_component.yml b/pid_ctrl/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..5497e7af32 --- /dev/null +++ b/pid_ctrl/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/pid_ctrl: + version: "*" + override_path: "../.." diff --git a/pid_ctrl/test_apps/main/pid_ctrl_test.c b/pid_ctrl/test_apps/main/pid_ctrl_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/pid_ctrl/test_apps/main/pid_ctrl_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +} diff --git a/pytest.ini b/pytest.ini index c5be4228b6..5919939a9e 100644 --- a/pytest.ini +++ b/pytest.ini @@ -9,14 +9,6 @@ addopts = --tb short markers = - # target markers - esp32: support esp32 target - esp32s2: support esp32s2 target - esp32s3: support esp32s3 target - esp32c3: support esp32c3 target - esp32c2: support esp32c2 target - supported_targets: support all supported targets ('esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2') - # env markers generic: generic runner ethernet: ethernet runners diff --git a/qrcode/.build-test-rules.yml b/qrcode/.build-test-rules.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/qrcode/test_apps/CMakeLists.txt b/qrcode/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..d75094c558 --- /dev/null +++ b/qrcode/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(qrcode_test) diff --git a/qrcode/test_apps/main/CMakeLists.txt b/qrcode/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..7dafc361c2 --- /dev/null +++ b/qrcode/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "qrcode_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) diff --git a/qrcode/test_apps/main/idf_component.yml b/qrcode/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..ca09814fac --- /dev/null +++ b/qrcode/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/qrcode: + version: "*" + override_path: "../.." diff --git a/qrcode/test_apps/main/qrcode_test.c b/qrcode/test_apps/main/qrcode_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/qrcode/test_apps/main/qrcode_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +} diff --git a/quirc/.build-test-rules.yml b/quirc/.build-test-rules.yml new file mode 100644 index 0000000000..9cf811434c --- /dev/null +++ b/quirc/.build-test-rules.yml @@ -0,0 +1,4 @@ +quirc/test_apps: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3"] + reason: "Sufficient to test on one Xtensa and one RISC-V target" diff --git a/quirc/test/CMakeLists.txt b/quirc/test/CMakeLists.txt deleted file mode 100644 index 093fe8d3e9..0000000000 --- a/quirc/test/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -idf_component_register(SRCS test_quirc.c PRIV_REQUIRES quirc unity EMBED_FILES test_qrcode.pgm) diff --git a/quirc/test_apps/CMakeLists.txt b/quirc/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..5354c7cfab --- /dev/null +++ b/quirc/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(quirc_test) diff --git a/quirc/test_apps/main/CMakeLists.txt b/quirc/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..d44da91c53 --- /dev/null +++ b/quirc/test_apps/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS test_quirc.c test_main.c + PRIV_REQUIRES unity + EMBED_FILES test_qrcode.pgm + WHOLE_ARCHIVE) diff --git a/quirc/test_apps/main/idf_component.yml b/quirc/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..0ddeed9cbe --- /dev/null +++ b/quirc/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/quirc: + version: "*" + override_path: "../.." diff --git a/quirc/test_apps/main/test_main.c b/quirc/test_apps/main/test_main.c new file mode 100644 index 0000000000..1fc91b82e1 --- /dev/null +++ b/quirc/test_apps/main/test_main.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" +#include "esp_newlib.h" +#include "unity_test_utils_memory.h" + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(0); +} + +void app_main(void) +{ + printf("Running quirc component tests\n"); + unity_run_menu(); +} diff --git a/quirc/test/test_qrcode.pgm b/quirc/test_apps/main/test_qrcode.pgm similarity index 100% rename from quirc/test/test_qrcode.pgm rename to quirc/test_apps/main/test_qrcode.pgm diff --git a/quirc/test/test_quirc.c b/quirc/test_apps/main/test_quirc.c similarity index 78% rename from quirc/test/test_quirc.c rename to quirc/test_apps/main/test_quirc.c index f74248aff8..1d401faf4c 100644 --- a/quirc/test/test_quirc.c +++ b/quirc/test_apps/main/test_quirc.c @@ -70,20 +70,22 @@ TEST_CASE("quirc can load a QR code", "[quirc]") // decode the QR code in the image // quirc uses a lot of stack space (around 10kB on ESP32 for this particular QR code), // so do this in a separate task - quirc_decode_task_args_t args = { - .q = q, - .done = xSemaphoreCreateBinary(), - }; - TEST_ASSERT(xTaskCreate(quirc_decode_task, "quirc_decode_task", 12000, &args, 5, NULL)); - TEST_ASSERT(xSemaphoreTake(args.done, pdMS_TO_TICKS(10000))); - vSemaphoreDelete(args.done); + quirc_decode_task_args_t *args = calloc(1, sizeof(*args)); + TEST_ASSERT_NOT_NULL(args); + args->q = q; + args->done = xSemaphoreCreateBinary(); + TEST_ASSERT(xTaskCreate(quirc_decode_task, "quirc_decode_task", 12000, args, 5, NULL)); + TEST_ASSERT(xSemaphoreTake(args->done, pdMS_TO_TICKS(10000))); + vSemaphoreDelete(args->done); // check the QR code data - TEST_ASSERT_EQUAL_INT(1, args.data.version); - TEST_ASSERT_EQUAL_INT(1, args.data.ecc_level); - TEST_ASSERT_EQUAL_INT(4, args.data.data_type); - TEST_ASSERT_EQUAL_INT(13, args.data.payload_len); - TEST_ASSERT_EQUAL_STRING("test of quirc", args.data.payload); + TEST_ASSERT_EQUAL_INT(1, args->data.version); + TEST_ASSERT_EQUAL_INT(1, args->data.ecc_level); + TEST_ASSERT_EQUAL_INT(4, args->data.data_type); + TEST_ASSERT_EQUAL_INT(13, args->data.payload_len); + TEST_ASSERT_EQUAL_STRING("test of quirc", args->data.payload); + free(args); quirc_destroy(q); + vTaskDelay(2); // allow the task to clean up } diff --git a/quirc/test_apps/pytest_quirc.py b/quirc/test_apps/pytest_quirc.py new file mode 100644 index 0000000000..356b6fa574 --- /dev/null +++ b/quirc/test_apps/pytest_quirc.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.mark.generic +def test_quirc(dut) -> None: + dut.run_all_single_board_cases() diff --git a/quirc/test_apps/sdkconfig.defaults b/quirc/test_apps/sdkconfig.defaults new file mode 100644 index 0000000000..ef5e06c6b0 --- /dev/null +++ b/quirc/test_apps/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_ESP_TASK_WDT_INIT=n diff --git a/sh2lib/examples/http2_request/pytest_http2_request.py b/sh2lib/examples/http2_request/pytest_http2_request.py index ab508aa95c..1aaa11074d 100644 --- a/sh2lib/examples/http2_request/pytest_http2_request.py +++ b/sh2lib/examples/http2_request/pytest_http2_request.py @@ -28,7 +28,6 @@ def is_test_server_available(): # type: () -> bool conn.close() -@pytest.mark.esp32 @pytest.mark.ethernet def test_examples_protocol_http2_request(dut: Dut) -> None: """ diff --git a/spi_nand_flash/test_app/main/test_app_main.c b/spi_nand_flash/test_app/main/test_app_main.c index a1cb44a1c3..7d942e80c0 100644 --- a/spi_nand_flash/test_app/main/test_app_main.c +++ b/spi_nand_flash/test_app/main/test_app_main.c @@ -7,30 +7,22 @@ #include "unity.h" #include "unity_test_utils.h" #include "esp_heap_caps.h" - -// Some resources are lazy allocated, the threadhold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (-100) - -static size_t before_free_8bit; -static size_t before_free_32bit; +#include "esp_newlib.h" +#include "unity_test_utils_memory.h" void setUp(void) { - before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + unity_utils_record_free_mem(); } void tearDown(void) { - size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); - unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD); - unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD); + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(0); } void app_main(void) { - UNITY_BEGIN(); + printf("Running spi_nand_flash component tests\n"); unity_run_menu(); - UNITY_END(); } diff --git a/zlib/.build-test-rules.yml b/zlib/.build-test-rules.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/zlib/test_apps/CMakeLists.txt b/zlib/test_apps/CMakeLists.txt new file mode 100644 index 0000000000..00a13a7ac6 --- /dev/null +++ b/zlib/test_apps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(zlib_test) diff --git a/zlib/test_apps/main/CMakeLists.txt b/zlib/test_apps/main/CMakeLists.txt new file mode 100644 index 0000000000..fa3c5a9a90 --- /dev/null +++ b/zlib/test_apps/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "zlib_test.c" + INCLUDE_DIRS "." + PRIV_REQUIRES unity) diff --git a/zlib/test_apps/main/idf_component.yml b/zlib/test_apps/main/idf_component.yml new file mode 100644 index 0000000000..83d612f6fc --- /dev/null +++ b/zlib/test_apps/main/idf_component.yml @@ -0,0 +1,4 @@ +dependencies: + espressif/zlib: + version: "*" + override_path: "../.." diff --git a/zlib/test_apps/main/zlib_test.c b/zlib/test_apps/main/zlib_test.c new file mode 100644 index 0000000000..7b66f33939 --- /dev/null +++ b/zlib/test_apps/main/zlib_test.c @@ -0,0 +1,6 @@ +#include + +void app_main(void) +{ + +}