Migrate "loadable elf" test from hello_world example to test_apps

This commit is contained in:
Roland Dobai 2020-04-16 14:42:33 +02:00
parent 819f7a4e57
commit 2d709c6384
11 changed files with 105 additions and 42 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,3 @@
# Loadable ELF test application
This project tests if the application can be loaded with GDB.

View file

@ -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()

View file

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

View file

@ -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();
}