|
|
@@ -24,12 +24,17 @@ except ImportError:
|
|
|
|
|
|
|
|
|
class Group(CIAssignTest.Group):
|
|
|
- SORT_KEYS = ["config", "test environment", "multi_device", "multi_stage", "tags", "chip_target"]
|
|
|
- MAX_CASE = 30
|
|
|
+ SORT_KEYS = ["test environment", "tags", "chip_target"]
|
|
|
+ MAX_CASE = 50
|
|
|
ATTR_CONVERT_TABLE = {
|
|
|
"execution_time": "execution time"
|
|
|
}
|
|
|
CI_JOB_MATCH_KEYS = ["test environment"]
|
|
|
+ DUT_CLS_NAME = {
|
|
|
+ "esp32": "ESP32DUT",
|
|
|
+ "esp32s2beta": "ESP32S2DUT",
|
|
|
+ "esp8266": "ESP8266DUT",
|
|
|
+ }
|
|
|
|
|
|
def __init__(self, case):
|
|
|
super(Group, self).__init__(case)
|
|
|
@@ -42,13 +47,28 @@ class Group(CIAssignTest.Group):
|
|
|
attr = Group.ATTR_CONVERT_TABLE[attr]
|
|
|
return case[attr]
|
|
|
|
|
|
- def _create_extra_data(self, test_function):
|
|
|
+ def add_extra_case(self, case):
|
|
|
+ """ If current group contains all tags required by case, then add succeed """
|
|
|
+ added = False
|
|
|
+ if self.accept_new_case():
|
|
|
+ for key in self.filters:
|
|
|
+ if self._get_case_attr(case, key) != self.filters[key]:
|
|
|
+ if key == "tags":
|
|
|
+ if self._get_case_attr(case, key).issubset(self.filters[key]):
|
|
|
+ continue
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ self.case_list.append(case)
|
|
|
+ added = True
|
|
|
+ return added
|
|
|
+
|
|
|
+ def _create_extra_data(self, test_cases, test_function):
|
|
|
"""
|
|
|
For unit test case, we need to copy some attributes of test cases into config file.
|
|
|
So unit test function knows how to run the case.
|
|
|
"""
|
|
|
case_data = []
|
|
|
- for case in self.case_list:
|
|
|
+ for case in test_cases:
|
|
|
one_case_data = {
|
|
|
"config": self._get_case_attr(case, "config"),
|
|
|
"name": self._get_case_attr(case, "summary"),
|
|
|
@@ -67,19 +87,26 @@ class Group(CIAssignTest.Group):
|
|
|
case_data.append(one_case_data)
|
|
|
return case_data
|
|
|
|
|
|
- def _map_test_function(self):
|
|
|
+ def _divide_case_by_test_function(self):
|
|
|
"""
|
|
|
- determine which test function to use according to current test case
|
|
|
+ divide cases of current test group by test function they need to use
|
|
|
|
|
|
- :return: test function name to use
|
|
|
+ :return: dict of list of cases for each test functions
|
|
|
"""
|
|
|
- if self.filters["multi_device"] == "Yes":
|
|
|
- test_function = "run_multiple_devices_cases"
|
|
|
- elif self.filters["multi_stage"] == "Yes":
|
|
|
- test_function = "run_multiple_stage_cases"
|
|
|
- else:
|
|
|
- test_function = "run_unit_test_cases"
|
|
|
- return test_function
|
|
|
+ case_by_test_function = {
|
|
|
+ "run_multiple_devices_cases": [],
|
|
|
+ "run_multiple_stage_cases": [],
|
|
|
+ "run_unit_test_cases": [],
|
|
|
+ }
|
|
|
+
|
|
|
+ for case in self.case_list:
|
|
|
+ if case["multi_device"] == "Yes":
|
|
|
+ case_by_test_function["run_multiple_devices_cases"].append(case)
|
|
|
+ elif case["multi_stage"] == "Yes":
|
|
|
+ case_by_test_function["run_multiple_stage_cases"].append(case)
|
|
|
+ else:
|
|
|
+ case_by_test_function["run_unit_test_cases"].append(case)
|
|
|
+ return case_by_test_function
|
|
|
|
|
|
def output(self):
|
|
|
"""
|
|
|
@@ -87,35 +114,30 @@ class Group(CIAssignTest.Group):
|
|
|
|
|
|
:return: {"Filter": case filter, "CaseConfig": list of case configs for cases in this group}
|
|
|
"""
|
|
|
- test_function = self._map_test_function()
|
|
|
+
|
|
|
+ target = self._get_case_attr(self.case_list[0], "chip_target")
|
|
|
+ if target:
|
|
|
+ overwrite = {
|
|
|
+ "dut": {
|
|
|
+ "path": "IDF/IDFDUT.py",
|
|
|
+ "class": self.DUT_CLS_NAME[target],
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else:
|
|
|
+ overwrite = dict()
|
|
|
+
|
|
|
+ case_by_test_function = self._divide_case_by_test_function()
|
|
|
|
|
|
output_data = {
|
|
|
# we don't need filter for test function, as UT uses a few test functions for all cases
|
|
|
"CaseConfig": [
|
|
|
{
|
|
|
"name": test_function,
|
|
|
- "extra_data": self._create_extra_data(test_function),
|
|
|
- }
|
|
|
+ "extra_data": self._create_extra_data(test_cases, test_function),
|
|
|
+ "overwrite": overwrite,
|
|
|
+ } for test_function, test_cases in case_by_test_function.iteritems() if test_cases
|
|
|
],
|
|
|
}
|
|
|
-
|
|
|
- target = self._get_case_attr(self.case_list[0], "chip_target")
|
|
|
- if target is not None:
|
|
|
- target_dut = {
|
|
|
- "esp32": "ESP32DUT",
|
|
|
- "esp32s2beta": "ESP32S2DUT",
|
|
|
- "esp8266": "ESP8266DUT",
|
|
|
- }[target]
|
|
|
- output_data.update({
|
|
|
- "Filter": {
|
|
|
- "overwrite": {
|
|
|
- "dut": {
|
|
|
- "path": "IDF/IDFDUT.py",
|
|
|
- "class": target_dut,
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
return output_data
|
|
|
|
|
|
|
|
|
@@ -135,6 +157,8 @@ class UnitTestAssignTest(CIAssignTest.AssignTest):
|
|
|
with open(test_case_path, "r") as f:
|
|
|
raw_data = yaml.load(f, Loader=Loader)
|
|
|
test_cases = raw_data["test cases"]
|
|
|
+ for case in test_cases:
|
|
|
+ case["tags"] = set(case["tags"])
|
|
|
except IOError:
|
|
|
print("Test case path is invalid. Should only happen when use @bot to skip unit test.")
|
|
|
test_cases = []
|
|
|
@@ -160,6 +184,10 @@ class UnitTestAssignTest(CIAssignTest.AssignTest):
|
|
|
# case don't have this key, regard as filter success
|
|
|
filtered_cases.append(case)
|
|
|
test_cases = filtered_cases
|
|
|
+ # sort cases with configs and test functions
|
|
|
+ # in later stage cases with similar attributes are more likely to be assigned to the same job
|
|
|
+ # it will reduce the count of flash DUT operations
|
|
|
+ test_cases.sort(key=lambda x: x["config"] + x["multi_stage"] + x["multi_device"])
|
|
|
return test_cases
|
|
|
|
|
|
|