Merge branch 'test/enhanced_unit_test_config_dependency' into 'master'
test: enhanced config dependency support for CI See merge request idf/esp-idf!3383
This commit is contained in:
commit
ee0ebc1e1a
1 changed files with 53 additions and 8 deletions
|
@ -4,7 +4,6 @@ import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import hashlib
|
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
import CreateSectionTable
|
import CreateSectionTable
|
||||||
|
@ -31,6 +30,7 @@ class Parser(object):
|
||||||
|
|
||||||
TAG_PATTERN = re.compile("([^=]+)(=)?(.+)?")
|
TAG_PATTERN = re.compile("([^=]+)(=)?(.+)?")
|
||||||
DESCRIPTION_PATTERN = re.compile("\[([^]\[]+)\]")
|
DESCRIPTION_PATTERN = re.compile("\[([^]\[]+)\]")
|
||||||
|
CONFIG_PATTERN = re.compile(r"{([^}]+)}")
|
||||||
|
|
||||||
# file path (relative to idf path)
|
# file path (relative to idf path)
|
||||||
TAG_DEF_FILE = os.path.join("tools", "unit-test-app", "tools", "TagDefinition.yml")
|
TAG_DEF_FILE = os.path.join("tools", "unit-test-app", "tools", "TagDefinition.yml")
|
||||||
|
@ -49,7 +49,7 @@ class Parser(object):
|
||||||
self.idf_path = idf_path
|
self.idf_path = idf_path
|
||||||
self.tag_def = yaml.load(open(os.path.join(idf_path, self.TAG_DEF_FILE), "r"))
|
self.tag_def = yaml.load(open(os.path.join(idf_path, self.TAG_DEF_FILE), "r"))
|
||||||
self.module_map = yaml.load(open(os.path.join(idf_path, self.MODULE_DEF_FILE), "r"))
|
self.module_map = yaml.load(open(os.path.join(idf_path, self.MODULE_DEF_FILE), "r"))
|
||||||
self.config_dependency = yaml.load(open(os.path.join(idf_path, self.CONFIG_DEPENDENCY_FILE), "r"))
|
self.config_dependencies = yaml.load(open(os.path.join(idf_path, self.CONFIG_DEPENDENCY_FILE), "r"))
|
||||||
# used to check if duplicated test case names
|
# used to check if duplicated test case names
|
||||||
self.test_case_names = set()
|
self.test_case_names = set()
|
||||||
self.parsing_errors = []
|
self.parsing_errors = []
|
||||||
|
@ -150,23 +150,56 @@ class Parser(object):
|
||||||
pass
|
pass
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_tags_internal(sdkconfig, config_dependencies, config_pattern):
|
||||||
|
required_tags = []
|
||||||
|
|
||||||
|
def compare_config(config):
|
||||||
|
return config in sdkconfig
|
||||||
|
|
||||||
|
def process_condition(condition):
|
||||||
|
matches = config_pattern.findall(condition)
|
||||||
|
if matches:
|
||||||
|
for config in matches:
|
||||||
|
compare_result = compare_config(config)
|
||||||
|
# replace all configs in condition with True or False according to compare result
|
||||||
|
condition = re.sub(config_pattern, str(compare_result), condition, count=1)
|
||||||
|
# Now the condition is a python condition, we can use eval to compute its value
|
||||||
|
ret = eval(condition)
|
||||||
|
else:
|
||||||
|
# didn't use complex condition. only defined one condition for the tag
|
||||||
|
ret = compare_config(condition)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
for tag in config_dependencies:
|
||||||
|
if process_condition(config_dependencies[tag]):
|
||||||
|
required_tags.append(tag)
|
||||||
|
|
||||||
|
return required_tags
|
||||||
|
|
||||||
def parse_tags(self, sdkconfig_file):
|
def parse_tags(self, sdkconfig_file):
|
||||||
"""
|
"""
|
||||||
Some test configs could requires different DUTs.
|
Some test configs could requires different DUTs.
|
||||||
For example, if CONFIG_SPIRAM_SUPPORT is enabled, we need WROVER-Kit to run test.
|
For example, if CONFIG_SPIRAM_SUPPORT is enabled, we need WROVER-Kit to run test.
|
||||||
This method will get tags for runners according to ConfigDependency.yml(maps tags to sdkconfig).
|
This method will get tags for runners according to ConfigDependency.yml(maps tags to sdkconfig).
|
||||||
|
|
||||||
:param sdkconfig_file: sdkconfig file of the unit test config
|
We support to the following syntax::
|
||||||
|
|
||||||
|
# define the config which requires the tag
|
||||||
|
'tag_a': 'config_a="value_a"'
|
||||||
|
# define the condition for the tag
|
||||||
|
'tag_b': '{config A} and (not {config B} or (not {config C} and {config D}))'
|
||||||
|
|
||||||
|
:param sdkconfig_file: sdk config file of the unit test config
|
||||||
:return: required tags for runners
|
:return: required tags for runners
|
||||||
"""
|
"""
|
||||||
required_tags = []
|
|
||||||
with open(sdkconfig_file, "r") as f:
|
with open(sdkconfig_file, "r") as f:
|
||||||
configs_raw_data = f.read()
|
configs_raw_data = f.read()
|
||||||
|
|
||||||
configs = configs_raw_data.splitlines(False)
|
configs = configs_raw_data.splitlines(False)
|
||||||
for tag in self.config_dependency:
|
|
||||||
if self.config_dependency[tag] in configs:
|
return self.parse_tags_internal(configs, self.config_dependencies, self.CONFIG_PATTERN)
|
||||||
required_tags.append(tag)
|
|
||||||
return required_tags
|
|
||||||
|
|
||||||
def parse_one_test_case(self, name, description, file_name, config_name, tags):
|
def parse_one_test_case(self, name, description, file_name, config_name, tags):
|
||||||
"""
|
"""
|
||||||
|
@ -254,6 +287,18 @@ def test_parser():
|
||||||
prop = parser.parse_case_properities("[esp32][[ignore=b]][]][test_env=AAA]]")
|
prop = parser.parse_case_properities("[esp32][[ignore=b]][]][test_env=AAA]]")
|
||||||
assert prop["module"] == "esp32" and prop["ignore"] == "b" and prop["test_env"] == "AAA"
|
assert prop["module"] == "esp32" and prop["ignore"] == "b" and prop["test_env"] == "AAA"
|
||||||
|
|
||||||
|
config_dependency = {
|
||||||
|
'a': '123',
|
||||||
|
'b': '456',
|
||||||
|
'c': 'not {123}',
|
||||||
|
'd': '{123} and not {456}',
|
||||||
|
'e': '{123} and not {789}',
|
||||||
|
'f': '({123} and {456}) or ({123} and {789})'
|
||||||
|
}
|
||||||
|
sdkconfig = ["123", "789"]
|
||||||
|
tags = parser.parse_tags_internal(sdkconfig, config_dependency, parser.CONFIG_PATTERN)
|
||||||
|
assert tags == ['a', 'd', 'f']
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
test_parser()
|
test_parser()
|
||||||
|
|
Loading…
Reference in a new issue