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 "smart" test runner for gtest unit tests (that caches successes).""" | 6 """A "smart" test runner for gtest unit tests (that caches successes).""" |
7 | 7 |
8 import argparse | 8 import argparse |
9 import ast | 9 import ast |
10 import logging | 10 import logging |
11 import os | 11 import os |
12 import platform | 12 import platform |
13 import subprocess | 13 import subprocess |
14 import sys | 14 import sys |
15 | 15 |
16 _logging = logging.getLogger() | 16 _logging = logging.getLogger() |
17 | 17 |
18 import mopy.gtest | 18 import mopy.gtest |
| 19 from mopy.config import Config |
| 20 from mopy.gn import ConfigForGNArgs, ParseGNConfig |
19 from mopy.paths import Paths | 21 from mopy.paths import Paths |
20 from mopy.transitive_hash import file_hash, transitive_hash | 22 from mopy.transitive_hash import file_hash, transitive_hash |
21 | 23 |
22 paths = Paths() | 24 paths = Paths() |
23 | 25 |
24 def main(): | 26 def main(): |
25 logging.basicConfig() | 27 logging.basicConfig() |
26 # Uncomment to debug: | 28 # Uncomment to debug: |
27 # _logging.setLevel(logging.DEBUG) | 29 # _logging.setLevel(logging.DEBUG) |
28 | 30 |
29 parser = argparse.ArgumentParser( | 31 parser = argparse.ArgumentParser( |
30 description="A 'smart' test runner for gtest unit tests (that caches " | 32 description="A 'smart' test runner for gtest unit tests (that caches " |
31 "successes).") | 33 "successes).") |
32 | 34 |
33 os_group = parser.add_mutually_exclusive_group() | |
34 os_group.add_argument("--android", help="Run tests for android", | |
35 action='store_true') | |
36 | |
37 parser.add_argument("gtest_list_file", | 35 parser.add_argument("gtest_list_file", |
38 help="The file containing the tests to run.", | 36 help="The file containing the tests to run.", |
39 type=file) | 37 type=file) |
40 parser.add_argument("root_dir", help="The build directory.") | 38 parser.add_argument("root_dir", help="The build directory.") |
41 parser.add_argument("successes_cache_filename", | 39 parser.add_argument("successes_cache_filename", |
42 help="The file caching test results.", default=None, | 40 help="The file caching test results.", default=None, |
43 nargs='?') | 41 nargs='?') |
44 args = parser.parse_args() | 42 args = parser.parse_args() |
45 | 43 |
46 _logging.debug("Test list file: %s", args.gtest_list_file) | 44 _logging.debug("Test list file: %s", args.gtest_list_file) |
47 gtest_list = ast.literal_eval(args.gtest_list_file.read()) | 45 gtest_list = ast.literal_eval(args.gtest_list_file.read()) |
48 _logging.debug("Test list: %s" % gtest_list) | 46 _logging.debug("Test list: %s" % gtest_list) |
49 | 47 |
| 48 config = ConfigForGNArgs(ParseGNConfig(args.root_dir)) |
| 49 |
50 print "Running tests in directory: %s" % args.root_dir | 50 print "Running tests in directory: %s" % args.root_dir |
51 os.chdir(args.root_dir) | 51 os.chdir(args.root_dir) |
52 | 52 |
53 if args.successes_cache_filename: | 53 if args.successes_cache_filename: |
54 print "Successes cache file: %s" % args.successes_cache_filename | 54 print "Successes cache file: %s" % args.successes_cache_filename |
55 else: | 55 else: |
56 print "No successes cache file (will run all tests unconditionally)" | 56 print "No successes cache file (will run all tests unconditionally)" |
57 | 57 |
58 if args.successes_cache_filename: | 58 if args.successes_cache_filename: |
59 # This file simply contains a list of transitive hashes of tests that | 59 # This file simply contains a list of transitive hashes of tests that |
(...skipping 11 matching lines...) Expand all Loading... |
71 successes = set() | 71 successes = set() |
72 | 72 |
73 mopy.gtest.set_color() | 73 mopy.gtest.set_color() |
74 | 74 |
75 # TODO(vtl): We may not close this file on failure. | 75 # TODO(vtl): We may not close this file on failure. |
76 successes_cache_file = open(args.successes_cache_filename, 'ab') \ | 76 successes_cache_file = open(args.successes_cache_filename, 'ab') \ |
77 if args.successes_cache_filename else None | 77 if args.successes_cache_filename else None |
78 for gtest_dict in gtest_list: | 78 for gtest_dict in gtest_list: |
79 if gtest_dict.get("disabled"): | 79 if gtest_dict.get("disabled"): |
80 continue | 80 continue |
81 if args.android and not gtest_dict.get("run_on_android"): | 81 if not config.match_target_os(gtest_dict.get("target_os", [])): |
82 continue | 82 continue |
83 | 83 |
84 gtest = gtest_dict["test"] | 84 gtest = gtest_dict["test"] |
85 cacheable = gtest_dict.get("cacheable", True) | 85 cacheable = gtest_dict.get("cacheable", True) |
86 if not cacheable: | 86 if not cacheable: |
87 _logging.debug("%s is marked as non-cacheable" % gtest) | 87 _logging.debug("%s is marked as non-cacheable" % gtest) |
88 | 88 |
89 gtest_file = gtest | 89 gtest_file = gtest |
90 if platform.system() == 'Windows': | 90 if platform.system() == 'Windows': |
91 gtest_file += ".exe" | 91 gtest_file += ".exe" |
92 if args.android: | 92 if config.target_os == Config.OS_ANDROID: |
93 gtest_file = gtest + "_apk/" + gtest + "-debug.apk" | 93 gtest_file = gtest + "_apk/" + gtest + "-debug.apk" |
94 | 94 |
95 if successes_cache_file and cacheable: | 95 if successes_cache_file and cacheable: |
96 _logging.debug("Getting transitive hash for %s ... " % gtest) | 96 _logging.debug("Getting transitive hash for %s ... " % gtest) |
97 try: | 97 try: |
98 if args.android: | 98 if config.target_os == Config.OS_ANDROID: |
99 gtest_hash = file_hash(gtest_file) | 99 gtest_hash = file_hash(gtest_file) |
100 else: | 100 else: |
101 gtest_hash = transitive_hash(gtest_file) | 101 gtest_hash = transitive_hash(gtest_file) |
102 except subprocess.CalledProcessError: | 102 except subprocess.CalledProcessError: |
103 print "Failed to get transitive hash for %s" % gtest | 103 print "Failed to get transitive hash for %s" % gtest |
104 return 1 | 104 return 1 |
105 _logging.debug(" Transitive hash: %s" % gtest_hash) | 105 _logging.debug(" Transitive hash: %s" % gtest_hash) |
106 | 106 |
107 if gtest_hash in successes: | 107 if gtest_hash in successes: |
108 print "Skipping %s (previously succeeded)" % gtest | 108 print "Skipping %s (previously succeeded)" % gtest |
109 continue | 109 continue |
110 | 110 |
111 print "Running %s...." % gtest, | 111 print "Running %s...." % gtest, |
112 sys.stdout.flush() | 112 sys.stdout.flush() |
113 try: | 113 try: |
114 if args.android: | 114 if config.target_os == Config.OS_ANDROID: |
115 command = [ | 115 command = [ |
116 "python", | 116 "python", |
117 os.path.join(paths.src_root, "build", "android", "test_runner.py"), | 117 os.path.join(paths.src_root, "build", "android", "test_runner.py"), |
118 "gtest", | 118 "gtest", |
119 "--output-directory", | 119 "--output-directory", |
120 args.root_dir, | 120 args.root_dir, |
121 "-s", | 121 "-s", |
122 gtest, | 122 gtest, |
123 ] | 123 ] |
124 else: | 124 else: |
(...skipping 15 matching lines...) Expand all Loading... |
140 print " Failed to start test" | 140 print " Failed to start test" |
141 return 1 | 141 return 1 |
142 print "All tests succeeded" | 142 print "All tests succeeded" |
143 if successes_cache_file: | 143 if successes_cache_file: |
144 successes_cache_file.close() | 144 successes_cache_file.close() |
145 | 145 |
146 return 0 | 146 return 0 |
147 | 147 |
148 if __name__ == '__main__': | 148 if __name__ == '__main__': |
149 sys.exit(main()) | 149 sys.exit(main()) |
OLD | NEW |