-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtests-from-target.py
executable file
·90 lines (81 loc) · 3.32 KB
/
tests-from-target.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/python
# Have you ever been annoyed by having to manually harvest test class names so
# that you can run a comprehensive set of tests from a Chromium subcomponent?
# Yes, well, me too! And here's the solution for it.
#
# This script generates a Google Test formatted filter string using all C++ test
# classes it can find given an output dir and one or more GN targets. For
# instance this call:
#
# tests-from-target.py out_linux/Debug components/offline_pages/core/background:unit_tests
#
# Generates this output as of today:
#
# AddRequestTaskTest.*:ChangeRequestsStateTaskTest.*:CleanupTaskTest.*:
# GetRequestsTaskTest.*:InitializeStoreTaskTest.*:MarkAttemptAbortedTaskTest.*:
# MarkAttemptCompletedTaskTest.*:MarkAttemptStartedTaskTest.*:
# PickRequestTaskTest.*:ReconcileTaskTest.*:RemoveRequestsTaskTest.*:
# RequestCoordinatorEventLoggerTest.*:RequestCoordinatorTest.*:
# RequestQueueStoreSQLTest.*:RequestQueueTest.*:SavePageRequestTest.*
#
# The most common usage case will be to use your shell's command substitution so
# that the script populates the filter argument of your test execution call.
# For Bash it would be something like this (if you are cool and use cr! ;):
#
# cr run components_unittests --gtest_filter=$(tests-from-target.py <OUT_DIR> <GN_TEST_TARGET>)
import sys
import re
import os.path
import subprocess
def eprint(text):
print >> sys.stderr, text
def GetGnSourcesFor(output_dir, gn_target):
command = ["gn", "desc", output_dir, gn_target, "sources"]
try:
output = subprocess.check_output(command, shell=False)
except subprocess.CalledProcessError as e:
eprint("GN call failed with error code %s for command: %s"
% (e.returncode, " ".join(command)))
exit(e.returncode)
gn_sources = output.splitlines()
return gn_sources
def GetGnSourcesForAllTargets(output_dir, gn_targets):
all_gn_sources = set()
for gn_target in gn_targets:
all_gn_sources.update(GetGnSourcesFor(output_dir, gn_target))
return all_gn_sources
def ParseTestClasses(filename):
with open(filename) as gtest_file:
contents = gtest_file.read()
test_class_name_regex = re.compile(r"\n(?:TEST|TEST_F)\(\s*(\w+)\s*,[^\)]+\)")
test_classes = set()
for match in test_class_name_regex.finditer(contents):
test_classes.add(match.group(1))
return test_classes
def ClassNamesFromGnSources(gn_sources):
all_test_classes = set()
for source_file in gn_sources:
actual_file_name = source_file[2:]
if os.path.isfile(actual_file_name):
all_test_classes |= ParseTestClasses(actual_file_name)
else:
eprint("Couldn't find file from source: %s" % (source_file,))
return all_test_classes
def BuildGoogleTestFilterString(test_class_names):
filters = []
for class_name in test_class_names:
filters.append(class_name + ".*")
filters.sort()
return ":".join(filters)
if __name__ == "__main__":
if len(sys.argv) < 3:
command_only = os.path.basename(sys.argv[0])
eprint("%s: prints a Google Test filter string containing all tests from "
"GN targets' sources." % (command_only,))
eprint("")
eprint("Usage: %s <output_dir> <gn_target_1> <gn_target_2> ..."
% (command_only,))
exit(1)
gn_sources = GetGnSourcesForAllTargets(sys.argv[1], sys.argv[2:])
test_class_names = ClassNamesFromGnSources(gn_sources)
print BuildGoogleTestFilterString(test_class_names)