runall.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import os
  2. import sys
  3. import time
  4. import re
  5. import shutil
  6. import platform
  7. PYTHON = os.path.basename(sys.executable)
  8. # Usage:
  9. # runall.py [test-to-resume]
  10. # Initialize test list
  11. tests = []
  12. # Excluded tests (because they fail?)
  13. excluded_tests = [
  14. "svn",
  15. "pyc",
  16. "scripts-call/150_srtp_2_1", # SRTP optional 'cannot' call SRTP mandatory
  17. "scripts-call/150_srtp_2_3.py", # disabled because #1267 wontfix
  18. "scripts-call/301_ice_public_a.py", # Unreliable, proxy returns 408 sometimes
  19. "scripts-call/301_ice_public_b.py", # Doesn't work because OpenSER modifies SDP
  20. "scripts-pres/200_publish.py", # Ok from cmdline, error from runall.py
  21. "scripts-media-playrec/100_resample_lf_8_11.py", # related to clock-rate 11 kHz problem
  22. "scripts-media-playrec/100_resample_lf_8_22.py", # related to clock-rate 22 kHz problem
  23. "scripts-media-playrec/100_resample_lf_11", # related to clock-rate 11 kHz problem
  24. "pesq", # temporarily disabling all pesq related test due to unreliability
  25. # TODO check all tests below for false negatives
  26. "call_305_ice_comp_1_2",
  27. "scripts-sendto/155_err_sdp_bad_syntax",
  28. "transfer-attended",
  29. "uac-inv-and-ack-without-sdp",
  30. "uac-subscribe",
  31. "uac-ticket-1148",
  32. "uas-422-then-200-bad-se",
  33. "uas-answer-180-multiple-fmts-support-update",
  34. "uas-inv-answered-with-srtp",
  35. "uas-mwi-0",
  36. "uas-mwi",
  37. "uas-register-ip-change-port-only",
  38. "uas-register-ip-change",
  39. "uas-timer-update"
  40. ]
  41. # Exclude scripts-sipp/uac-reinvite-bad-via-branch on MacOS due to unreliable result
  42. if platform.system()=='Darwin':
  43. excluded_tests.append("scripts-sipp/uac-reinvite-bad-via-branch")
  44. # Add basic tests
  45. for f in os.listdir("scripts-run"):
  46. tests.append("mod_run.py scripts-run/" + f)
  47. # Add basic call tests
  48. for f in os.listdir("scripts-call"):
  49. tests.append("mod_call.py scripts-call/" + f)
  50. # Add presence tests
  51. for f in os.listdir("scripts-pres"):
  52. tests.append("mod_pres.py scripts-pres/" + f)
  53. # Add mod_sendto tests
  54. for f in os.listdir("scripts-sendto"):
  55. tests.append("mod_sendto.py scripts-sendto/" + f)
  56. # Add mod_media_playrec tests
  57. for f in os.listdir("scripts-media-playrec"):
  58. tests.append("mod_media_playrec.py scripts-media-playrec/" + f)
  59. # Add mod_pesq tests
  60. for f in os.listdir("scripts-pesq"):
  61. tests.append("mod_pesq.py scripts-pesq/" + f)
  62. # Add recvfrom tests
  63. for f in os.listdir("scripts-recvfrom"):
  64. tests.append("mod_recvfrom.py scripts-recvfrom/" + f)
  65. # Add sipp tests
  66. for f in os.listdir("scripts-sipp"):
  67. if f.endswith(".xml"):
  68. tests.append("mod_sipp.py scripts-sipp/" + f)
  69. resume_script=""
  70. retry_num=0
  71. shell_cmd=""
  72. with_log=True
  73. # Parse arguments
  74. sys.argv.pop(0)
  75. while len(sys.argv):
  76. if sys.argv[0]=='/h' or sys.argv[0]=='-h' or sys.argv[0]=='--help' or sys.argv[0]=='/help':
  77. sys.argv.pop(0)
  78. print("Usage:")
  79. print(" runall.py [OPTIONS] [run.py-OPTIONS]")
  80. print("OPTIONS:")
  81. print(" --list")
  82. print(" List the tests")
  83. print(" --list-xml")
  84. print(" List the tests as XML format suitable for ccdash")
  85. print(" --resume,-r RESUME")
  86. print(" RESUME is string/substring to specify where to resume tests.")
  87. print(" If this argument is omited, tests will start from the beginning.")
  88. print(" --disable,-d TEST_NAME")
  89. print(" Disable a specific test that contains the specified TEST_NAME.")
  90. print(" --retry,-t RETRY_NUM")
  91. print(" Retry a specific test RETRY_NUM times before marking it as failed.")
  92. print(" Default is 0 (no retry).")
  93. print(" --shell,-s SHELL")
  94. print(" Run the tests with the specified SHELL cmd. This can also be")
  95. print(" used to run the test with ccdash. Example:")
  96. print(" --shell '/bin/sh -c'")
  97. print(" --no-log")
  98. print(" Do not generate log files. By default log files will be generated")
  99. print(" and put in 'logs' dir.")
  100. print("")
  101. print(" run.py-OPTIONS are applicable here")
  102. sys.exit(0)
  103. elif sys.argv[0] == '-r' or sys.argv[0] == '--resume':
  104. if len(sys.argv) > 1:
  105. resume_script=sys.argv[1]
  106. sys.argv.pop(0)
  107. sys.argv.pop(0)
  108. else:
  109. sys.argv.pop(0)
  110. sys.stderr.write("Error: argument value required")
  111. sys.exit(1)
  112. elif sys.argv[0] == '-t' or sys.argv[0] == '--retry':
  113. if len(sys.argv) > 1:
  114. retry_num=int(sys.argv[1])
  115. sys.argv.pop(0)
  116. sys.argv.pop(0)
  117. else:
  118. sys.argv.pop(0)
  119. sys.stderr.write("Error: argument value required")
  120. sys.exit(1)
  121. elif sys.argv[0] == '--list':
  122. sys.argv.pop(0)
  123. for t in tests:
  124. print(t)
  125. sys.exit(0)
  126. elif sys.argv[0] == '--list-xml':
  127. sys.argv.pop(0)
  128. for t in tests:
  129. (mod,param) = t.split(None,2)
  130. tname = mod[4:mod.find(".py")] + "_" + \
  131. param[param.find("/")+1:param.rfind(".")]
  132. c = ""
  133. if len(sys.argv):
  134. c = " ".join(sys.argv) + " "
  135. tcmd = PYTHON + ' run.py ' + c + t
  136. print('\t\t<Test name="%s" cmd="%s" wdir="tests/pjsua" />' % (tname, tcmd))
  137. sys.exit(0)
  138. elif sys.argv[0] == '-s' or sys.argv[0] == '--shell':
  139. if len(sys.argv) > 1:
  140. shell_cmd = sys.argv[1]
  141. sys.argv.pop(0)
  142. sys.argv.pop(0)
  143. else:
  144. sys.argv.pop(0)
  145. sys.stderr.write("Error: argument value required")
  146. sys.exit(1)
  147. elif sys.argv[0] == '-d' or sys.argv[0] == '--disable':
  148. if len(sys.argv) > 1:
  149. excluded_tests.append(sys.argv[1])
  150. sys.argv.pop(0)
  151. sys.argv.pop(0)
  152. else:
  153. sys.argv.pop(0)
  154. sys.stderr.write("Error: argument value required")
  155. sys.exit(1)
  156. elif sys.argv[0] == '--no-log':
  157. sys.argv.pop(0)
  158. with_log=False
  159. else:
  160. # should be run.py options
  161. break
  162. # Generate arguments for run.py
  163. argv_st = " ".join(sys.argv) + " "
  164. # Init vars
  165. fails_cnt = 0
  166. tests_cnt = 0
  167. # Filter-out excluded tests
  168. for pat in excluded_tests:
  169. tests = [t for t in tests if t.find(pat)==-1]
  170. # Now run the tests
  171. total_cnt = len(tests)
  172. for t in tests:
  173. if resume_script!="" and t.find(resume_script)==-1:
  174. print("Skipping " + t +"..")
  175. total_cnt = total_cnt - 1
  176. continue
  177. resume_script=""
  178. cmdline = "python run.py " + argv_st + t
  179. if shell_cmd:
  180. cmdline = "%s '%s'" % (shell_cmd, cmdline)
  181. for i in range(1, retry_num+2):
  182. t0 = time.time()
  183. msg = "Running %3d/%d (#%d): %s..." % (tests_cnt+1, total_cnt, i, cmdline)
  184. sys.stdout.write(msg)
  185. sys.stdout.flush()
  186. if with_log:
  187. logname = re.search(".*\s+(.*)", t).group(1)
  188. logname = re.sub("[\\\/]", "_", logname)
  189. logname = re.sub("\.py$", ".log", logname)
  190. logname = re.sub("\.xml$", ".log", logname)
  191. logname = "logs/" + logname
  192. else:
  193. logname = os.devnull
  194. ret = os.system(cmdline + " > " + logname)
  195. t1 = time.time()
  196. if ret != 0:
  197. dur = int(t1 - t0)
  198. print(" failed!! [" + str(dur) + "s]")
  199. if (i < retry_num + 1):
  200. continue
  201. if with_log:
  202. lines = open(logname, "r", encoding='utf-8').readlines()
  203. print(''.join(lines))
  204. print("Log file: '" + logname + "'.")
  205. fails_cnt += 1
  206. else:
  207. dur = int(t1 - t0)
  208. print(" ok [" + str(dur) + "s]")
  209. break
  210. tests_cnt += 1
  211. if fails_cnt == 0:
  212. print("All " + str(tests_cnt) + " tests completed successfully")
  213. else:
  214. print(str(tests_cnt) + " tests completed, " + str(fails_cnt) + " test(s) failed")
  215. sys.exit(fails_cnt)