From bffcea09dfb2f77517fed0b0baa3f8c4da6c2162 Mon Sep 17 00:00:00 2001 From: He Yin Ling Date: Thu, 26 Jul 2018 15:07:32 +0800 Subject: [PATCH] CI: erase nvs partition before test: Latest NVS partition bin can't be parsed by old IDF revision. Need to erase before test. --- tools/tiny-test-fw/IDF/IDFDUT.py | 54 +++++++++++++++++++++++------- tools/tiny-test-fw/IDF/__init__.py | 38 ++++++++++++++++++--- tools/unit-test-app/unit_test.py | 9 ++--- 3 files changed, 79 insertions(+), 22 deletions(-) diff --git a/tools/tiny-test-fw/IDF/IDFDUT.py b/tools/tiny-test-fw/IDF/IDFDUT.py index 8f870fec8..28ea4867c 100644 --- a/tools/tiny-test-fw/IDF/IDFDUT.py +++ b/tools/tiny-test-fw/IDF/IDFDUT.py @@ -18,7 +18,9 @@ import sys import re import subprocess import functools -import serial +import random +import tempfile + from serial.tools import list_ports import DUT @@ -46,6 +48,8 @@ class IDFDUT(DUT.SerialDUT): # /dev/ttyAMA0 port is listed in Raspberry Pi # /dev/tty.Bluetooth-Incoming-Port port is listed in Mac INVALID_PORT_PATTERN = re.compile(r"AMA|Bluetooth") + # if need to erase NVS partition in start app + ERASE_NVS = True def __init__(self, name, port, log_file, app, **kwargs): self.download_config, self.partition_table = app.process_app_info() @@ -74,24 +78,39 @@ class IDFDUT(DUT.SerialDUT): return cls.get_chip(app, port) is not None @_tool_method - def start_app(self): + def start_app(self, erase_nvs=ERASE_NVS): """ download and start app. + :param: erase_nvs: whether erase NVS partition during flash :return: None """ + if erase_nvs: + address = self.partition_table["nvs"]["offset"] + size = self.partition_table["nvs"]["size"] + nvs_file = tempfile.NamedTemporaryFile() + nvs_file.write(chr(0xFF) * size) + nvs_file.flush() + download_config = self.download_config + [address, nvs_file.name] + else: + download_config = self.download_config + retry_baud_rates = ["921600", "115200"] error = IDFToolError() - for baud_rate in retry_baud_rates: - try: - subprocess.check_output(["python", self.app.esptool, - "--port", self.port, "--baud", baud_rate] - + self.download_config) - break - except subprocess.CalledProcessError as error: - continue - else: - raise error + try: + for baud_rate in retry_baud_rates: + try: + subprocess.check_output(["python", self.app.esptool, + "--port", self.port, "--baud", baud_rate] + + download_config) + break + except subprocess.CalledProcessError as error: + continue + else: + raise error + finally: + if erase_nvs: + nvs_file.close() @_tool_method def reset(self): @@ -102,6 +121,17 @@ class IDFDUT(DUT.SerialDUT): """ subprocess.check_output(["python", self.app.esptool, "--port", self.port, "run"]) + @_tool_method + def erase_partition(self, partition): + """ + :param partition: partition name to erase + :return: None + """ + address = self.partition_table[partition]["offset"] + size = self.partition_table[partition]["size"] + with open(".erase_partition.tmp", "wb") as f: + f.write(chr(0xFF) * size) + @_tool_method def dump_flush(self, output_file, **kwargs): """ diff --git a/tools/tiny-test-fw/IDF/__init__.py b/tools/tiny-test-fw/IDF/__init__.py index fad52f41b..c7480c43f 100644 --- a/tools/tiny-test-fw/IDF/__init__.py +++ b/tools/tiny-test-fw/IDF/__init__.py @@ -20,9 +20,8 @@ from IDF.IDFApp import IDFApp, Example, UT from IDF.IDFDUT import IDFDUT -def idf_example_test(app=Example, dut=IDFDUT, chip="ESP32", - module="examples", execution_time=1, level="example", - **kwargs): +def idf_example_test(app=Example, dut=IDFDUT, chip="ESP32", module="examples", execution_time=1, + level="example", erase_nvs=True, **kwargs): """ decorator for testing idf examples (with default values for some keyword args). @@ -32,10 +31,41 @@ def idf_example_test(app=Example, dut=IDFDUT, chip="ESP32", :param module: module, string :param execution_time: execution time in minutes, int :param level: test level, could be used to filter test cases, string + :param erase_nvs: if need to erase_nvs in DUT.start_app() :param kwargs: other keyword args :return: test method """ - # not use partial function as define as function support auto generating document + try: + # try to config the default behavior of erase nvs + dut.ERASE_NVS = erase_nvs + except AttributeError: + pass + + return TinyFW.test_method(app=app, dut=dut, chip=chip, module=module, + execution_time=execution_time, level=level, **kwargs) + + +def idf_unit_test(app=UT, dut=IDFDUT, chip="ESP32", module="unit-test", execution_time=1, + level="unit", erase_nvs=True, **kwargs): + """ + decorator for testing idf unit tests (with default values for some keyword args). + + :param app: test application class + :param dut: dut class + :param chip: chip supported, string or tuple + :param module: module, string + :param execution_time: execution time in minutes, int + :param level: test level, could be used to filter test cases, string + :param erase_nvs: if need to erase_nvs in DUT.start_app() + :param kwargs: other keyword args + :return: test method + """ + try: + # try to config the default behavior of erase nvs + dut.ERASE_NVS = erase_nvs + except AttributeError: + pass + return TinyFW.test_method(app=app, dut=dut, chip=chip, module=module, execution_time=execution_time, level=level, **kwargs) diff --git a/tools/unit-test-app/unit_test.py b/tools/unit-test-app/unit_test.py index e0e265709..4ce625af3 100644 --- a/tools/unit-test-app/unit_test.py +++ b/tools/unit-test-app/unit_test.py @@ -105,8 +105,7 @@ def format_test_case_config(test_case_data): return case_config -@TinyFW.test_method(app=UT, dut=IDF.IDFDUT, chip="ESP32", module="unit_test", - execution_time=1, env_tag="UT_T1_1") +@IDF.idf_unit_test(env_tag="UT_T1_1") def run_unit_test_cases(env, extra_data): """ extra_data can be three types of value @@ -347,8 +346,7 @@ def case_run(duts, ut_config, env, one_case, failed_cases): Utility.console_log("Failed: " + one_case["name"], color="red") -@TinyFW.test_method(app=UT, dut=IDF.IDFDUT, chip="ESP32", module="master_slave_test_case", execution_time=1, - env_tag="UT_T2_1") +@IDF.idf_unit_test(env_tag="UT_T2_1") def run_multiple_devices_cases(env, extra_data): """ extra_data can be two types of value @@ -385,8 +383,7 @@ def run_multiple_devices_cases(env, extra_data): raise AssertionError("Unit Test Failed") -@TinyFW.test_method(app=UT, dut=IDF.IDFDUT, chip="ESP32", module="unit_test", - execution_time=1, env_tag="UT_T1_1") +@IDF.idf_unit_test(env_tag="UT_T1_1") def run_multiple_stage_cases(env, extra_data): """ extra_data can be 2 types of value