UnitTestParser.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import yaml
  2. import os
  3. import re
  4. import sys
  5. import shutil
  6. MODULE_MAP = yaml.load(open("ModuleDefinition.yml", "r"))
  7. TEST_CASE_PATTERN = {
  8. "initial condition": "UTINIT1",
  9. "SDK": "ESP32_IDF",
  10. "level": "Unit",
  11. "execution time": 0,
  12. "Test App": "UT",
  13. "auto test": "Yes",
  14. "category": "Function",
  15. "test point 1": "basic function",
  16. "version": "v1 (2016-12-06)",
  17. "test environment": "UT_T1_1",
  18. "expected result": "1. set succeed"
  19. }
  20. CONFIG_FILE_PATTERN = {
  21. "Config": {"execute count": 1, "execute order": "in order"},
  22. "DUT": [],
  23. "Filter": [{"Add": {"ID": []}}]
  24. }
  25. test_cases = list()
  26. test_ids = {}
  27. test_ids_by_job = {}
  28. unit_jobs = {}
  29. os.chdir(os.path.join("..", ".."))
  30. IDF_PATH = os.getcwd()
  31. class Parser(object):
  32. @classmethod
  33. def parse_test_folders(cls):
  34. test_folder_paths = list()
  35. os.chdir(os.path.join(IDF_PATH, "components"))
  36. component_dirs = os.listdir(".")
  37. for dir in component_dirs:
  38. os.chdir(dir)
  39. if "test" in os.listdir("."):
  40. test_folder_paths.append(os.path.join(os.getcwd(), "test"))
  41. os.chdir("..")
  42. Parser.parse_test_files(test_folder_paths)
  43. @classmethod
  44. def parse_test_files(cls, test_folder_paths):
  45. for path in test_folder_paths:
  46. os.chdir(path)
  47. for file_path in os.listdir("."):
  48. if file_path[-2:] == ".c":
  49. Parser.read_test_file(os.path.join(os.getcwd(), file_path), len(test_cases)+1)
  50. os.chdir(os.path.join("..", ".."))
  51. Parser.dump_test_cases(test_cases)
  52. @classmethod
  53. def read_test_file(cls, test_file_path, file_index):
  54. test_index = 0
  55. with open(test_file_path, "r") as file:
  56. for line in file:
  57. if re.match("TEST_CASE", line):
  58. test_index += 1
  59. tags = re.split(r"[\[\]\"]", line)
  60. Parser.parse_test_cases(file_index, test_index, tags)
  61. @classmethod
  62. def parse_test_cases(cls, file_index, test_index, tags):
  63. ci_ready = "Yes"
  64. test_env = "UT_T1_1"
  65. for tag in tags:
  66. if tag == "ignore":
  67. ci_ready = "No"
  68. if re.match("test_env=", tag):
  69. test_env = tag[9:]
  70. module_name = tags[4]
  71. try:
  72. MODULE_MAP[module_name]
  73. except KeyError:
  74. module_name = "misc"
  75. id = "UT_%s_%s_%03d%02d" % (MODULE_MAP[module_name]['module abbr'],
  76. MODULE_MAP[module_name]['sub module abbr'],
  77. file_index, test_index)
  78. test_case = dict(TEST_CASE_PATTERN)
  79. test_case.update({"module": MODULE_MAP[module_name]['module'],
  80. "CI ready": ci_ready,
  81. "cmd set": ["IDFUnitTest/UnitTest", [tags[1]]],
  82. "ID": id,
  83. "test point 2": module_name,
  84. "steps": tags[1],
  85. "comment": tags[1],
  86. "test environment": test_env,
  87. "sub module": MODULE_MAP[module_name]['sub module'],
  88. "summary": tags[1]})
  89. if test_case["CI ready"] == "Yes":
  90. if test_ids.has_key(test_env):
  91. test_ids[test_env].append(id)
  92. else:
  93. test_ids.update({test_env: [id]})
  94. test_cases.append(test_case)
  95. @classmethod
  96. def dump_test_cases(cls, test_cases):
  97. os.chdir(os.path.join(IDF_PATH, "components", "idf_test", "unit_test"))
  98. with open ("TestCaseAll.yml", "wb+") as f:
  99. yaml.dump({"test cases": test_cases}, f, allow_unicode=True, default_flow_style=False)
  100. @classmethod
  101. def dump_ci_config(cls):
  102. Parser.split_test_cases()
  103. os.chdir(os.path.join(IDF_PATH, "components", "idf_test", "unit_test"))
  104. if not os.path.exists("CIConfigs"):
  105. os.makedirs("CIConfigs")
  106. os.chdir("CIConfigs")
  107. for unit_job in unit_jobs:
  108. job = dict(CONFIG_FILE_PATTERN)
  109. job.update({"DUT": ["UT1"]})
  110. job.update({"Filter": [{"Add": {"ID": test_ids_by_job[unit_job]}}]})
  111. with open (unit_job + ".yml", "wb+") as f:
  112. yaml.dump(job, f, allow_unicode=True, default_flow_style=False)
  113. @classmethod
  114. def split_test_cases(cls):
  115. for job in unit_jobs:
  116. test_ids_by_job.update({job: list()})
  117. for test_env in test_ids:
  118. available_jobs = list()
  119. for job in unit_jobs:
  120. if test_env in unit_jobs[job]:
  121. available_jobs.append(job)
  122. for idx, job in enumerate(available_jobs):
  123. test_ids_by_job[job] += (test_ids[test_env][idx*len(test_ids[test_env])/len(available_jobs):(idx+1)*len(test_ids[test_env])/len(available_jobs)])
  124. @classmethod
  125. def parse_gitlab_ci(cls):
  126. os.chdir(IDF_PATH)
  127. with open(".gitlab-ci.yml", "rb") as f:
  128. gitlab_ci = yaml.load(f)
  129. keys = gitlab_ci.keys()
  130. for key in keys:
  131. if re.match("UT_", key):
  132. test_env = gitlab_ci[key]["tags"]
  133. unit_job = key
  134. key = {}
  135. key.update({unit_job: test_env})
  136. unit_jobs.update(key)
  137. @classmethod
  138. def copy_module_def_file(cls):
  139. src = os.path.join(IDF_PATH, "tools", "unit-test-app", "ModuleDefinition.yml")
  140. dst = os.path.join(IDF_PATH, "components", "idf_test", "unit_test")
  141. shutil.copy(src, dst)
  142. def main():
  143. Parser.parse_test_folders()
  144. Parser.parse_gitlab_ci()
  145. Parser.dump_ci_config()
  146. Parser.copy_module_def_file()
  147. if __name__ == '__main__':
  148. main()