CIAssignUnitTest.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. """
  2. Command line tool to assign unit tests to CI test jobs.
  3. """
  4. import re
  5. import os
  6. import sys
  7. import argparse
  8. import yaml
  9. test_fw_path = os.getenv("TEST_FW_PATH")
  10. if test_fw_path:
  11. sys.path.insert(0, test_fw_path)
  12. from Utility import CIAssignTest
  13. class Group(CIAssignTest.Group):
  14. SORT_KEYS = ["Test App", "SDK", "test environment"]
  15. MAX_CASE = 30
  16. ATTR_CONVERT_TABLE = {
  17. "execution_time": "execution time"
  18. }
  19. @staticmethod
  20. def _get_case_attr(case, attr):
  21. if attr in Group.ATTR_CONVERT_TABLE:
  22. attr = Group.ATTR_CONVERT_TABLE[attr]
  23. return case[attr]
  24. @staticmethod
  25. def _get_ut_config(test_app):
  26. # we format test app "UT_ + config" when parsing test cases
  27. # now we need to extract config
  28. assert test_app[:3] == "UT_"
  29. return test_app[3:]
  30. def _create_extra_data(self):
  31. case_data = []
  32. for case in self.case_list:
  33. if self._get_case_attr(case, "cmd set") == "multiple_devices_case":
  34. case_data.append({
  35. "config": self._get_ut_config(self._get_case_attr(case, "Test App")),
  36. "name": self._get_case_attr(case, "summary"),
  37. "child case num": self._get_case_attr(case, "child case num")
  38. })
  39. else:
  40. case_data.append({
  41. "config": self._get_ut_config(self._get_case_attr(case, "Test App")),
  42. "name": self._get_case_attr(case, "summary"),
  43. "reset": self._get_case_attr(case, "reset") ,
  44. })
  45. return case_data
  46. def output(self):
  47. """
  48. output data for job configs
  49. :return: {"Filter": case filter, "CaseConfig": list of case configs for cases in this group}
  50. """
  51. output_data = {
  52. # we don't need filter for test function, as UT uses a few test functions for all cases
  53. "CaseConfig": [
  54. {
  55. "name": self.case_list[0]["cmd set"] if isinstance(self.case_list[0]["cmd set"], str) else self.case_list[0]["cmd set"][0],
  56. "extra_data": self._create_extra_data(),
  57. }
  58. ]
  59. }
  60. return output_data
  61. class UnitTestAssignTest(CIAssignTest.AssignTest):
  62. CI_TEST_JOB_PATTERN = re.compile(r"^UT_.+")
  63. def __init__(self, test_case_path, ci_config_file):
  64. CIAssignTest.AssignTest.__init__(self, test_case_path, ci_config_file, case_group=Group)
  65. @staticmethod
  66. def _search_cases(test_case_path, case_filter=None):
  67. """
  68. For unit test case, we don't search for test functions.
  69. The unit test cases is stored in a yaml file which is created in job build-idf-test.
  70. """
  71. with open(test_case_path, "r") as f:
  72. raw_data = yaml.load(f)
  73. test_cases = raw_data["test cases"]
  74. if case_filter:
  75. for key in case_filter:
  76. filtered_cases = []
  77. for case in test_cases:
  78. try:
  79. # bot converts string to lower case
  80. if isinstance(case[key], str):
  81. _value = case[key].lower()
  82. else:
  83. _value = case[key]
  84. if _value in case_filter[key]:
  85. filtered_cases.append(case)
  86. except KeyError:
  87. # case don't have this key, regard as filter success
  88. filtered_cases.append(case)
  89. test_cases = filtered_cases
  90. return test_cases
  91. if __name__ == '__main__':
  92. parser = argparse.ArgumentParser()
  93. parser.add_argument("test_case",
  94. help="test case folder or file")
  95. parser.add_argument("ci_config_file",
  96. help="gitlab ci config file")
  97. parser.add_argument("output_path",
  98. help="output path of config files")
  99. args = parser.parse_args()
  100. assign_test = UnitTestAssignTest(args.test_case, args.ci_config_file)
  101. assign_test.assign_cases()
  102. assign_test.output_configs(args.output_path)