run-tests.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. #!/usr/bin/env python2
  2. #
  3. # Remote test case executor
  4. # Copyright (c) 2016, Tieto Corporation
  5. #
  6. # This software may be distributed under the terms of the BSD license.
  7. # See README for more details.
  8. import os
  9. import re
  10. import sys
  11. import time
  12. import traceback
  13. import getopt
  14. from datetime import datetime
  15. import logging
  16. logger = logging.getLogger()
  17. scriptsdir = os.path.dirname(os.path.realpath(sys.modules[__name__].__file__))
  18. sys.path.append(os.path.join(scriptsdir, '..', '..', 'wpaspy'))
  19. sys.path.append(os.path.join(scriptsdir, '..', 'hwsim'))
  20. import wpaspy
  21. import config
  22. from test_devices import show_devices
  23. from test_devices import check_devices
  24. from rutils import TestSkip
  25. from utils import HwsimSkip
  26. from hwsim_wrapper import run_hwsim_test
  27. def usage():
  28. print "USAGE: " + sys.argv[0] + " -t devices"
  29. print "USAGE: " + sys.argv[0] + " -t check_devices"
  30. print "USAGE: " + sys.argv[0] + " -d <dut_name> -t <all|sanity|tests_to_run> [-r <ref_name>] [-c <cfg_file.py>] [-m <all|monitor_name>] [-h hwsim_tests][-R][-T][-P][-v]"
  31. print "USAGE: " + sys.argv[0]
  32. def get_devices(devices, duts, refs, monitors):
  33. for dut in duts:
  34. config.get_device(devices, dut, lock=True)
  35. for ref in refs:
  36. config.get_device(devices, ref, lock=True)
  37. for monitor in monitors:
  38. if monitor == "all":
  39. continue
  40. if monitor in duts:
  41. continue
  42. if monitor in refs:
  43. continue
  44. config.get_device(devices, monitor, lock=True)
  45. def put_devices(devices, duts, refs, monitors):
  46. for dut in duts:
  47. config.put_device(devices, dut)
  48. for ref in refs:
  49. config.put_device(devices, ref)
  50. for monitor in monitors:
  51. if monitor == "all":
  52. continue
  53. if monitor in duts:
  54. continue
  55. if monitor in refs:
  56. continue
  57. config.put_device(devices, monitor)
  58. def main():
  59. duts = []
  60. refs = []
  61. monitors = []
  62. filter_keys = []
  63. requested_tests = ["help"]
  64. requested_hwsim_tests = []
  65. hwsim_tests = []
  66. cfg_file = "cfg.py"
  67. log_dir = "./logs/"
  68. verbose = False
  69. trace = False
  70. restart = False
  71. perf = False
  72. # parse input parameters
  73. try:
  74. opts, args = getopt.getopt(sys.argv[1:], "d:r:t:l:k:c:m:h:vRPT",
  75. ["dut=", "ref=", "tests=", "log-dir=",
  76. "cfg=", "key=", "monitor=", "hwsim="])
  77. except getopt.GetoptError as err:
  78. print(err)
  79. usage()
  80. sys.exit(2)
  81. for option, argument in opts:
  82. if option == "-v":
  83. verbose = True
  84. elif option == "-R":
  85. restart = True
  86. elif option == "-T":
  87. trace = True
  88. elif option == "-P":
  89. perf = True
  90. elif option in ("-d", "--dut"):
  91. duts.append(argument)
  92. elif option in ("-r", "--ref"):
  93. refs.append(argument)
  94. elif option in ("-t", "--tests"):
  95. requested_tests = re.split('; | |, ', argument)
  96. elif option in ("-l", "--log-dir"):
  97. log_dir = argument
  98. elif option in ("-k", "--key"):
  99. filter_keys.append(argument)
  100. elif option in ("-m", "--monitor"):
  101. monitors.append(argument)
  102. elif option in ("-c", "--cfg"):
  103. cfg_file = argument
  104. elif option in ("-h", "--hwsim"):
  105. requested_hwsim_tests = re.split('; | |, ', argument)
  106. else:
  107. assert False, "unhandled option"
  108. # get env configuration
  109. setup_params = config.get_setup_params(cfg_file)
  110. devices = config.get_devices(cfg_file)
  111. # put logs in log_dir
  112. symlink = os.path.join(log_dir, "current");
  113. if os.path.exists(symlink):
  114. os.unlink(symlink)
  115. log_dir = os.path.join(log_dir, time.strftime("%Y_%m_%d_%H_%M_%S"))
  116. if not os.path.exists(log_dir):
  117. os.makedirs(log_dir)
  118. os.symlink(os.path.join("../", log_dir), symlink)
  119. # setup restart/trace/perf request
  120. setup_params['local_log_dir'] = log_dir
  121. setup_params['restart_device'] = restart
  122. setup_params['trace'] = trace
  123. setup_params['perf'] = perf
  124. # configure logger
  125. logger.setLevel(logging.DEBUG)
  126. stdout_handler = logging.StreamHandler()
  127. stdout_handler.setLevel(logging.WARNING)
  128. if verbose:
  129. stdout_handler.setLevel(logging.DEBUG)
  130. logger.addHandler(stdout_handler)
  131. formatter = logging.Formatter('%(asctime)s - %(message)s')
  132. file_name = os.path.join(log_dir, 'run-tests.log')
  133. log_handler = logging.FileHandler(file_name)
  134. log_handler.setLevel(logging.DEBUG)
  135. log_handler.setFormatter(formatter)
  136. logger.addHandler(log_handler)
  137. # import available tests
  138. tests = []
  139. failed = []
  140. test_modules = []
  141. files = os.listdir(scriptsdir)
  142. for t in files:
  143. m = re.match(r'(test_.*)\.py$', t)
  144. if m:
  145. mod = __import__(m.group(1))
  146. test_modules.append(mod.__name__.replace('test_', '', 1))
  147. for key,val in mod.__dict__.iteritems():
  148. if key.startswith("test_"):
  149. tests.append(val)
  150. test_names = list(set([t.__name__.replace('test_', '', 1) for t in tests]))
  151. # import test_*
  152. files = os.listdir("../hwsim/")
  153. for t in files:
  154. m = re.match(r'(test_.*)\.py$', t)
  155. if m:
  156. mod = __import__(m.group(1))
  157. test_modules.append(mod.__name__.replace('test_', '', 1))
  158. for key,val in mod.__dict__.iteritems():
  159. if key.startswith("test_"):
  160. hwsim_tests.append(val)
  161. # setup hwsim tests
  162. hwsim_tests_to_run = []
  163. if len(requested_hwsim_tests) > 0:
  164. # apply filters
  165. for filter_key in filter_keys:
  166. filtered_tests = []
  167. for hwsim_test in hwsim_tests:
  168. if re.search(filter_key, hwsim_test.__name__):
  169. filtered_tests.append(hwsim_test)
  170. hwsim_tests = filtered_tests
  171. # setup hwsim_test we should run
  172. if requested_hwsim_tests[0] == "all":
  173. hwsim_tests_to_run = hwsim_tests
  174. elif requested_hwsim_tests[0] == "remote":
  175. hwsim_tests_to_run = [t for t in hwsim_tests
  176. if hasattr(t, "remote_compatible") and
  177. t.remote_compatible]
  178. else:
  179. for test in requested_hwsim_tests:
  180. t = None
  181. for tt in hwsim_tests:
  182. name = tt.__name__.replace('test_', '', 1)
  183. if name == test and tt.func_code.co_argcount <= 2:
  184. t = tt
  185. break
  186. if not t:
  187. logger.warning("hwsim test case: " + test + " NOT-FOUND")
  188. continue
  189. hwsim_tests_to_run.append(t)
  190. # sort the list
  191. test_names.sort()
  192. tests.sort()
  193. # print help
  194. if requested_tests[0] == "help" and len(requested_hwsim_tests) == 0:
  195. usage()
  196. print "\nAvailable Devices:"
  197. for device in devices:
  198. print "\t", device['name']
  199. print "\nAvailable tests:"
  200. for test in test_names:
  201. print "\t", test
  202. print "\nAvailable hwsim tests:"
  203. for hwsim_test in hwsim_tests:
  204. print "\t", hwsim_test.__name__.replace('test_', '', 1)
  205. return
  206. # show/check devices
  207. if requested_tests[0] == "devices":
  208. show_devices(devices, setup_params)
  209. return
  210. # apply filters
  211. for filter_key in filter_keys:
  212. filtered_tests = []
  213. for test in tests:
  214. if re.search(filter_key, test.__name__):
  215. filtered_tests.append(test)
  216. tests = filtered_tests
  217. # setup test we should run
  218. tests_to_run = []
  219. if requested_tests[0] == "all":
  220. tests_to_run = tests
  221. if requested_tests[0] == "help":
  222. pass
  223. elif requested_tests[0] == "sanity":
  224. for test in tests:
  225. if test.__name__.startswith("test_sanity_"):
  226. tests_to_run.append(test)
  227. else:
  228. for test in requested_tests:
  229. t = None
  230. for tt in tests:
  231. name = tt.__name__.replace('test_', '', 1)
  232. if name == test:
  233. t = tt
  234. break
  235. if not t:
  236. logger.warning("test case: " + test + " NOT-FOUND")
  237. continue
  238. tests_to_run.append(t)
  239. # lock devices
  240. try:
  241. get_devices(devices, duts, refs, monitors)
  242. except Exception, e:
  243. logger.warning("get devices failed: " + str(e))
  244. logger.info(traceback.format_exc())
  245. put_devices(devices, duts, refs, monitors)
  246. return
  247. except:
  248. logger.warning("get devices failed")
  249. logger.info(traceback.format_exc())
  250. put_devices(devices, duts, refs, monitors)
  251. return
  252. # now run test cases
  253. for dut in duts:
  254. logger.warning("DUT: " + str(dut))
  255. for ref in refs:
  256. logger.warning("REF: " + str(ref))
  257. for monitor in monitors:
  258. logger.warning("MON: " + str(monitor))
  259. # run check_devices at begining
  260. logger.warning("RUN check_devices")
  261. try:
  262. check_devices(devices, setup_params, refs, duts, monitors)
  263. except Exception, e:
  264. logger.warning("FAILED: " + str(e))
  265. logger.info(traceback.format_exc())
  266. put_devices(devices, duts, refs, monitors)
  267. return
  268. except:
  269. logger.warning("FAILED")
  270. logger.info(traceback.format_exc())
  271. put_devices(devices, duts, refs, monitors)
  272. return
  273. logger.warning("PASS")
  274. test_no = 1
  275. for test in tests_to_run:
  276. try:
  277. start = datetime.now()
  278. setup_params['tc_name'] = test.__name__.replace('test_', '', 1)
  279. logger.warning("START - " + setup_params['tc_name'] + " (" + str(test_no) + "/" + str(len(tests_to_run)) + ")")
  280. if test.__doc__:
  281. logger.info("Test: " + test.__doc__)
  282. # run tc
  283. res = test(devices, setup_params, refs, duts, monitors)
  284. end = datetime.now()
  285. logger.warning("PASS (" + res + ") - " + str((end - start).total_seconds()) + "s")
  286. except KeyboardInterrupt:
  287. put_devices(devices, duts, refs, monitors)
  288. raise
  289. except TestSkip, e:
  290. end = datetime.now()
  291. logger.warning("SKIP (" + str(e) + ") - " + str((end - start).total_seconds()) + "s")
  292. except Exception, e:
  293. end = datetime.now()
  294. logger.warning("FAILED (" + str(e) + ") - " + str((end - start).total_seconds()) + "s")
  295. logger.info(traceback.format_exc())
  296. failed.append(test.__name__.replace('test_', '', 1))
  297. except:
  298. end = datetime.now()
  299. logger.warning("FAILED - " + str((end - start).total_seconds()) + "s")
  300. logger.info(traceback.format_exc())
  301. failed.append(test.__name__.replace('test_', '', 1))
  302. test_no += 1
  303. test_no = 1
  304. for hwsim_test in hwsim_tests_to_run:
  305. try:
  306. start = datetime.now()
  307. setup_params['tc_name'] = hwsim_test.__name__.replace('test_', '', 1)
  308. logger.warning("START - " + setup_params['tc_name'] + " (" + str(test_no) + "/" + str(len(hwsim_tests_to_run)) + ")")
  309. res = run_hwsim_test(devices, setup_params, refs, duts, monitors, hwsim_test)
  310. end = datetime.now()
  311. logger.warning("PASS (" + res + ") - " + str((end - start).total_seconds()) + "s")
  312. except KeyboardInterrupt:
  313. put_devices(devices, duts, refs, monitors)
  314. raise
  315. except HwsimSkip,e:
  316. end = datetime.now()
  317. logger.warning("SKIP (" + str(e) + ") - " + str((end - start).total_seconds()) + "s")
  318. failed.append(hwsim_test.__name__.replace('test_', '', 1))
  319. except Exception, e:
  320. end = datetime.now()
  321. logger.warning("FAILED (" + str(e) + ") - " + str((end - start).total_seconds()) + "s")
  322. logger.info(traceback.format_exc())
  323. failed.append(hwsim_test.__name__.replace('test_', '', 1))
  324. except:
  325. end = datetime.now()
  326. logger.warning("FAILED - " + str((end - start).total_seconds()) + "s")
  327. logger.info(traceback.format_exc())
  328. failed.append(hwsim_test.__name__.replace('test_', '', 1))
  329. test_no += 1
  330. # unlock devices
  331. put_devices(devices, duts, refs, monitors)
  332. if len(failed) > 0:
  333. logger.warning("Failed test cases:")
  334. for test in failed:
  335. logger.warning("\t" + test)
  336. if __name__ == "__main__":
  337. main()