Browse Source

Migrate "loadable elf" test from hello_world example to test_apps

Roland Dobai 5 năm trước cách đây
mục cha
commit
2d709c6384

+ 8 - 2
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

+ 5 - 3
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

+ 29 - 29
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

+ 1 - 1
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
 

+ 0 - 0
examples/get-started/hello_world/.gdbinit.ci → tools/test_apps/system/gdb_loadable_elf/.gdbinit.ci


+ 6 - 0
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)

+ 3 - 0
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.

+ 8 - 7
examples/get-started/hello_world/loadable_elf_example_test.py → 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()

+ 2 - 0
tools/test_apps/system/gdb_loadable_elf/main/CMakeLists.txt

@@ -0,0 +1,2 @@
+idf_component_register(SRCS "hello_world_main.c"
+                    INCLUDE_DIRS "")

+ 43 - 0
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 <stdio.h>
+#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();
+}

+ 0 - 0
examples/get-started/hello_world/sdkconfig.ci → tools/test_apps/system/gdb_loadable_elf/sdkconfig.ci.default