PageRenderTime 84ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/chrome/test/chromedriver/test/run_java_tests.py

https://gitlab.com/jonnialva90/iridium-browser
Python | 334 lines | 285 code | 15 blank | 34 comment | 7 complexity | d46eaee9a8c04bbc7a8af6083be5f992 MD5 | raw file
  1. #!/usr/bin/env python
  2. # Copyright 2013 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Runs the WebDriver Java acceptance tests.
  6. This script is called from chrome/test/chromedriver/run_all_tests.py and reports
  7. results using the buildbot annotation scheme.
  8. For ChromeDriver documentation, refer to http://code.google.com/p/chromedriver.
  9. """
  10. import optparse
  11. import os
  12. import shutil
  13. import sys
  14. import xml.dom.minidom as minidom
  15. _THIS_DIR = os.path.abspath(os.path.dirname(__file__))
  16. sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir))
  17. import chrome_paths
  18. import test_environment
  19. import util
  20. if util.IsLinux():
  21. sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'build', 'android'))
  22. from pylib import constants
  23. class TestResult(object):
  24. """A result for an attempted single test case."""
  25. def __init__(self, name, time, failure):
  26. """Initializes a test result.
  27. Args:
  28. name: the full name of the test.
  29. time: the amount of time the test ran, in seconds.
  30. failure: the test error or failure message, or None if the test passed.
  31. """
  32. self._name = name
  33. self._time = time
  34. self._failure = failure
  35. def GetName(self):
  36. """Returns the test name."""
  37. return self._name
  38. def GetTime(self):
  39. """Returns the time it took to run the test."""
  40. return self._time
  41. def IsPass(self):
  42. """Returns whether the test passed."""
  43. return self._failure is None
  44. def GetFailureMessage(self):
  45. """Returns the test failure message, or None if the test passed."""
  46. return self._failure
  47. def _Run(java_tests_src_dir, test_filter,
  48. chromedriver_path, chrome_path, log_path, android_package_key,
  49. verbose, debug):
  50. """Run the WebDriver Java tests and return the test results.
  51. Args:
  52. java_tests_src_dir: the java test source code directory.
  53. test_filter: the filter to use when choosing tests to run. Format is same
  54. as Google C++ Test format.
  55. chromedriver_path: path to ChromeDriver exe.
  56. chrome_path: path to Chrome exe.
  57. log_path: path to server log.
  58. android_package_key: name of Chrome's Android package.
  59. verbose: whether the output should be verbose.
  60. debug: whether the tests should wait until attached by a debugger.
  61. Returns:
  62. A list of |TestResult|s.
  63. """
  64. test_dir = util.MakeTempDir()
  65. keystore_path = ('java', 'client', 'test', 'keystore')
  66. required_dirs = [keystore_path[:-1],
  67. ('javascript',),
  68. ('third_party', 'closure', 'goog'),
  69. ('third_party', 'js')]
  70. for required_dir in required_dirs:
  71. os.makedirs(os.path.join(test_dir, *required_dir))
  72. test_jar = 'test-standalone.jar'
  73. class_path = test_jar
  74. shutil.copyfile(os.path.join(java_tests_src_dir, 'keystore'),
  75. os.path.join(test_dir, *keystore_path))
  76. util.Unzip(os.path.join(java_tests_src_dir, 'common.zip'), test_dir)
  77. shutil.copyfile(os.path.join(java_tests_src_dir, test_jar),
  78. os.path.join(test_dir, test_jar))
  79. sys_props = ['selenium.browser=chrome',
  80. 'webdriver.chrome.driver=' + os.path.abspath(chromedriver_path)]
  81. if chrome_path:
  82. sys_props += ['webdriver.chrome.binary=' + os.path.abspath(chrome_path)]
  83. if log_path:
  84. sys_props += ['webdriver.chrome.logfile=' + log_path]
  85. if android_package_key:
  86. android_package = constants.PACKAGE_INFO[android_package_key].package
  87. sys_props += ['webdriver.chrome.android_package=' + android_package]
  88. if android_package_key == 'chromedriver_webview_shell':
  89. android_activity = constants.PACKAGE_INFO[android_package_key].activity
  90. android_process = '%s:main' % android_package
  91. sys_props += ['webdriver.chrome.android_activity=' + android_activity]
  92. sys_props += ['webdriver.chrome.android_process=' + android_process]
  93. if test_filter:
  94. # Test jar actually takes a regex. Convert from glob.
  95. test_filter = test_filter.replace('*', '.*')
  96. sys_props += ['filter=' + test_filter]
  97. jvm_args = []
  98. if debug:
  99. transport = 'dt_socket'
  100. if util.IsWindows():
  101. transport = 'dt_shmem'
  102. jvm_args += ['-agentlib:jdwp=transport=%s,server=y,suspend=y,'
  103. 'address=33081' % transport]
  104. # Unpack the sources into the test directory and add to the class path
  105. # for ease of debugging, particularly with jdb.
  106. util.Unzip(os.path.join(java_tests_src_dir, 'test-nodeps-srcs.jar'),
  107. test_dir)
  108. class_path += ':' + test_dir
  109. return _RunAntTest(
  110. test_dir, 'org.openqa.selenium.chrome.ChromeDriverTests',
  111. class_path, sys_props, jvm_args, verbose)
  112. def _RunAntTest(test_dir, test_class, class_path, sys_props, jvm_args, verbose):
  113. """Runs a single Ant JUnit test suite and returns the |TestResult|s.
  114. Args:
  115. test_dir: the directory to run the tests in.
  116. test_class: the name of the JUnit test suite class to run.
  117. class_path: the Java class path used when running the tests, colon delimited
  118. sys_props: Java system properties to set when running the tests.
  119. jvm_args: Java VM command line args to use.
  120. verbose: whether the output should be verbose.
  121. Returns:
  122. A list of |TestResult|s.
  123. """
  124. def _CreateBuildConfig(test_name, results_file, class_path, junit_props,
  125. sys_props, jvm_args):
  126. def _SystemPropToXml(prop):
  127. key, value = prop.split('=')
  128. return '<sysproperty key="%s" value="%s"/>' % (key, value)
  129. def _JvmArgToXml(arg):
  130. return '<jvmarg value="%s"/>' % arg
  131. return '\n'.join([
  132. '<project>',
  133. ' <target name="test">',
  134. ' <junit %s>' % ' '.join(junit_props),
  135. ' <formatter type="xml"/>',
  136. ' <classpath>',
  137. ' <pathelement path="%s"/>' % class_path,
  138. ' </classpath>',
  139. ' ' + '\n '.join(map(_SystemPropToXml, sys_props)),
  140. ' ' + '\n '.join(map(_JvmArgToXml, jvm_args)),
  141. ' <test name="%s" outfile="%s"/>' % (test_name, results_file),
  142. ' </junit>',
  143. ' </target>',
  144. '</project>'])
  145. def _ProcessResults(results_path):
  146. doc = minidom.parse(results_path)
  147. tests = []
  148. for test in doc.getElementsByTagName('testcase'):
  149. name = test.getAttribute('classname') + '.' + test.getAttribute('name')
  150. time = test.getAttribute('time')
  151. failure = None
  152. error_nodes = test.getElementsByTagName('error')
  153. failure_nodes = test.getElementsByTagName('failure')
  154. if error_nodes:
  155. failure = error_nodes[0].childNodes[0].nodeValue
  156. elif failure_nodes:
  157. failure = failure_nodes[0].childNodes[0].nodeValue
  158. tests += [TestResult(name, time, failure)]
  159. return tests
  160. junit_props = ['printsummary="yes"',
  161. 'fork="yes"',
  162. 'haltonfailure="no"',
  163. 'haltonerror="no"']
  164. if verbose:
  165. junit_props += ['showoutput="yes"']
  166. ant_file = open(os.path.join(test_dir, 'build.xml'), 'w')
  167. ant_file.write(_CreateBuildConfig(
  168. test_class, 'results', class_path, junit_props, sys_props, jvm_args))
  169. ant_file.close()
  170. if util.IsWindows():
  171. ant_name = 'ant.bat'
  172. else:
  173. ant_name = 'ant'
  174. code = util.RunCommand([ant_name, 'test'], cwd=test_dir)
  175. if code != 0:
  176. print 'FAILED to run java tests of %s through ant' % test_class
  177. return
  178. return _ProcessResults(os.path.join(test_dir, 'results.xml'))
  179. def PrintTestResults(results):
  180. """Prints the given results in a format recognized by the buildbot."""
  181. failures = []
  182. failure_names = []
  183. for result in results:
  184. if not result.IsPass():
  185. failures += [result]
  186. failure_names += ['.'.join(result.GetName().split('.')[-2:])]
  187. print 'Ran %s tests' % len(results)
  188. print 'Failed %s:' % len(failures)
  189. util.AddBuildStepText('failed %s/%s' % (len(failures), len(results)))
  190. for result in failures:
  191. print '=' * 80
  192. print '=' * 10, result.GetName(), '(%ss)' % result.GetTime()
  193. print result.GetFailureMessage()
  194. if len(failures) < 10:
  195. util.AddBuildStepText('.'.join(result.GetName().split('.')[-2:]))
  196. print 'Rerun failing tests with filter:', ':'.join(failure_names)
  197. return len(failures)
  198. def main():
  199. parser = optparse.OptionParser()
  200. parser.add_option(
  201. '', '--verbose', action='store_true', default=False,
  202. help='Whether output should be verbose')
  203. parser.add_option(
  204. '', '--debug', action='store_true', default=False,
  205. help='Whether to wait to be attached by a debugger')
  206. parser.add_option(
  207. '', '--chromedriver', type='string', default=None,
  208. help='Path to a build of the chromedriver library(REQUIRED!)')
  209. parser.add_option(
  210. '', '--chrome', type='string', default=None,
  211. help='Path to a build of the chrome binary')
  212. parser.add_option(
  213. '', '--log-path',
  214. help='Output verbose server logs to this file')
  215. parser.add_option(
  216. '', '--chrome-version', default='HEAD',
  217. help='Version of chrome. Default is \'HEAD\'')
  218. parser.add_option(
  219. '', '--android-package', help='Android package key')
  220. parser.add_option(
  221. '', '--filter', type='string', default=None,
  222. help='Filter for specifying what tests to run, "*" will run all. E.g., '
  223. '*testShouldReturnTitleOfPageIfSet')
  224. parser.add_option(
  225. '', '--also-run-disabled-tests', action='store_true', default=False,
  226. help='Include disabled tests while running the tests')
  227. parser.add_option(
  228. '', '--isolate-tests', action='store_true', default=False,
  229. help='Relaunch the jar test harness after each test')
  230. options, _ = parser.parse_args()
  231. options.chromedriver = util.GetAbsolutePathOfUserPath(options.chromedriver)
  232. if options.chromedriver is None or not os.path.exists(options.chromedriver):
  233. parser.error('chromedriver is required or the given path is invalid.' +
  234. 'Please run "%s --help" for help' % __file__)
  235. if options.android_package:
  236. if options.android_package not in constants.PACKAGE_INFO:
  237. parser.error('Invalid --android-package')
  238. if options.chrome_version != 'HEAD':
  239. parser.error('Android does not support the --chrome-version argument.')
  240. environment = test_environment.AndroidTestEnvironment(
  241. options.android_package)
  242. else:
  243. environment = test_environment.DesktopTestEnvironment(
  244. options.chrome_version)
  245. try:
  246. environment.GlobalSetUp()
  247. # Run passed tests when filter is not provided.
  248. if options.isolate_tests:
  249. test_filters = environment.GetPassedJavaTests()
  250. else:
  251. if options.filter:
  252. test_filter = options.filter
  253. else:
  254. test_filter = '*'
  255. if not options.also_run_disabled_tests:
  256. if '-' in test_filter:
  257. test_filter += ':'
  258. else:
  259. test_filter += '-'
  260. test_filter += ':'.join(environment.GetDisabledJavaTestMatchers())
  261. test_filters = [test_filter]
  262. java_tests_src_dir = os.path.join(chrome_paths.GetSrc(), 'chrome', 'test',
  263. 'chromedriver', 'third_party',
  264. 'java_tests')
  265. if (not os.path.exists(java_tests_src_dir) or
  266. not os.listdir(java_tests_src_dir)):
  267. java_tests_url = ('http://src.chromium.org/svn/trunk/deps/third_party'
  268. '/webdriver')
  269. print ('"%s" is empty or it doesn\'t exist. ' % java_tests_src_dir +
  270. 'Need to map <chrome-svn>/trunk/deps/third_party/webdriver to '
  271. 'chrome/test/chromedriver/third_party/java_tests in .gclient.\n'
  272. 'Alternatively, do:\n'
  273. ' $ cd chrome/test/chromedriver/third_party\n'
  274. ' $ svn co %s java_tests' % java_tests_url)
  275. return 1
  276. results = []
  277. for filter in test_filters:
  278. results += _Run(
  279. java_tests_src_dir=java_tests_src_dir,
  280. test_filter=filter,
  281. chromedriver_path=options.chromedriver,
  282. chrome_path=util.GetAbsolutePathOfUserPath(options.chrome),
  283. log_path=options.log_path,
  284. android_package_key=options.android_package,
  285. verbose=options.verbose,
  286. debug=options.debug)
  287. return PrintTestResults(results)
  288. finally:
  289. environment.GlobalTearDown()
  290. if __name__ == '__main__':
  291. sys.exit(main())