From 7d0796dd35af859a252a2b66cd6b66a80df6ac62 Mon Sep 17 00:00:00 2001 From: Li Junru Date: Wed, 10 May 2023 18:15:15 +0800 Subject: [PATCH] CI: Add hardware test 1. Use parallel 2. Fix lightbulb_driver build warning Co-authored-by: Chen Yudong --- .gitignore | 6 + .gitlab-ci.yml | 4 +- .gitlab/ci/build.yml | 395 +++++++--------------- .gitlab/ci/rules.yml | 132 ++++++++ .gitlab/ci/target_test.yml | 36 ++ components/.build-rules.yml | 3 + conftest.py | 215 ++++++++++++ examples/.build-rules.yml | 129 +++++++ pytest.ini | 42 +++ tools/build_apps.py | 149 ++++++++ tools/requirements/requirement.pytest.txt | 5 + 11 files changed, 845 insertions(+), 271 deletions(-) create mode 100644 .gitlab/ci/target_test.yml create mode 100644 components/.build-rules.yml create mode 100644 conftest.py create mode 100644 examples/.build-rules.yml create mode 100644 pytest.ini create mode 100644 tools/build_apps.py create mode 100644 tools/requirements/requirement.pytest.txt diff --git a/.gitignore b/.gitignore index bc073550b..aecccb196 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,9 @@ flake8_output.txt # ESP-IDF default build directory name build +build_esp*/ +build_linux*/ +size_info.txt # lock files for examples and components dependencies.lock @@ -100,3 +103,6 @@ managed_components # pytest log pytest_embedded_log/ +pytest_log/ +.pytest_cache/ +XUNIT_RESULT.xml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 15f12aa39..89c610d73 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ stages: - pre_check - build + - target_test - build_doc - deploy @@ -38,4 +39,5 @@ include: - '.gitlab/ci/pre_check.yml' - '.gitlab/ci/build.yml' - '.gitlab/ci/docs.yml' - - '.gitlab/ci/deploy.yml' \ No newline at end of file + - '.gitlab/ci/deploy.yml' + - '.gitlab/ci/target_test.yml' \ No newline at end of file diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index 46d5e7680..16aaf918b 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -1,8 +1,8 @@ .build_template: &build_template stage: build - image: espressif/idf:release-v4.4 tags: - build + image: ${IMAGE} variables: # Enable ccache for all build jobs. See configure_ci_environment.sh for more ccache related settings. IDF_CCACHE_ENABLE: "1" @@ -34,457 +34,312 @@ script: - pip install --upgrade idf-component-manager - pip install idf_build_apps - - python -m idf_build_apps build -vv - -p $EXAMPLE_DIR - -t all - --config "sdkconfig.ci.*=" - --build-dir build_@t_@w - --build-log build_log.txt - --size-file size.json - --check-warnings - --ignore-warning-str "$WARNING_STR" - --collect-size-info size_info.txt - --default-build-targets $IDF_TARGET - -build_example_audio_wav_player_v4.4: - extends: - - .build_examples_template - - .rules:build:example_audio_wav_player - image: espressif/idf:release-v4.4 - variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 - EXAMPLE_DIR: examples/audio/wav_player + - python tools/build_apps.py ${EXAMPLE_DIR} -t all -vv -build_example_audio_wav_player_v5.0: +build_example_audio_wav_player: extends: - .build_examples_template - .rules:build:example_audio_wav_player - image: espressif/idf:release-v5.0 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c2,esp32c3 EXAMPLE_DIR: examples/audio/wav_player -build_example_bluetooth_ble_ota_v4.4: - extends: - - .build_examples_template - - .rules:build:example_bluetooth_ble_ota - image: espressif/idf:release-v4.4 - variables: - IDF_TARGET: esp32,esp32s3,esp32c3 - EXAMPLE_DIR: examples/bluetooth/ble_ota - -build_example_bluetooth_ble_ota_v5.0: +build_example_bluetooth_ble_ota: extends: - .build_examples_template - .rules:build:example_bluetooth_ble_ota - image: espressif/idf:release-v5.0 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s3,esp32c3 EXAMPLE_DIR: examples/bluetooth/ble_ota -build_example_camera_basic_v4.4: - extends: - - .build_examples_template - - .rules:build:example_camera_basic - image: espressif/idf:release-v4.4 - variables: - IDF_TARGET: esp32s2,esp32s3 - EXAMPLE_DIR: examples/camera/basic - -build_example_camera_basic_v5.0: +build_example_camera_basic: extends: - .build_examples_template - .rules:build:example_camera_basic - image: espressif/idf:release-v5.0 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s2,esp32s3 EXAMPLE_DIR: examples/camera/basic -build_example_camera_pic_server_v4.4: - extends: - - .build_examples_template - - .rules:build:example_camera_pic_server - image: espressif/idf:release-v4.4 - variables: - IDF_TARGET: esp32s2,esp32s3 - EXAMPLE_DIR: examples/camera/pic_server - -build_example_camera_pic_server_v5.0: +build_example_camera_pic_server: extends: - .build_examples_template - .rules:build:example_camera_pic_server - image: espressif/idf:release-v5.0 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s2,esp32s3 EXAMPLE_DIR: examples/camera/pic_server -build_example_camera_test_framerate_v4.4: +build_example_camera_test_framerate: extends: - .build_examples_template - .rules:build:example_camera_test_framerate - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s2,esp32s3 EXAMPLE_DIR: examples/camera/test_framerate -build_example_camera_test_framerate_v5.0: - extends: - - .build_examples_template - - .rules:build:example_camera_test_framerate - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32s2,esp32s3 - EXAMPLE_DIR: examples/camera/test_framerate - -build_example_camera_video_recorder_v4.4: - extends: - - .build_examples_template - - .rules:build:example_camera_video_recorder - image: espressif/idf:release-v4.4 - variables: - IDF_TARGET: esp32s3 - EXAMPLE_DIR: examples/camera/video_recorder - -build_example_camera_video_recorder_v5.0: +build_example_camera_video_recorder: extends: - .build_examples_template - .rules:build:example_camera_video_recorder - image: espressif/idf:release-v5.0 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s3 EXAMPLE_DIR: examples/camera/video_recorder -build_example_camera_video_stream_server_v4.4: +build_example_camera_video_stream_server: extends: - .build_examples_template - .rules:build:example_camera_video_stream_server - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32s2,esp32s3 EXAMPLE_DIR: examples/camera/video_stream_server + IMAGE: espressif/idf:release-v4.4 -build_example_camera_video_stream_server_v5.0: - extends: - - .build_examples_template - - .rules:build:example_camera_video_stream_server - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32s2,esp32s3 - EXAMPLE_DIR: examples/camera/video_stream_server - -build_example_check_pedestrian_flow_v4.4: +build_example_check_pedestrian_flow: extends: - .build_examples_template - .rules:build:example_check_pedestrian_flow - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 EXAMPLE_DIR: examples/check_pedestrian_flow -build_example_extended_vfs_gpio_gpio_simple_v4.4: +build_example_extended_vfs_gpio_gpio_simple: extends: - .build_examples_template - .rules:build:example_extended_vfs_gpio_gpio_simple - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 EXAMPLE_DIR: examples/extended_vfs/gpio/gpio_simple -build_example_extended_vfs_gpio_gpio_simple_v5.0: - extends: - - .build_examples_template - - .rules:build:example_extended_vfs_gpio_gpio_simple - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c2,esp32c3 - EXAMPLE_DIR: examples/extended_vfs/gpio/gpio_simple - -build_example_extended_vfs_i2c_i2c_bh1750_v4.4: +build_example_extended_vfs_i2c_i2c_bh1750: extends: - .build_examples_template - .rules:build:example_extended_vfs_i2c_i2c_bh1750 - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 EXAMPLE_DIR: examples/extended_vfs/i2c/i2c_bh1750 -build_example_extended_vfs_i2c_i2c_bh1750_v5.0: - extends: - - .build_examples_template - - .rules:build:example_extended_vfs_i2c_i2c_bh1750 - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c2,esp32c3 - EXAMPLE_DIR: examples/extended_vfs/i2c/i2c_bh1750 - -build_example_extended_vfs_i2c_i2c_tt21100_v4.4: +build_example_extended_vfs_i2c_i2c_tt21100: extends: - .build_examples_template - .rules:build:example_extended_vfs_i2c_i2c_tt21100 - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 EXAMPLE_DIR: examples/extended_vfs/i2c/i2c_tt21100 -build_example_extended_vfs_i2c_i2c_tt21100_v5.0: - extends: - - .build_examples_template - - .rules:build:example_extended_vfs_i2c_i2c_tt21100 - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c2,esp32c3 - EXAMPLE_DIR: examples/extended_vfs/i2c/i2c_tt21100 - -build_example_extended_vfs_ledc_ledc_simple_v4.4: - extends: - - .build_examples_template - - .rules:build:example_extended_vfs_ledc_ledc_simple - image: espressif/idf:release-v4.4 - variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 - EXAMPLE_DIR: examples/extended_vfs/ledc/ledc_simple - -build_example_extended_vfs_ledc_ledc_simple_v5.0: +build_example_extended_vfs_ledc_ledc_simple: extends: - .build_examples_template - .rules:build:example_extended_vfs_ledc_ledc_simple - image: espressif/idf:release-v5.0 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c2,esp32c3 EXAMPLE_DIR: examples/extended_vfs/ledc/ledc_simple -build_example_extended_vfs_spi_spi_master_simple_v4.4: +build_example_extended_vfs_spi_spi_master_simple: extends: - .build_examples_template - .rules:build:example_extended_vfs_spi_spi_master_simple - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 EXAMPLE_DIR: examples/extended_vfs/spi/spi_master_simple -build_example_extended_vfs_spi_spi_master_simple_v5.0: - extends: - - .build_examples_template - - .rules:build:example_extended_vfs_spi_spi_master_simple - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 - EXAMPLE_DIR: examples/extended_vfs/spi/spi_master_simple - -build_example_extended_vfs_spi_spi_slave_simple_v4.4: +build_example_extended_vfs_spi_spi_slave_simple: extends: - .build_examples_template - .rules:build:example_extended_vfs_spi_spi_slave_simple - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 EXAMPLE_DIR: examples/extended_vfs/spi/spi_slave_simple -build_example_extended_vfs_spi_spi_slave_simple_v5.0: - extends: - - .build_examples_template - - .rules:build:example_extended_vfs_spi_spi_slave_simple - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 - EXAMPLE_DIR: examples/extended_vfs/spi/spi_slave_simple - -build_example_get_started_blink_v4.4: +build_example_get_started_blink: extends: - .build_examples_template - .rules:build:example_get_started_blink - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32,esp32s2,esp32s3 EXAMPLE_DIR: examples/get-started/blink + IMAGE: espressif/idf:release-v4.4 -build_example_hmi_lvgl_coffee_v4.4: +build_example_hmi_lvgl_coffee: extends: - .build_examples_template - .rules:build:example_hmi_lvgl_coffee - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32 EXAMPLE_DIR: examples/hmi/lvgl_coffee + IMAGE: espressif/idf:release-v4.4 -build_example_hmi_lvgl_example_v4.4: +build_example_hmi_lvgl_example: extends: - .build_examples_template - .rules:build:example_hmi_lvgl_example - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32 EXAMPLE_DIR: examples/hmi/lvgl_example + IMAGE: espressif/idf:release-v4.4 -build_example_hmi_lvgl_thermostat_v4.4: +build_example_hmi_lvgl_thermostat: extends: - .build_examples_template - .rules:build:example_hmi_lvgl_thermostat - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32 EXAMPLE_DIR: examples/hmi/lvgl_thermostat + IMAGE: espressif/idf:release-v4.4 -build_example_hmi_lvgl_wificonfig_v4.4: +build_example_hmi_lvgl_wificonfig: extends: - .build_examples_template - .rules:build:example_hmi_lvgl_wificonfig - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32 EXAMPLE_DIR: examples/hmi/lvgl_wificonfig + IMAGE: espressif/idf:release-v4.4 -build_example_lighting_lightbulb_v4.4: - extends: - - .build_examples_template - - .rules:build:example_lighting_lightbulb - image: espressif/idf:release-v4.4 - variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 - EXAMPLE_DIR: examples/lighting/lightbulb - -build_example_lighting_lightbulb_v5.0: +build_example_lighting_lightbulb: extends: - .build_examples_template - .rules:build:example_lighting_lightbulb - image: espressif/idf:release-v5.0 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c2,esp32c3 EXAMPLE_DIR: examples/lighting/lightbulb -build_example_ota_simple_ota_example_v5.0: - extends: - - .build_examples_template - - .rules:build:example_ota_simple_ota_example - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32c2,esp32c3,esp32 - EXAMPLE_DIR: examples/ota/simple_ota_example - WARNING_STR: "1/2 app partitions are too small" - -build_example_ota_simple_ota_example_v5.1: +build_example_ota_simple_ota_example: extends: - .build_examples_template - .rules:build:example_ota_simple_ota_example - image: espressif/idf:release-v5.1 + parallel: + matrix: + - IMAGE: espressif/idf:release-v5.0 + - IMAGE: espressif/idf:release-v5.1 variables: - IDF_TARGET: esp32c2,esp32c3,esp32,esp32c6 EXAMPLE_DIR: examples/ota/simple_ota_example WARNING_STR: "1/2 app partitions are too small" -build_example_screen_v4.4: +build_example_screen: extends: - .build_examples_template - .rules:build:example_screen - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32 EXAMPLE_DIR: examples/screen + IMAGE: espressif/idf:release-v4.4 -build_example_sensors_sensor_control_led_v4.4: +build_example_sensors_sensor_control_led: extends: - .build_examples_template - .rules:build:example_sensors_sensor_control_led - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32,esp32s2 EXAMPLE_DIR: examples/sensors/sensor_control_led + IMAGE: espressif/idf:release-v4.4 -build_example_sensors_sensor_hub_monitor_v4.4: +build_example_sensors_sensor_hub_monitor: extends: - .build_examples_template - .rules:build:example_sensors_sensor_hub_monitor - image: espressif/idf:release-v4.4 variables: - IDF_TARGET: esp32,esp32s2 EXAMPLE_DIR: examples/sensors/sensor_hub_monitor + IMAGE: espressif/idf:release-v4.4 -build_example_usb_device_usb_msc_wireless_disk_v5.0: +build_example_usb_device_usb_msc_wireless_disk: extends: - .build_examples_template - .rules:build:example_usb_device_usb_msc_wireless_disk - image: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s2,esp32s3 EXAMPLE_DIR: examples/usb/device/usb_msc_wireless_disk + IMAGE: espressif/idf:release-v5.0 -build_example_usb_device_usb_surface_dial_v4.4: - extends: - - .build_examples_template - - .rules:build:example_usb_device_usb_surface_dial - image: espressif/idf:release-v4.4 - variables: - IDF_TARGET: esp32s2,esp32s3 - EXAMPLE_DIR: examples/usb/device/usb_surface_dial - -build_example_usb_device_usb_surface_dial_v5.0: +build_example_usb_device_usb_surface_dial: extends: - .build_examples_template - .rules:build:example_usb_device_usb_surface_dial - image: espressif/idf:release-v5.0 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s2,esp32s3 EXAMPLE_DIR: examples/usb/device/usb_surface_dial -build_example_usb_host_usb_camera_lcd_display_v5.0: +build_example_usb_host_usb_camera_lcd_display: extends: - .build_examples_template - .rules:build:example_usb_host_usb_camera_lcd_display - image: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s3 EXAMPLE_DIR: examples/usb/host/usb_camera_lcd_display + IMAGE: espressif/idf:release-v5.0 -build_example_usb_host_usb_camera_mic_spk_v4.4: +build_example_usb_host_usb_camera_mic_spk: extends: - .build_examples_template - .rules:build:example_usb_host_usb_camera_mic_spk - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s2,esp32s3 EXAMPLE_DIR: examples/usb/host/usb_camera_mic_spk -build_example_usb_host_usb_camera_mic_spk_v5.0: - extends: - - .build_examples_template - - .rules:build:example_usb_host_usb_camera_mic_spk - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32s2,esp32s3 - EXAMPLE_DIR: examples/usb/host/usb_camera_mic_spk - -build_example_usb_host_usb_cdc_4g_module_v4.4: +build_example_usb_host_usb_cdc_4g_module: extends: - .build_examples_template - .rules:build:example_usb_host_usb_cdc_4g_module - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32s2,esp32s3 EXAMPLE_DIR: examples/usb/host/usb_cdc_4g_module -build_example_usb_host_usb_cdc_4g_module_v5.0: - extends: - - .build_examples_template - - .rules:build:example_usb_host_usb_cdc_4g_module - image: espressif/idf:release-v5.0 - variables: - IDF_TARGET: esp32s2,esp32s3 - EXAMPLE_DIR: examples/usb/host/usb_cdc_4g_module - -build_example_utilities_xz_decompress_file_v4.4: +build_example_utilities_xz_decompress_file: extends: - .build_examples_template - .rules:build:example_utilities_xz_decompress_file - image: espressif/idf:release-v4.4 + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c3 EXAMPLE_DIR: examples/utilities/xz_decompress_file -build_example_utilities_xz_decompress_file_v5.0: +build_components_usb_usb_stream_test_apps: extends: - .build_examples_template - - .rules:build:example_utilities_xz_decompress_file - image: espressif/idf:release-v5.0 + - .rules:build:components_usb_usb_stream_test + parallel: + matrix: + - IMAGE: espressif/idf:release-v4.4 + - IMAGE: espressif/idf:release-v5.0 variables: - IDF_TARGET: esp32,esp32s2,esp32s3,esp32c2,esp32c3 - EXAMPLE_DIR: examples/utilities/xz_decompress_file \ No newline at end of file + EXAMPLE_DIR: components/usb/usb_stream/test_apps diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 1b65b0cf6..cc9fc1753 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -2,6 +2,12 @@ # Patterns # ############ +# build system, if changed, build all apps +.patterns-build_system: &patterns-build_system + - "tools/build_apps.py" + - "conftest.py" + - "pytest.ini" + # components folder, in the alphabetic order .patterns-components_audio_dac_audio: &patterns-components_audio_dac_audio - "components/audio/dac_audio/**/*" @@ -285,6 +291,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_audio_pwm_audio - <<: *if-dev-push @@ -294,6 +302,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_bluetooth_ble_profiles_esp_ble_ota - <<: *if-dev-push @@ -303,6 +313,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-example_camera_basic - <<: *if-dev-push @@ -312,6 +324,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-example_camera_pic_server - <<: *if-dev-push @@ -321,6 +335,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-example_camera_test_framerate - <<: *if-dev-push @@ -330,6 +346,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-example_camera_video_recorder - <<: *if-dev-push @@ -339,6 +357,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-example_camera_video_stream_server - <<: *if-dev-push @@ -348,6 +368,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-example_check_pedestrian_flow @@ -355,6 +377,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_extended_vfs - <<: *if-dev-push @@ -364,6 +388,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_extended_vfs - <<: *if-dev-push @@ -373,6 +399,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_extended_vfs - <<: *if-dev-push @@ -382,6 +410,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_extended_vfs - <<: *if-dev-push @@ -391,6 +421,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_extended_vfs - <<: *if-dev-push @@ -400,6 +432,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_extended_vfs - <<: *if-dev-push @@ -409,6 +443,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-example_get_started_blink @@ -416,6 +452,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_gui_lvgl_gui - <<: *if-dev-push @@ -427,6 +465,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_gui_lvgl_gui - <<: *if-dev-push @@ -438,6 +478,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_gui_lvgl_gui - <<: *if-dev-push @@ -449,6 +491,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_gui_lvgl_gui - <<: *if-dev-push @@ -460,6 +504,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_led_lightbulb_driver - <<: *if-dev-push @@ -469,6 +515,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_bootloader_support_plus - <<: *if-dev-push @@ -478,6 +526,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_display_screen - <<: *if-dev-push @@ -487,6 +537,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_bus - <<: *if-dev-push @@ -520,6 +572,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_bus - <<: *if-dev-push @@ -553,6 +607,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-example_usb_device_usb_msc_wireless_disk @@ -560,6 +616,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_button - <<: *if-dev-push @@ -571,6 +629,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_usb_usb_stream - <<: *if-dev-push @@ -580,6 +640,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_usb_usb_stream - <<: *if-dev-push @@ -589,6 +651,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_led_led_indicator - <<: *if-dev-push @@ -600,6 +664,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_utilities_xz - <<: *if-dev-push @@ -610,6 +676,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_audio_dac_audio @@ -617,6 +685,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_audio_pwm_audio @@ -624,6 +694,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_bus @@ -631,6 +703,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_button @@ -638,6 +712,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_display_digital_tube_ch450 @@ -645,6 +721,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_display_digital_tube_ht16c21 @@ -652,6 +730,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_display_digital_tube_is31fl3xxx @@ -659,6 +739,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_display_screen @@ -666,6 +748,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_display_touch_panel @@ -673,6 +757,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_expander_io_expander_mcp23017 @@ -680,6 +766,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_knob @@ -687,6 +775,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_led_led_indicator @@ -694,6 +784,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_led_light @@ -701,6 +793,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_led_lightbulb_driver @@ -708,6 +802,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_motor_servo @@ -715,6 +811,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_gesture_apds9960 @@ -722,6 +820,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_humiture_hdc2010 @@ -729,6 +829,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_humiture_hts221 @@ -736,6 +838,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_humiture_mvh3004d @@ -743,6 +847,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_humiture_sht3x @@ -750,6 +856,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_imu_lis2dh12 @@ -757,6 +865,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_imu_mpu6050 @@ -764,6 +874,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_light_sensor_bh1750 @@ -771,6 +883,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_light_sensor_veml6040 @@ -778,6 +892,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_light_sensor_veml6075 @@ -785,6 +901,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_pressure_bme280 @@ -792,6 +910,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_sensors_sensor_hub @@ -799,6 +919,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_storage_eeprom_at24c02 @@ -806,6 +928,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_usb_iot_usbh @@ -813,6 +937,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_usb_iot_usbh_cdc @@ -820,6 +946,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-components_usb_usb_stream @@ -827,6 +955,8 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-docs - <<: *if-dev-push @@ -836,5 +966,7 @@ rules: - <<: *if-protected - <<: *if-label-build + - <<: *if-dev-push + changes: *patterns-build_system - <<: *if-dev-push changes: *patterns-docs_md \ No newline at end of file diff --git a/.gitlab/ci/target_test.yml b/.gitlab/ci/target_test.yml new file mode 100644 index 000000000..8a910e5e5 --- /dev/null +++ b/.gitlab/ci/target_test.yml @@ -0,0 +1,36 @@ +variables: + # There is no target-test-env-v4.4 + DOCKER_TARGET_TEST_v5_0_ENV_IMAGE: "$CI_DOCKER_REGISTRY/target-test-env-v5.0:3" + DOCKER_TARGET_TEST_v5_1_ENV_IMAGE: "$CI_DOCKER_REGISTRY/target-test-env-v5.1:1" + +.test_template: &test_template + image: DOCKER_TARGET_TEST_v5_0_ENV_IMAGE + stage: target_test + timeout: 4 hour + variables: + GIT_DEPTH: 1 + SUBMODULES_TO_FETCH: "none" + cache: + # Usually do not need submodule-cache in target_test + - key: pip-cache + paths: + - .cache/pip + policy: pull + +.pytest_template: + <<: *test_template + artifacts: + when: always + paths: + - XUNIT_RESULT.xml + - pytest_embedded_log/ + reports: + junit: XUNIT_RESULT.xml + expire_in: 4 days + variables: + TEST_TARGET: 'esp32' + TEST_FOLDER: '.' + TEST_ENV: 'generic' + script: + - pip install -r tools/requirements/requirement.pytest.txt + - pytest ${TEST_FOLDER} --target ${IDF_TARGET} --env ${TEST_ENV} --junitxml=XUNIT_RESULT.xml diff --git a/components/.build-rules.yml b/components/.build-rules.yml new file mode 100644 index 000000000..0c41ac4b8 --- /dev/null +++ b/components/.build-rules.yml @@ -0,0 +1,3 @@ +components/usb/usb_stream/test_apps: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] \ No newline at end of file diff --git a/conftest.py b/conftest.py new file mode 100644 index 000000000..0220a9ef7 --- /dev/null +++ b/conftest.py @@ -0,0 +1,215 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: Apache-2.0 + +import logging +import os +import pathlib +import re +import sys +from datetime import datetime +from typing import Callable, List, Optional, Tuple + +import pytest +from pytest import Config, FixtureRequest, Function, Session +from pytest_embedded.plugin import multi_dut_argument, multi_dut_fixture + +IDF_VERSION = os.environ.get('IDF_VERSION') +PYTEST_ROOT_DIR = str(pathlib.Path(__file__).parent) +logging.info(f'Pytest root dir: {PYTEST_ROOT_DIR}') + + +@pytest.fixture(scope='session', autouse=True) +def idf_version() -> str: + if os.environ.get('IDF_VERSION'): + return os.environ.get('IDF_VERSION') + idf_path = os.environ.get('IDF_PATH') + if not idf_path: + logging.warning('Failed to get IDF_VERSION!') + return '' + version_path = os.path.join(os.environ['IDF_PATH'], 'tools/cmake/version.cmake') + regex = re.compile(r'^\s*set\s*\(\s*IDF_VERSION_([A-Z]{5})\s+(\d+)') + ver = {} + with open(version_path) as f: + for line in f: + m = regex.match(line) + if m: + ver[m.group(1)] = m.group(2) + return '{}.{}'.format(int(ver['MAJOR']), int(ver['MINOR'])) + + +@pytest.fixture(scope='session', autouse=True) +def session_tempdir() -> str: + _tmpdir = os.path.join( + os.path.dirname(__file__), + 'pytest_log', + datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), + ) + os.makedirs(_tmpdir, exist_ok=True) + return _tmpdir + + +@pytest.fixture +@multi_dut_argument +def config(request: FixtureRequest) -> str: + config_marker = list(request.node.iter_markers(name='config')) + return config_marker[0].args[0] if config_marker else 'default' + + +@pytest.fixture +@multi_dut_argument +def app_path(request: FixtureRequest, test_file_path: str) -> str: + config_marker = list(request.node.iter_markers(name='app_path')) + if config_marker: + return config_marker[0].args[0] + else: + # compatible with old pytest-embedded parametrize --app_path + return request.config.getoption('app_path', None) or os.path.dirname(test_file_path) + + +@pytest.fixture +def test_case_name(request: FixtureRequest, target: str, config: str) -> str: + if not isinstance(target, str): + target = '|'.join(sorted(list(set(target)))) + if not isinstance(config, str): + config = '|'.join(sorted(list(config))) + return f'{target}.{config}.{request.node.originalname}' + + +@pytest.fixture +@multi_dut_fixture +def build_dir( + app_path: str, + target: Optional[str], + config: Optional[str], + idf_version: str +) -> Optional[str]: + """ + Check local build dir with the following priority: + + 1. /${IDF_VERSION}/build__ + 2. /${IDF_VERSION}/build_ + 3. /build__ + 4. /build + 5. + + Args: + app_path: app path + target: target + config: config + + Returns: + valid build directory + """ + + assert target + assert config + check_dirs = [] + if idf_version: + check_dirs.append(os.path.join(idf_version, f'build_{target}_{config}')) + check_dirs.append(os.path.join(idf_version, f'build_{target}')) + check_dirs.append(f'build_{target}_{config}') + check_dirs.append('build') + check_dirs.append('.') + for check_dir in check_dirs: + binary_path = os.path.join(app_path, check_dir) + if os.path.isdir(binary_path): + logging.info(f'find valid binary path: {binary_path}') + return check_dir + + logging.warning( + f'checking binary path: {binary_path} ... missing ... try another place') + + logging.error( + f'no build dir. Please build the binary "python tools/build_apps.py {app_path}" and run pytest again') + sys.exit(1) + + +@pytest.fixture(autouse=True) +@multi_dut_fixture +def junit_properties( + test_case_name: str, record_xml_attribute: Callable[[str, object], None] +) -> None: + """ + This fixture is autoused and will modify the junit report test case name to .. + """ + record_xml_attribute('name', test_case_name) + + +################## +# Hook functions # +################## +_idf_pytest_embedded_key = pytest.StashKey['IdfPytestEmbedded'] + + +def pytest_addoption(parser: pytest.Parser) -> None: + base_group = parser.getgroup('idf') + base_group.addoption( + '--env', + help='only run tests matching the environment NAME.', + ) + + +def pytest_configure(config: Config) -> None: + # Require cli option "--target" + help_commands = ['--help', '--fixtures', '--markers', '--version'] + for cmd in help_commands: + if cmd in config.invocation_params.args: + target = 'unneeded' + break + else: + target = config.getoption('target') + if not target: + raise ValueError('Please specify one target marker via "--target [TARGET]"') + + config.stash[_idf_pytest_embedded_key] = IdfPytestEmbedded( + target=target, + env_name=config.getoption('env'), + ) + config.pluginmanager.register(config.stash[_idf_pytest_embedded_key]) + + +def pytest_unconfigure(config: Config) -> None: + _pytest_embedded = config.stash.get(_idf_pytest_embedded_key, None) + if _pytest_embedded: + del config.stash[_idf_pytest_embedded_key] + config.pluginmanager.unregister(_pytest_embedded) + + +class IdfPytestEmbedded: + def __init__( + self, + target: Optional[str] = None, + env_name: Optional[str] = None, + ): + # CLI options to filter the test cases + self.target = target + self.env_name = env_name + + self._failed_cases: List[ + Tuple[str, bool, bool] + ] = [] # (test_case_name, is_known_failure_cases, is_xfail) + + @pytest.hookimpl(tryfirst=True) + def pytest_sessionstart(self, session: Session) -> None: + if self.target: + self.target = self.target.lower() + session.config.option.target = self.target + + # @pytest.hookimpl(tryfirst=True) + def pytest_collection_modifyitems(self, items: List[Function]) -> None: + # set default timeout 10 minutes for each case + for item in items: + # default timeout 5 mins + if 'timeout' not in item.keywords: + item.add_marker(pytest.mark.timeout(5 * 60)) + + # filter all the test cases with "--target" + if self.target: + def item_targets(item): return [m.args[0] for m in item.iter_markers(name='target')] + items[:] = [item for item in items if self.target in item_targets(item)] + + # filter all the test cases with "--env" + if self.env_name: + def item_envs(item): return [m.args[0] for m in item.iter_markers(name='env')] + items[:] = [item for item in items if self.env_name in item_envs(item)] diff --git a/examples/.build-rules.yml b/examples/.build-rules.yml new file mode 100644 index 000000000..bab506bb9 --- /dev/null +++ b/examples/.build-rules.yml @@ -0,0 +1,129 @@ +# Note: All operators are binary operators. For more than two operands, you may use the nested parentheses trick. +# For example: +# * A == 1 or (B == 2 and C in [1,2,3]) +# * (A == 1 and B == 2) or (C not in ["3", "4", 5]) + +examples/audio/wav_player: + enable: + - if: INCLUDE_DEFAULT == 1 + +examples/bluetooth/ble_ota: + enable: + - if: IDF_TARGET in ["esp32","esp32s3","esp32c3"] + +examples/camera/basic: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] + +examples/camera/pic_server: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] + +examples/camera/pic_server: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] + +examples/camera/test_framerate: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] + +examples/camera/video_recorder: + enable: + - if: IDF_TARGET == "esp32s3" + +examples/camera/video_stream_server: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] and (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) + +examples/check_pedestrian_flow: + enable: + - if: IDF_TARGET in ["esp32","esp32s2","esp32s3","esp32c3"] + +examples/extended_vfs/gpio/gpio_simple: + enable: + - if: IDF_TARGET in ["esp32","esp32s2","esp32s3","esp32c3"] + +examples/extended_vfs/i2c/i2c_bh1750: + enable: + - if: INCLUDE_DEFAULT == 1 + +examples/extended_vfs/i2c/i2c_tt21100: + enable: + - if: INCLUDE_DEFAULT == 1 + +examples/extended_vfs/ledc/ledc_simple: + enable: + - if: INCLUDE_DEFAULT == 1 + +examples/extended_vfs/spi/spi_master_simple: + enable: + - if: IDF_TARGET in ["esp32","esp32s2","esp32s3","esp32c3"] + +examples/extended_vfs/spi/spi_slave_simple: + enable: + - if: IDF_TARGET in ["esp32","esp32s2","esp32s3","esp32c3"] + +examples/get-started/blink: + enable: + - if: (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) and IDF_TARGET in ["esp32","esp32s2","esp32s3"] + +examples/hmi/lvgl_coffee: + enable: + - if: (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) and IDF_TARGET == "esp32" + +examples/hmi/lvgl_example: + enable: + - if: (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) and IDF_TARGET == "esp32" + +examples/hmi/lvgl_thermostat: + enable: + - if: (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) and IDF_TARGET == "esp32" + +examples/hmi/lvgl_wificonfig: + enable: + - if: (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) and IDF_TARGET == "esp32" + +examples/lighting/lightbulb: + enable: + - if: INCLUDE_DEFAULT == 1 + +examples/ota/simple_ota_example: + enable: + - if: INCLUDE_DEFAULT in ["esp32c2","esp32c3","es32"] and (IDF_VERSION_MAJOR == 5 and IDF_VERSION_MINOR == 0) + - if: INCLUDE_DEFAULT in ["esp32c2","esp32c3","es32","esp32c6"] and (IDF_VERSION_MAJOR == 5 and IDF_VERSION_MINOR == 1) + +examples/screen: + enable: + - if: IDF_TARGET == "esp32" and (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) + +examples/sensors/sensor_control_led: + enable: + - if: IDF_TARGET in ["esp32","esp32s2"] and (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) + +examples/sensors/sensor_hub_monitor: + enable: + - if: IDF_TARGET in ["esp32","esp32s2"] and (IDF_VERSION_MAJOR == 4 and IDF_VERSION_MINOR == 4) + +examples/usb/device/usb_msc_wireless_disk: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] and (IDF_VERSION_MAJOR == 5 and IDF_VERSION_MINOR == 0) + +examples/usb/device/usb_surface_dial: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] + +examples/usb/host/usb_camera_lcd_display: + enable: + - if: IDF_TARGET == "esp32s3" and (IDF_VERSION_MAJOR == 5 and IDF_VERSION_MINOR == 0) + +examples/usb/host/usb_camera_mic_spk: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] + +examples/usb/host/usb_cdc_4g_module: + enable: + - if: IDF_TARGET in ["esp32s2","esp32s3"] + +examples/utilities/xz_decompress_file: + enable: + - if: INCLUDE_DEFAULT == 1 \ No newline at end of file diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..8026cc74b --- /dev/null +++ b/pytest.ini @@ -0,0 +1,42 @@ +[pytest] +# exclude examples/ota/simple_ota_example/pytest_simple_ota.py +norecursedirs = examples/ota/* +# only the files with prefix `pytest_` would be recognized as pytest test scripts. +python_files = pytest_*.py + +# set traceback to "short" to prevent the overwhelming tracebacks +addopts = + -s + --embedded-services esp,idf + --tb short + --skip-check-coredump y + +# ignore PytestExperimentalApiWarning for record_xml_attribute +filterwarnings = + ignore::_pytest.warning_types.PytestExperimentalApiWarning + + +markers = + # target markers + target: target chip name (--target) + # env markers + env: target test env name (--env) + # config markers + config: choose specific bins built by `sdkconfig.ci.` + # app_path markers + app_path: choose specific app_path, [/build_xxx] + + +# log related +log_cli = True +log_cli_level = INFO +log_cli_format = %(asctime)s %(levelname)s %(message)s +log_cli_date_format = %Y-%m-%d %H:%M:%S + +# junit related +junit_family = xunit1 + + +## log all to `system-out` when case fail +junit_logging = stdout +junit_log_passing_tests = False diff --git a/tools/build_apps.py b/tools/build_apps.py new file mode 100644 index 000000000..38fc9b677 --- /dev/null +++ b/tools/build_apps.py @@ -0,0 +1,149 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: Apache-2.0 + +""" +This file is used in CI generate binary files for different kinds of apps +""" + +import argparse +import sys +import os +import re +from pathlib import Path +from typing import List + +from idf_build_apps import LOGGER, App, build_apps, find_apps, setup_logging + +PROJECT_ROOT = Path(__file__).parent.parent.absolute() +APPS_BUILD_PER_JOB = 30 +IGNORE_WARNINGS = [ + r'1/2 app partitions are too small', + r'This clock source will be affected by the DFS of the power management', + r'The current IDF version does not support using the gptimer API', +] + +def _get_idf_version(): + if os.environ.get('IDF_VERSION'): + return os.environ.get('IDF_VERSION') + version_path = os.path.join(os.environ['IDF_PATH'], 'tools/cmake/version.cmake') + regex = re.compile(r'^\s*set\s*\(\s*IDF_VERSION_([A-Z]{5})\s+(\d+)') + ver = {} + with open(version_path) as f: + for line in f: + m = regex.match(line) + if m: + ver[m.group(1)] = m.group(2) + return '{}.{}'.format(int(ver['MAJOR']), int(ver['MINOR'])) + +def get_cmake_apps( + paths, + target, + config_rules_str, + default_build_targets, +): # type: (List[str], str, List[str]) -> List[App] + idf_ver = _get_idf_version() + apps = find_apps( + paths, + recursive=True, + target=target, + build_dir=f'{idf_ver}/build_@t_@w', + config_rules_str=config_rules_str, + build_log_path='build_log.txt', + size_json_path='size.json', + check_warnings=True, + preserve=True, + default_build_targets=default_build_targets, + manifest_files=[ + str(Path(PROJECT_ROOT) /'components'/'.build-rules.yml'), + str(Path(PROJECT_ROOT) /'examples'/'.build-rules.yml'), + ], + ) + return apps + + +def main(args): # type: (argparse.Namespace) -> None + default_build_targets = args.default_build_targets.split(',') if args.default_build_targets else None + apps = get_cmake_apps(args.paths, args.target, args.config, default_build_targets) + if args.exclude_apps: + apps_to_build = [app for app in apps if app.name not in args.exclude_apps] + else: + apps_to_build = apps[:] + + LOGGER.info('Found %d apps after filtering', len(apps_to_build)) + LOGGER.info( + 'Suggest setting the parallel count to %d for this build job', + len(apps_to_build) // APPS_BUILD_PER_JOB + 1, + ) + + ret_code = build_apps( + apps_to_build, + parallel_count=args.parallel_count, + parallel_index=args.parallel_index, + dry_run=False, + collect_size_info=args.collect_size_info, + keep_going=True, + ignore_warning_strs=IGNORE_WARNINGS, + copy_sdkconfig=True, + ) + + sys.exit(ret_code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='Build all the apps for different test types. Will auto remove those non-test apps binaries', + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument('paths', nargs='*', help='Paths to the apps to build.') + parser.add_argument( + '-t', '--target', + default='all', + help='Build apps for given target. could pass "all" to get apps for all targets', + ) + parser.add_argument( + '--config', + default=['sdkconfig.ci=default', 'sdkconfig.ci.*=', '=default'], + action='append', + help='Adds configurations (sdkconfig file names) to build. This can either be ' + 'FILENAME[=NAME] or FILEPATTERN. FILENAME is the name of the sdkconfig file, ' + 'relative to the project directory, to be used. Optional NAME can be specified, ' + 'which can be used as a name of this configuration. FILEPATTERN is the name of ' + 'the sdkconfig file, relative to the project directory, with at most one wildcard. ' + 'The part captured by the wildcard is used as the name of the configuration.', + ) + parser.add_argument( + '--parallel-count', default=1, type=int, help='Number of parallel build jobs.' + ) + parser.add_argument( + '--parallel-index', + default=1, + type=int, + help='Index (1-based) of the job, out of the number specified by --parallel-count.', + ) + parser.add_argument( + '--collect-size-info', + type=argparse.FileType('w'), + help='If specified, the test case name and size info json will be written to this file', + ) + parser.add_argument( + '--exclude-apps', + nargs='*', + help='Exclude build apps', + ) + parser.add_argument( + '--default-build-targets', + default=None, + help='default build targets used in manifest files', + ) + parser.add_argument( + '-v', '--verbose', + action='count', default=0, + help='Show verbose log message', + ) + + arguments = parser.parse_args() + if not arguments.paths: + arguments.paths = [PROJECT_ROOT] + setup_logging(verbose=arguments.verbose) # Info + main(arguments) diff --git a/tools/requirements/requirement.pytest.txt b/tools/requirements/requirement.pytest.txt new file mode 100644 index 000000000..8c259742b --- /dev/null +++ b/tools/requirements/requirement.pytest.txt @@ -0,0 +1,5 @@ +pytest +pytest-embedded-idf +pytest-embedded-serial-esp +pytest-rerunfailures +pytest-timeout