framework.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. from __future__ import print_function
  2. #
  3. # Copyright (C) 2019 Intel Corporation. All rights reserved.
  4. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5. #
  6. import datetime
  7. import os
  8. import pprint
  9. import random
  10. import re
  11. import shlex
  12. import subprocess
  13. import signal
  14. import sys
  15. import time
  16. import shutil
  17. from .test_api import *
  18. import this
  19. '''
  20. The run evironment dir structure:
  21. run/
  22. run{date-time}/
  23. suites/
  24. {suite name}/
  25. -- target/ (the target software being tested)
  26. -- tools/ (the tools for testing the target software)
  27. '''
  28. framework=None
  29. def get_framework():
  30. global framework
  31. return framework
  32. def my_import(name):
  33. mod = __import__(name)
  34. components = name.split('.')
  35. for comp in components[1:]:
  36. mod = getattr(mod, comp)
  37. return mod
  38. # we maintain a root path apart from framework location
  39. # so the suites can be located in anywhere
  40. class CTestFramework(object):
  41. def __init__(self, path):
  42. self.running_case = ''
  43. self.running_suite = ''
  44. self.target_suites = {}
  45. self.target_cases = {}
  46. self.root_path = path
  47. self.running_folder=''
  48. self.report = None
  49. self.sucess_cases = 0
  50. self.failed_cases = 0
  51. self.setup_fails = 0
  52. self.load_fails = 0;
  53. global framework
  54. framework = self
  55. api_set_root_path(path)
  56. print("root_path is " + self.root_path)
  57. def gen_execution_stats(self):
  58. return '\nTest Execution Summary: ' \
  59. '\n\tSuccess: {}' \
  60. '\n\tCases fails: {}' \
  61. '\n\tSetup fails: {}' \
  62. '\n\tCase load fails: {}'.format(
  63. self.sucess_cases, self.failed_cases, self.setup_fails, self.load_fails)
  64. def report_result(self, success, message, case_description):
  65. if self.report is None:
  66. return
  67. case_pass = "pass"
  68. if not success:
  69. case_pass = "fail"
  70. self.report.write(case_pass + ": [" + self.running_case + "]\n\treason: " + \
  71. message + "\n\tcase: " + case_description + "\n")
  72. return
  73. def get_running_path(self):
  74. return self.root_path + "/run/" + self.running_folder
  75. def load_suites(self):
  76. self.target_suites = os.listdir(self.root_path + "/suites")
  77. return
  78. def run_case(self, suite_instance, case):
  79. # load the test case module
  80. case_description = ''
  81. suite = suite_instance.m_name
  82. api_log("\n>>start run [" + case + "] >>")
  83. module_name = 'suites.' + suite + ".cases." + case + ".case"
  84. try:
  85. module = my_import(module_name)
  86. except Exception as e:
  87. report_fail("load case fail: " + str(e))
  88. api_log_error("load case fail: " + str(e))
  89. self.load_fails = self.load_fails +1
  90. print(traceback.format_exc())
  91. return False
  92. try:
  93. case = module.CTestCase(suite_instance)
  94. except Exception as e:
  95. report_fail("initialize case fail: " + str(e))
  96. api_log_error("initialize case fail: " + str(e))
  97. self.load_fails = self.load_fails +1
  98. return False
  99. # call the case on setup callback
  100. try:
  101. case_description = case.on_get_case_description()
  102. result, message = case.on_setup_case()
  103. except Exception as e:
  104. result = False
  105. message = str(e);
  106. if not result:
  107. api_log_error(message)
  108. report_fail (message, case_description)
  109. self.failed_cases = self.failed_cases+1
  110. return False
  111. # call the case execution callaback
  112. try:
  113. result, message = case.on_run_case()
  114. except Exception as e:
  115. result = False
  116. message = str(e);
  117. if not result:
  118. report_fail (message, case_description)
  119. api_log_error(message)
  120. self.failed_cases = self.failed_cases+1
  121. else:
  122. report_success(case_description)
  123. self.sucess_cases = self.sucess_cases +1
  124. # call the case cleanup callback
  125. try:
  126. clean_result, message = case.on_cleanup_case()
  127. except Exception as e:
  128. clean_result = False
  129. message = str(e)
  130. if not clean_result:
  131. api_log(message)
  132. return result
  133. def run_suite(self, suite, cases):
  134. # suite setup
  135. message = ''
  136. api_log("\n>>> Suite [" + suite + "] starting >>>")
  137. running_folder = self.get_running_path()+ "/suites/" + suite;
  138. module_name = 'suites.' + suite + ".suite_setup"
  139. try:
  140. module = my_import(module_name)
  141. except Exception as e:
  142. report_fail("load suite [" + suite +"] fail: " + str(e))
  143. self.load_fails = self.load_fails +1
  144. return False
  145. try:
  146. suite_instance = module.CTestSuite(suite, \
  147. self.root_path + '/suites/' + suite, running_folder)
  148. except Exception as e:
  149. report_fail("initialize suite fail: " + str(e))
  150. self.load_fails = self.load_fails +1
  151. return False
  152. result, message = suite_instance.load_settings()
  153. if not result:
  154. report_fail("load settings fail: " + str(e))
  155. self.load_fails = self.load_fails +1
  156. return False
  157. try:
  158. result, message = suite_instance.on_suite_setup()
  159. except Exception as e:
  160. result = False
  161. message = str(e);
  162. if not result:
  163. api_log_error(message)
  164. report_fail (message)
  165. self.setup_fails = self.setup_fails + 1
  166. return False
  167. self.running_suite = suite
  168. cases.sort()
  169. # run cases
  170. for case in cases:
  171. if not os.path.isdir(self.root_path + '/suites/' + suite + '/cases/' + case):
  172. continue
  173. self.running_case = case
  174. self.run_case(suite_instance, case)
  175. self.running_case = ''
  176. # suites cleanup
  177. self.running_suite = ''
  178. try:
  179. result, message = suite_instance.on_suite_cleanup()
  180. except Exception as e:
  181. result = False
  182. message = str(e);
  183. if not result:
  184. api_log_error(message)
  185. report_fail (message)
  186. self.setup_fails = self.setup_fails + 1
  187. return
  188. def start_run(self):
  189. if self.target_suites is None:
  190. print("\n\nstart run: no target suites, exit..")
  191. return
  192. cur_time = time.localtime()
  193. time_prefix = "{:02}-{:02}-{:02}-{:02}".format(
  194. cur_time.tm_mon, cur_time.tm_mday, cur_time.tm_hour, cur_time.tm_min)
  195. debug = api_get_value('debug', False)
  196. if debug:
  197. self.running_folder = 'debug'
  198. else:
  199. self.running_folder = 'run-' + time_prefix
  200. folder = self.root_path + "/run/" +self.running_folder;
  201. if os.path.exists(folder):
  202. shutil.rmtree(folder, ignore_errors=True)
  203. if not os.path.exists(folder):
  204. os.makedirs(folder )
  205. os.makedirs(folder + "/suites")
  206. api_init_log(folder + "/test.log")
  207. self.report = open(folder + "/report.txt", 'a')
  208. self.target_suites.sort()
  209. for suite in self.target_suites:
  210. if not os.path.isdir(self.root_path + '/suites/' + suite):
  211. continue
  212. self.report.write("suite " + suite + " cases:\n")
  213. if self.target_cases is None:
  214. cases = os.listdir(self.root_path + "/suites/" + suite + "/cases")
  215. self.run_suite(suite, cases)
  216. else:
  217. self.run_suite(suite, self.target_cases)
  218. self.report.write("\n")
  219. self.report.write("\n\n")
  220. summary = self.gen_execution_stats()
  221. self.report.write(summary);
  222. self.report.flush()
  223. self.report.close()
  224. print(summary)
  225. def report_fail(message, case_description=''):
  226. global framework
  227. if framework is not None:
  228. framework.report_result(False, message, case_description)
  229. api_log_error(message)
  230. return
  231. def report_success(case_description=''):
  232. global framework
  233. if framework is not None:
  234. framework.report_result(True , "OK", case_description)
  235. return