diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index b78e61ac77..13c59ffdfc 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -207,7 +207,7 @@ test_weekend_network: example_test_001A: extends: .example_test_template - parallel: 4 + parallel: 5 tags: - ESP32 - Example_WIFI @@ -290,7 +290,6 @@ example_test_009: artifacts: when: always paths: - - $CI_PROJECT_DIR/examples/get-started/hello_world/*.log - $CI_PROJECT_DIR/examples/storage/semihost_vfs/*.log expire_in: 1 week variables: @@ -307,6 +306,13 @@ test_app_test_001: tags: - ESP32 - test_jtag_arm + artifacts: + when: always + paths: + - $CI_PROJECT_DIR/tools/test_apps/system/gdb_loadable_elf/*.log + expire_in: 1 week + variables: + SETUP_TOOLS: "1" test_app_test_002: extends: .test_app_template diff --git a/tools/ci/python_packages/ttfw_idf/DebugUtils.py b/tools/ci/python_packages/ttfw_idf/DebugUtils.py index ff93ab521a..55fd6df89c 100644 --- a/tools/ci/python_packages/ttfw_idf/DebugUtils.py +++ b/tools/ci/python_packages/ttfw_idf/DebugUtils.py @@ -4,7 +4,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http:#www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals +from io import open from tiny_test_fw import Utility import pexpect @@ -19,10 +21,10 @@ import pexpect class CustomProcess(object): def __init__(self, cmd, logfile, verbose): self.verbose = verbose - self.f = open(logfile, 'wb') + self.f = open(logfile, 'w') if self.verbose: Utility.console_log('Starting {} > {}'.format(cmd, self.f.name)) - self.pexpect_proc = pexpect.spawn(cmd, timeout=60, logfile=self.f) + self.pexpect_proc = pexpect.spawn(cmd, timeout=60, logfile=self.f, encoding='utf-8') def __enter__(self): return self diff --git a/tools/ci/python_packages/ttfw_idf/IDFApp.py b/tools/ci/python_packages/ttfw_idf/IDFApp.py index e61455f9bb..461e667307 100644 --- a/tools/ci/python_packages/ttfw_idf/IDFApp.py +++ b/tools/ci/python_packages/ttfw_idf/IDFApp.py @@ -368,35 +368,6 @@ class Example(IDFApp): raise OSError("Failed to find example binary") -class LoadableElfExample(Example): - def __init__(self, app_path, app_files, config_name=None, target=None): - # add arg `app_files` for loadable elf example. - # Such examples only build elf files, so it doesn't generate flasher_args.json. - # So we can't get app files from config file. Test case should pass it to application. - super(IDFApp, self).__init__(app_path) - self.app_files = app_files - self.config_name = config_name - self.target = target - self.idf_path = self.get_sdk_path() - self.binary_path = self.get_binary_path(app_path, config_name, target) - self.elf_file = self._get_elf_file_path(self.binary_path) - assert os.path.exists(self.binary_path) - - def get_binary_path(self, app_path, config_name=None, target=None): - path = self._try_get_binary_from_local_fs(app_path, config_name, target) - if path: - return path - else: - artifacts = Artifacts(self.idf_path, - CIAssignExampleTest.get_artifact_index_file(case_group=CIAssignExampleTest.ExampleGroup), - app_path, config_name, target) - path = artifacts.download_artifact_files(self.app_files) - if path: - return os.path.join(self.idf_path, path) - else: - raise OSError("Failed to find example binary") - - class UT(IDFApp): def get_binary_path(self, app_path, config_name=None, target=None): if not config_name: @@ -437,6 +408,35 @@ class TestApp(Example): raise OSError("Failed to find example binary") +class LoadableElfTestApp(TestApp): + def __init__(self, app_path, app_files, config_name=None, target=None): + # add arg `app_files` for loadable elf test_app. + # Such examples only build elf files, so it doesn't generate flasher_args.json. + # So we can't get app files from config file. Test case should pass it to application. + super(IDFApp, self).__init__(app_path) + self.app_files = app_files + self.config_name = config_name + self.target = target + self.idf_path = self.get_sdk_path() + self.binary_path = self.get_binary_path(app_path, config_name, target) + self.elf_file = self._get_elf_file_path(self.binary_path) + assert os.path.exists(self.binary_path) + + def get_binary_path(self, app_path, config_name=None, target=None): + path = self._try_get_binary_from_local_fs(app_path, config_name, target, local_build_dir="build_test_apps") + if path: + return path + else: + artifacts = Artifacts(self.idf_path, + CIAssignExampleTest.get_artifact_index_file(case_group=CIAssignExampleTest.TestAppsGroup), + app_path, config_name, target) + path = artifacts.download_artifact_files(self.app_files) + if path: + return os.path.join(self.idf_path, path) + else: + raise OSError("Failed to find the loadable ELF file") + + class SSC(IDFApp): def get_binary_path(self, app_path, config_name=None, target=None): # TODO: to implement SSC get binary path diff --git a/tools/ci/python_packages/ttfw_idf/__init__.py b/tools/ci/python_packages/ttfw_idf/__init__.py index 8983b167ae..ccb90214e9 100644 --- a/tools/ci/python_packages/ttfw_idf/__init__.py +++ b/tools/ci/python_packages/ttfw_idf/__init__.py @@ -15,7 +15,7 @@ import os import re from tiny_test_fw import TinyFW, Utility -from .IDFApp import IDFApp, Example, LoadableElfExample, UT, TestApp # noqa: export all Apps for users +from .IDFApp import IDFApp, Example, LoadableElfTestApp, UT, TestApp # noqa: export all Apps for users from .IDFDUT import IDFDUT, ESP32DUT, ESP32S2DUT, ESP8266DUT, ESP32QEMUDUT # noqa: export DUTs for users from .DebugUtils import OCDProcess, GDBProcess # noqa: export DebugUtils for users diff --git a/examples/get-started/hello_world/.gdbinit.ci b/tools/test_apps/system/gdb_loadable_elf/.gdbinit.ci similarity index 100% rename from examples/get-started/hello_world/.gdbinit.ci rename to tools/test_apps/system/gdb_loadable_elf/.gdbinit.ci diff --git a/tools/test_apps/system/gdb_loadable_elf/CMakeLists.txt b/tools/test_apps/system/gdb_loadable_elf/CMakeLists.txt new file mode 100644 index 0000000000..ecbc92d435 --- /dev/null +++ b/tools/test_apps/system/gdb_loadable_elf/CMakeLists.txt @@ -0,0 +1,6 @@ +# 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) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(gdb_loadable_elf) diff --git a/tools/test_apps/system/gdb_loadable_elf/README.md b/tools/test_apps/system/gdb_loadable_elf/README.md new file mode 100644 index 0000000000..211a50c2f5 --- /dev/null +++ b/tools/test_apps/system/gdb_loadable_elf/README.md @@ -0,0 +1,3 @@ +# Loadable ELF test application + +This project tests if the application can be loaded with GDB. diff --git a/examples/get-started/hello_world/loadable_elf_example_test.py b/tools/test_apps/system/gdb_loadable_elf/app_test.py similarity index 84% rename from examples/get-started/hello_world/loadable_elf_example_test.py rename to tools/test_apps/system/gdb_loadable_elf/app_test.py index 8eca5690b2..126cf433d2 100644 --- a/examples/get-started/hello_world/loadable_elf_example_test.py +++ b/tools/test_apps/system/gdb_loadable_elf/app_test.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import os import threading import time @@ -33,15 +34,15 @@ class SerialThread(object): Utility.console_log('The pyserial thread is still alive', 'O') -@ttfw_idf.idf_example_test(env_tag="test_jtag_arm") -def test_examples_loadable_elf(env, extra_data): +@ttfw_idf.idf_custom_test(env_tag="test_jtag_arm", group="test-apps") +def test_app_loadable_elf(env, extra_data): - rel_project_path = os.path.join('examples', 'get-started', 'hello_world') - app_files = ['hello-world.elf', 'partition_table/partition-table.bin'] - example = ttfw_idf.LoadableElfExample(rel_project_path, app_files, target="esp32") + rel_project_path = os.path.join('tools', 'test_apps', 'system', 'gdb_loadable_elf') + app_files = ['gdb_loadable_elf.elf', 'partition_table/partition-table.bin'] + example = ttfw_idf.LoadableElfTestApp(rel_project_path, app_files, target="esp32") idf_path = example.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) - elf_path = os.path.join(example.binary_path, 'hello-world.elf') + elf_path = os.path.join(example.binary_path, 'gdb_loadable_elf.elf') esp_log_path = os.path.join(proj_path, 'esp.log') with SerialThread(esp_log_path): @@ -74,4 +75,4 @@ def test_examples_loadable_elf(env, extra_data): if __name__ == '__main__': - test_examples_loadable_elf() + test_app_loadable_elf() diff --git a/tools/test_apps/system/gdb_loadable_elf/main/CMakeLists.txt b/tools/test_apps/system/gdb_loadable_elf/main/CMakeLists.txt new file mode 100644 index 0000000000..07686dc8e1 --- /dev/null +++ b/tools/test_apps/system/gdb_loadable_elf/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "hello_world_main.c" + INCLUDE_DIRS "") diff --git a/tools/test_apps/system/gdb_loadable_elf/main/hello_world_main.c b/tools/test_apps/system/gdb_loadable_elf/main/hello_world_main.c new file mode 100644 index 0000000000..1bbb227906 --- /dev/null +++ b/tools/test_apps/system/gdb_loadable_elf/main/hello_world_main.c @@ -0,0 +1,43 @@ +/* Hello World Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_spi_flash.h" + +void app_main(void) +{ + printf("Hello world!\n"); + + /* Print chip information */ + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + printf("This is %s chip with %d CPU cores, WiFi%s%s, ", + CONFIG_IDF_TARGET, + chip_info.cores, + (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); + + printf("silicon revision %d, ", chip_info.revision); + + printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024), + (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); + + printf("Free heap: %d\n", esp_get_free_heap_size()); + + for (int i = 10; i >= 0; i--) { + printf("Restarting in %d seconds...\n", i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + printf("Restarting now.\n"); + fflush(stdout); + esp_restart(); +} diff --git a/examples/get-started/hello_world/sdkconfig.ci b/tools/test_apps/system/gdb_loadable_elf/sdkconfig.ci.default similarity index 100% rename from examples/get-started/hello_world/sdkconfig.ci rename to tools/test_apps/system/gdb_loadable_elf/sdkconfig.ci.default