UnitTestParser.py 5.7 KB

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