OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """A test runner for gtest application tests.""" | 6 """A test runner for gtest application tests.""" |
7 | 7 |
8 import logging | 8 import logging |
9 import os | 9 import os |
10 import platform | 10 import platform |
11 import subprocess | 11 import subprocess |
12 import sys | 12 import sys |
13 | 13 |
14 _logging = logging.getLogger() | 14 _logging = logging.getLogger() |
15 | 15 |
16 from mopy.gtest_list_tests import gtest_list_tests | 16 from mopy.gtest_list_tests import gtest_list_tests |
17 | 17 |
| 18 |
| 19 def print_output(command_line, output): |
| 20 print command_line |
| 21 print 72 * '-' |
| 22 print output |
| 23 print 72 * '-' |
| 24 |
| 25 |
| 26 def try_command_line(command_line): |
| 27 """Returns the output of a command line or an empty string on error.""" |
| 28 _logging.debug("Running command line: %s" % command_line) |
| 29 try: |
| 30 output = subprocess.check_output(command_line, stderr=subprocess.STDOUT) |
| 31 return output |
| 32 except subprocess.CalledProcessError as e: |
| 33 print "Failed with exit code %d, command line, and output:" % e.returncode |
| 34 print_output(command_line, e.output) |
| 35 except Exception as e: |
| 36 print "Failed with command line and exception:" |
| 37 print_output(command_line, e) |
| 38 return None |
| 39 |
| 40 |
| 41 def get_fixtures(command_line): |
| 42 """Returns the "Test.Fixture" list from a --gtest_list_tests commandline.""" |
| 43 list_output = try_command_line(command_line) |
| 44 _logging.debug("Tests listed:\n%s" % list_output) |
| 45 try: |
| 46 return gtest_list_tests(list_output) |
| 47 except Exception as e: |
| 48 print "Failed to get test fixtures with command line and exception:" |
| 49 print_output(command_line, e) |
| 50 return [] |
| 51 |
| 52 |
| 53 def run_test(command_line): |
| 54 """Runs a command line and checks the output for signs of gtest failure.""" |
| 55 output = try_command_line(command_line) |
| 56 # Fail on output with gtest's "[ FAILED ]" or a lack of "[ PASSED ]". |
| 57 # The latter condition ensures failure on broken command lines or output. |
| 58 # Check output instead of exit codes because mojo_shell always exits with 0. |
| 59 if output.find("[ FAILED ]") != -1 or output.find("[ PASSED ]") == -1: |
| 60 print "Failed test with command line and output:" |
| 61 print_output(command_line, output) |
| 62 return False |
| 63 _logging.debug("Succeeded with output:\n%s" % output) |
| 64 return True |
| 65 |
| 66 |
18 def main(argv): | 67 def main(argv): |
19 logging.basicConfig() | 68 logging.basicConfig() |
20 # Uncomment to debug: | 69 # Uncomment to debug: |
21 # _logging.setLevel(logging.DEBUG) | 70 # _logging.setLevel(logging.DEBUG) |
22 | 71 |
23 if len(argv) != 3: | 72 if len(argv) != 3: |
24 print "Usage: %s gtest_app_list_file root_dir" % os.path.basename(argv[0]) | 73 print "Usage: %s gtest_app_list_file root_dir" % os.path.basename(argv[0]) |
25 return 0 | 74 return 0 |
26 | 75 |
27 _logging.debug("Test list file: %s", argv[1]) | 76 _logging.debug("Test list file: %s", argv[1]) |
28 with open(argv[1], 'rb') as f: | 77 with open(argv[1], 'rb') as f: |
29 apptest_list = [y for y in [x.strip() for x in f.readlines()] \ | 78 apptest_list = [y for y in [x.strip() for x in f.readlines()] \ |
30 if y and y[0] != '#'] | 79 if y and y[0] != '#'] |
31 _logging.debug("Test list: %s" % apptest_list) | 80 _logging.debug("Test list: %s" % apptest_list) |
32 | 81 |
33 # Run gtests with color if we're on a TTY (and we're not being told explicitly | 82 # Run gtests with color if we're on a TTY (and we're not being told explicitly |
34 # what to do). | 83 # what to do). |
35 if sys.stdout.isatty() and 'GTEST_COLOR' not in os.environ: | 84 if sys.stdout.isatty() and 'GTEST_COLOR' not in os.environ: |
36 _logging.debug("Setting GTEST_COLOR=yes") | 85 _logging.debug("Setting GTEST_COLOR=yes") |
37 os.environ['GTEST_COLOR'] = 'yes' | 86 os.environ['GTEST_COLOR'] = 'yes' |
38 | 87 |
39 mojo_shell = "./" + argv[2] + "/mojo_shell" | 88 mojo_shell = "./" + argv[2] + "/mojo_shell" |
40 if platform.system() == 'Windows': | 89 if platform.system() == 'Windows': |
41 mojo_shell += ".exe" | 90 mojo_shell += ".exe" |
42 | 91 |
| 92 exit_code = 0 |
43 for apptest in apptest_list: | 93 for apptest in apptest_list: |
44 print "Running " + apptest + "...", | 94 print "Running " + apptest + "...", |
45 sys.stdout.flush() | 95 sys.stdout.flush() |
46 | 96 |
47 # List the apptest fixtures so they can be run independently for isolation. | 97 # List the apptest fixtures so they can be run independently for isolation. |
48 # TODO(msw): Run some apptests without fixture isolation? | 98 # TODO(msw): Run some apptests without fixture isolation? |
49 list_command_line = [mojo_shell, apptest + " --gtest_list_tests"] | 99 command = [mojo_shell, |
50 _logging.debug("Listing tests: %s" % list_command_line) | 100 "--args-for={0} --gtest_list_tests".format(apptest), |
51 try: | 101 apptest] |
52 # TODO(msw): Need to fail on errors! mojo_shell always exits with 0! | 102 fixtures = get_fixtures(command) |
53 list_output = subprocess.check_output(list_command_line) | |
54 _logging.debug("Tests listed:\n%s" % list_output) | |
55 except subprocess.CalledProcessError as e: | |
56 print "Failed with exit code %d and output:" % e.returncode | |
57 print 72 * '-' | |
58 print e.output | |
59 print 72 * '-' | |
60 return 1 | |
61 except OSError as e: | |
62 print " Failed to start test" | |
63 return 1 | |
64 | 103 |
65 test_list = gtest_list_tests(list_output) | 104 if not fixtures: |
66 for test in test_list: | 105 print "Failed with no tests found." |
67 # TODO(msw): enable passing arguments to tests down from the test harness. | 106 exit_code = 1 |
68 command_line = [ | 107 continue |
69 mojo_shell, | 108 |
| 109 apptest_result = "Succeeded" |
| 110 for fixture in fixtures: |
| 111 # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg. |
| 112 # TODO(msw): Enable passing arguments to tests down from the test harness. |
| 113 command = [mojo_shell, |
70 "--args-for={0} --example_apptest_arg --gtest_filter={1}".format( | 114 "--args-for={0} --example_apptest_arg --gtest_filter={1}".format( |
71 apptest, test), | 115 apptest, fixture), |
72 apptest] | 116 apptest] |
| 117 if not run_test(command): |
| 118 apptest_result = "Failed test(s) in " + apptest |
| 119 exit_code = 1 |
| 120 print apptest_result |
73 | 121 |
74 _logging.debug("Running %s..." % command_line) | 122 return exit_code |
75 try: | |
76 # TODO(msw): Need to fail on errors! mojo_shell always exits with 0! | |
77 subprocess.check_output(command_line, stderr=subprocess.STDOUT) | |
78 _logging.debug("Succeeded") | |
79 except subprocess.CalledProcessError as e: | |
80 print "Failed with exit code %d and output:" % e.returncode | |
81 print 72 * '-' | |
82 print e.output | |
83 print 72 * '-' | |
84 return 1 | |
85 except OSError as e: | |
86 print " Failed to start test" | |
87 return 1 | |
88 print "Succeeded" | |
89 | |
90 return 0 | |
91 | 123 |
92 if __name__ == '__main__': | 124 if __name__ == '__main__': |
93 sys.exit(main(sys.argv)) | 125 sys.exit(main(sys.argv)) |
OLD | NEW |