Skip to content

Commit 6a8213c

Browse files
committed
test: Speed up test/Misc/verify-swift-feature-testing.test-sh some more
Instead of first invoking `grep` to get a list of files with matches, and then invoking it again on each file to find lines with matches, invoke it once on the entire test suite to get a list of paths and lines with matches, and parse that output into a dictionary that maps file paths to lists of lines. This further reduces run time from ~2.5s to ~1s.
1 parent c91e295 commit 6a8213c

File tree

1 file changed

+53
-61
lines changed

1 file changed

+53
-61
lines changed

test/Misc/verify-swift-feature-testing.test-sh

Lines changed: 53 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -33,59 +33,13 @@ ENABLE_FEATURE_RE = re.compile(
3333
FEATURE_LIT_MARKER_RE = re.compile(r"swift_feature_([A-Za-z0-9]*)")
3434

3535

36-
def find_test_files(swift_src_root):
37-
# Look for every test file in the test directories with `REQUIRES` lines
38-
# that mention `swift_feature_`.
39-
# Look for every test file in the test directories with `RUN` lines that
40-
# mention `-enable-experimental-feature` or `-enable-upcoming-feature`.
41-
# Be careful to not use RUN or REQUIRES with a colon after them or Lit will
42-
# pick them up.
43-
output = subprocess.check_output(
44-
[
45-
"grep",
46-
"--extended-regexp",
47-
"--recursive",
48-
"-e",
49-
"REQUIRES[:].*swift_feature_",
50-
"-e",
51-
"RUN[:].*-enable-(experimental|upcoming)-feature",
52-
"--files-with-matches",
53-
str(swift_src_root / "test"),
54-
str(swift_src_root / "validation-test"),
55-
],
56-
text=True,
57-
)
58-
return output.splitlines()
59-
60-
61-
def find_run_and_requires_lines(test_file):
62-
# Be careful to not use RUN or REQUIRES with a colon after them or Lit will
63-
# pick them up.
64-
output = subprocess.check_output(
65-
[
66-
"grep",
67-
"--extended-regexp",
68-
"--no-filename",
69-
"-e",
70-
"RUN[:]",
71-
"-e",
72-
"REQUIRES[:]",
73-
test_file,
74-
],
75-
text=True,
76-
)
77-
return output.splitlines()
78-
79-
80-
def check_test_file(test_file, existing_swift_features):
81-
enabled_features = set()
82-
required_features = set()
83-
84-
for line in find_run_and_requires_lines(test_file):
85-
enabled_features.update(feature for feature in ENABLE_FEATURE_RE.findall(line))
86-
required_features.update(
87-
feature for feature in FEATURE_LIT_MARKER_RE.findall(line)
88-
)
36+
def check_test_file(file_path, lines, existing_swift_features):
37+
enabled_features = {
38+
feature for line in lines for feature in ENABLE_FEATURE_RE.findall(line)
39+
}
40+
required_features = {
41+
feature for line in lines for feature in FEATURE_LIT_MARKER_RE.findall(line)
42+
}
8943

9044
had_error = False
9145

@@ -97,7 +51,7 @@ def check_test_file(test_file, existing_swift_features):
9751
# Be careful to not use RUN with a colon after it or Lit will pick
9852
# it up.
9953
print(
100-
f"{test_file}: error: unknown feature '{feature}' enabled in 'RUN"
54+
f"{file_path}: error: unknown feature '{feature}' enabled in 'RUN"
10155
+ ":' line"
10256
)
10357
had_error = True
@@ -108,7 +62,7 @@ def check_test_file(test_file, existing_swift_features):
10862
# Be careful to not use REQUIRES with a colon after it or Lit will pick
10963
# it up.
11064
print(
111-
f"{test_file}: error: unknown feature '{feature}' in 'REQUIRES"
65+
f"{file_path}: error: unknown feature '{feature}' in 'REQUIRES"
11266
+ f":' line: swift_feature_{feature}"
11367
)
11468
had_error = True
@@ -123,20 +77,49 @@ def check_test_file(test_file, existing_swift_features):
12377
# Be careful to not use REQUIRES with a colon after it or Lit will pick
12478
# it up.
12579
print(
126-
f"{test_file}: error: file enables '{feature}' but is missing '// REQUIRES"
80+
f"{file_path}: error: file enables '{feature}' but is missing '// REQUIRES"
12781
+ f": swift_feature_{feature}'"
12882
)
12983
had_error = True
13084

13185
for feature in required_features.difference(enabled_features):
13286
print(
133-
f"{test_file}: error: file requires 'swift_feature_{feature}' but does not enable '{feature}'"
87+
f"{file_path}: error: file requires 'swift_feature_{feature}' but does not enable '{feature}'"
13488
)
13589
had_error = True
13690

13791
return had_error
13892

13993

94+
def find_matches(swift_src_root):
95+
# Look for every `REQUIRES` line that mentions `swift_feature_` in the
96+
# test directories.
97+
# Look for every `RUN` line that mentions `-enable-experimental-feature` or
98+
# `-enable-upcoming-feature` in the test directories.
99+
output = subprocess.check_output(
100+
[
101+
"grep",
102+
"--extended-regexp",
103+
"--recursive",
104+
# Separate paths from lines with a null char.
105+
"--null",
106+
"-e",
107+
# Be careful to not use REQUIRES with a colon after it or Lit will
108+
# pick it up.
109+
"REQUIRES[:].*swift_feature_",
110+
"-e",
111+
# Be careful to not use RUN with a colon after it or Lit will pick
112+
# it up.
113+
"RUN[:].*-enable-(experimental|upcoming)-feature",
114+
"test",
115+
"validation-test",
116+
],
117+
text=True,
118+
cwd=str(swift_src_root),
119+
)
120+
return output.splitlines()
121+
122+
140123
def main():
141124
if len(sys.argv) < 3:
142125
print("Invalid number of arguments.")
@@ -145,14 +128,23 @@ def main():
145128
swift_src_root = pathlib.Path(sys.argv[1])
146129
existing_swift_features = set(json.loads(sys.argv[2]))
147130

148-
had_error = False
131+
file_paths_to_lines = dict()
132+
133+
# Build a dictionary that maps file paths to lists of matching lines.
134+
for match in find_matches(swift_src_root):
135+
# '<path><zero-byte><line>'
136+
relative_file_path, line = match.split("\0")
149137

150-
for test_file in find_test_files(swift_src_root):
151138
# Skip if this is one of the exceptional files.
152-
if pathlib.Path(test_file).relative_to(swift_src_root) in EXCEPTIONAL_FILES:
139+
if pathlib.Path(relative_file_path) in EXCEPTIONAL_FILES:
153140
continue
154141

155-
if check_test_file(test_file, existing_swift_features):
142+
abs_file_path = swift_src_root / relative_file_path
143+
file_paths_to_lines.setdefault(abs_file_path, list()).append(line)
144+
145+
had_error = False
146+
for file_path, lines in file_paths_to_lines.items():
147+
if check_test_file(file_path, lines, existing_swift_features):
156148
had_error = True
157149

158150
if had_error:

0 commit comments

Comments
 (0)