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
4 # found in the LICENSE file.
6 """A "smart" test runner for gtest unit tests (that caches successes)."""
13 _logging
= logging
.getLogger()
15 _script_dir
= os
.path
.dirname(os
.path
.abspath(__file__
))
16 sys
.path
.insert(0, os
.path
.join(_script_dir
, "pylib"))
18 from transitive_hash
import transitive_hash
23 # _logging.setLevel(logging.DEBUG)
25 if len(argv
) < 3 or len(argv
) > 4:
26 print "Usage: %s gtest_list_file root_dir [successes_cache_file]" % \
27 os
.path
.basename(argv
[0])
28 return 0 if len(argv
) < 2 else 1
30 _logging
.debug("Test list file: %s", argv
[1])
31 with
open(argv
[1], 'rb') as f
:
32 gtest_list
= [y
for y
in [x
.strip() for x
in f
.readlines()] \
34 _logging
.debug("Test list: %s" % gtest_list
)
36 print "Running tests in directory: %s" % argv
[2]
39 if len(argv
) == 4 and argv
[3]:
40 successes_cache_filename
= argv
[3]
41 print "Successes cache file: %s" % successes_cache_filename
43 successes_cache_filename
= None
44 print "No successes cache file (will run all tests unconditionally)"
46 if successes_cache_filename
:
47 # This file simply contains a list of transitive hashes of tests that
50 _logging
.debug("Trying to read successes cache file: %s",
51 successes_cache_filename
)
52 with
open(argv
[3], 'rb') as f
:
53 successes
= set([x
.strip() for x
in f
.readlines()])
54 _logging
.debug("Successes: %s", successes
)
56 # Just assume that it didn't exist, or whatever.
57 print "Failed to read successes cache file %s (will create)" % argv
[3]
60 # Run gtests with color if we're on a TTY (and we're not being told explicitly
62 if sys
.stdout
.isatty() and 'GTEST_COLOR' not in os
.environ
:
63 _logging
.debug("Setting GTEST_COLOR=yes")
64 os
.environ
['GTEST_COLOR'] = 'yes'
66 # TODO(vtl): We may not close this file on failure.
67 successes_cache_file
= open(successes_cache_filename
, 'ab') \
68 if successes_cache_filename
else None
69 for gtest
in gtest_list
:
72 _logging
.debug("%s is marked as non-cacheable" % gtest
)
77 if successes_cache_file
and cacheable
:
78 _logging
.debug("Getting transitive hash for %s ... " % gtest
)
80 gtest_hash
= transitive_hash(gtest
)
82 print "Failed to get transitive hash for %s" % gtest
84 _logging
.debug(" Transitive hash: %s" % gtest_hash
)
86 if gtest_hash
in successes
:
87 print "Skipping %s (previously succeeded)" % gtest
90 print "Running %s...." % gtest
,
93 subprocess
.check_output(["./" + gtest
], stderr
=subprocess
.STDOUT
)
96 if successes_cache_filename
and cacheable
:
97 successes
.add(gtest_hash
)
98 successes_cache_file
.write(gtest_hash
+ '\n')
99 successes_cache_file
.flush()
100 except subprocess
.CalledProcessError
as e
:
101 print "Failed with exit code %d and output:" % e
.returncode
107 print " Failed to start test"
109 print "All tests succeeded"
110 if successes_cache_file
:
111 successes_cache_file
.close()
115 if __name__
== '__main__':
116 sys
.exit(main(sys
.argv
))