utils.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import ConfigParser
  2. import os
  3. import glob
  4. import json
  5. import socket
  6. import fnmatch
  7. from ast import literal_eval
  8. def find_docker_file(path, pattern):
  9. for root, dirs, files in os.walk(path):
  10. for name in files:
  11. if fnmatch.fnmatch(name, pattern):
  12. return os.path.join(root, name)
  13. def gather_docker_dependencies(docker_file):
  14. '''
  15. Gathers all the known docker dependencies for the given docker image.
  16. '''
  17. # Avoid setting up a circular import
  18. from setup.linux import setup_util
  19. deps = []
  20. docker_dir = os.path.join(setup_util.get_fwroot(), "toolset", "setup", "linux", "docker")
  21. if os.path.exists(docker_file):
  22. with open(docker_file) as fp:
  23. for line in fp.readlines():
  24. tokens = line.strip().split(' ')
  25. if tokens[0] == "FROM":
  26. # This is magic that our base image points to
  27. if tokens[1] != "ubuntu:16.04":
  28. depToken = tokens[1].strip().split(':')[0].strip().split('/')[1]
  29. deps.append(depToken)
  30. dep_docker_file = os.path.join(os.path.dirname(docker_file), depToken + ".dockerfile")
  31. if not os.path.exists(dep_docker_file):
  32. dep_docker_file = find_docker_file(docker_dir, depToken + ".dockerfile")
  33. deps.extend(gather_docker_dependencies(dep_docker_file))
  34. return deps
  35. def gather_langauges():
  36. '''
  37. Gathers all the known languages in the suite via the folder names
  38. beneath FWROOT.
  39. '''
  40. # Avoid setting up a circular import
  41. from setup.linux import setup_util
  42. lang_dir = os.path.join(setup_util.get_fwroot(), "frameworks")
  43. langs = []
  44. for dir in glob.glob(os.path.join(lang_dir, "*")):
  45. langs.append(dir.replace(lang_dir,"")[1:])
  46. return langs
  47. def gather_tests(include = [], exclude=[], benchmarker=None):
  48. '''
  49. Given test names as strings, returns a list of FrameworkTest objects.
  50. For example, 'aspnet-mysql-raw' turns into a FrameworkTest object with
  51. variables for checking the test directory, the test database os, and
  52. other useful items.
  53. With no arguments, every test in this framework will be returned.
  54. With include, only tests with this exact name will be returned.
  55. With exclude, all tests but those excluded will be returned.
  56. A benchmarker is needed to construct full FrameworkTest objects. If
  57. one is not provided, a default Benchmarker will be created.
  58. '''
  59. # Avoid setting up a circular import
  60. from benchmark import framework_test
  61. from benchmark.benchmarker import Benchmarker
  62. from setup.linux import setup_util
  63. # Help callers out a bit
  64. if include is None:
  65. include = []
  66. if exclude is None:
  67. exclude = []
  68. # Old, hacky method to exclude all tests was to
  69. # request a test known to not exist, such as ''.
  70. # If test '' was requested, short-circuit and return
  71. # nothing immediately
  72. if len(include) == 1 and '' in include:
  73. return []
  74. # Setup default Benchmarker using example configuration
  75. if benchmarker is None:
  76. default_config = setup_util.get_fwroot() + "/benchmark.cfg"
  77. config = ConfigParser.SafeConfigParser()
  78. config.readfp(open(default_config))
  79. defaults = dict(config.items("Defaults"))
  80. # Convert strings into proper python types
  81. for k,v in defaults.iteritems():
  82. try:
  83. defaults[k] = literal_eval(v)
  84. except Exception:
  85. pass
  86. # Ensure we only run the __init__ method of Benchmarker
  87. defaults['install'] = None
  88. defaults['results_name'] = "(unspecified, datetime = %Y-%m-%d %H:%M:%S)"
  89. defaults['results_environment'] = "My Server Environment"
  90. defaults['test_dir'] = None
  91. defaults['test_lang'] = None
  92. defaults['quiet'] = True
  93. benchmarker = Benchmarker(defaults)
  94. # Search for configuration files
  95. fwroot = setup_util.get_fwroot()
  96. config_files = []
  97. if benchmarker.test_lang:
  98. benchmarker.test_dir = []
  99. for lang in benchmarker.test_lang:
  100. if os.path.exists("{!s}/frameworks/{!s}".format(fwroot, lang)):
  101. for test_dir in os.listdir("{!s}/frameworks/{!s}".format(fwroot, lang)):
  102. benchmarker.test_dir.append("{!s}/{!s}".format(lang, test_dir))
  103. else:
  104. raise Exception("Unable to locate language directory: {!s}".format(lang))
  105. if benchmarker.test_dir:
  106. for test_dir in benchmarker.test_dir:
  107. dir_config_files = glob.glob("{!s}/frameworks/{!s}/benchmark_config.json".format(fwroot, test_dir))
  108. if len(dir_config_files):
  109. config_files.extend(dir_config_files)
  110. else:
  111. raise Exception("Unable to locate tests in test-dir: {!s}".format(test_dir))
  112. else:
  113. config_files.extend(glob.glob("{!s}/frameworks/*/*/benchmark_config.json".format(fwroot)))
  114. tests = []
  115. for config_file_name in config_files:
  116. config = None
  117. with open(config_file_name, 'r') as config_file:
  118. try:
  119. config = json.load(config_file)
  120. except ValueError:
  121. # User-friendly errors
  122. print("Error loading '{!s}'.".format(config_file_name))
  123. raise
  124. # Find all tests in the config file
  125. config_tests = framework_test.parse_config(config,
  126. os.path.dirname(config_file_name), benchmarker)
  127. # Filter
  128. for test in config_tests:
  129. if len(include) is 0 and len(exclude) is 0:
  130. # No filters, we are running everything
  131. tests.append(test)
  132. elif test.name in exclude:
  133. continue
  134. elif test.name in include:
  135. tests.append(test)
  136. else:
  137. # An include list exists, but this test is
  138. # not listed there, so we ignore it
  139. pass
  140. # Ensure we were able to locate everything that was
  141. # explicitly included
  142. if 0 != len(include):
  143. names = {test.name for test in tests}
  144. if 0 != len(set(include) - set(names)):
  145. missing = list(set(include) - set(names))
  146. raise Exception("Unable to locate tests %s" % missing)
  147. tests.sort(key=lambda x: x.name)
  148. return tests
  149. def gather_frameworks(include = [], exclude=[], benchmarker=None):
  150. '''Return a dictionary mapping frameworks->[test1,test2,test3]
  151. for quickly grabbing all tests in a grouped manner.
  152. Args have the same meaning as gather_tests'''
  153. tests = gather_tests(include, exclude, benchmarker)
  154. frameworks = dict()
  155. for test in tests:
  156. if test.framework not in frameworks:
  157. frameworks[test.framework] = []
  158. frameworks[test.framework].append(test)
  159. return frameworks
  160. def header(message, top='-', bottom='-'):
  161. '''
  162. Generates a clean header
  163. '''
  164. topheader = (top * 80)[:80]
  165. bottomheader = (bottom * 80)[:80]
  166. result = ""
  167. if topheader != "":
  168. result += "%s" % topheader
  169. if message != "":
  170. if result == "":
  171. result = " %s" % message
  172. else:
  173. result += "\n %s" % message
  174. if bottomheader != "":
  175. if result == "":
  176. result = "%s" % bottomheader
  177. else:
  178. result += "\n%s" % bottomheader
  179. return result + '\n'
  180. def check_services(services):
  181. def check_service(address, port):
  182. try:
  183. s = socket.socket()
  184. s.settimeout(20)
  185. s.connect((address, port))
  186. return (True, "")
  187. except Exception as ex:
  188. return (False, ex)
  189. finally:
  190. s.close
  191. res = []
  192. for s in services:
  193. r = check_service(s[1], s[2])
  194. res.append((s[0], r[0], str(r[1])))
  195. return res
  196. def verify_database_connections(services):
  197. allGo = True
  198. messages = []
  199. for r in check_services(services):
  200. if r[1]:
  201. messages.append(r[0] + ": is GO!")
  202. else:
  203. messages.append(r[0] + ": is _NO_ GO!: ERROR: " + r[2])
  204. allGo = False
  205. return (allGo, messages)