framework.py 8.3 KB

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