Skip to content

Commit e5751af

Browse files
committed
[test] Verify usage of swift_feature_ markers without enabling features
When a feature is removed from `Features.def` or when a test removes all usages of `-enable-experimental/upcoming-feature` keeping the `REQUIRES:` lines around is probably a mistake. Warn about possibly missing flags if a `REQUIRES:` is found referencing a feature without the equivalent `-enable-*-feature` in a `RUN:` line.
1 parent fff1884 commit e5751af

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

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

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ EXCEPTIONAL_FILES = [
1818
FEATURE_USAGE_RE = re.compile(
1919
r"-enable-(?:experimental|upcoming)-feature (?:-Xfrontend )?([A-Za-z0-9]*)"
2020
)
21+
# Be careful of not using REQUIRES or RUN with a colon after them or Lit will
22+
# pick them up.
23+
FEATURE_LIT_MARKER_RE = re.compile(r"swift_feature_([A-Za-z0-9]*)")
2124

2225

2326
def find_test_files_with_features_usage(swift_src_root):
@@ -38,6 +41,24 @@ def find_test_files_with_features_usage(swift_src_root):
3841
return output.splitlines()
3942

4043

44+
def find_test_files_with_marker_usage(swift_src_root):
45+
# Look for every test file in the test directories with `REQUIRES` lines
46+
# that mention `swift_feature_`.
47+
# Be careful of not using REQUIRES with a colon after them or Lit will
48+
# pick them up.
49+
output = subprocess.check_output([
50+
"grep",
51+
"--extended-regexp",
52+
"--recursive",
53+
"-e",
54+
"REQUIRES[:].*swift_feature_",
55+
"--files-with-matches",
56+
str(swift_src_root / "test"),
57+
str(swift_src_root / "validation-test"),
58+
], text=True)
59+
return output.splitlines()
60+
61+
4162
def find_run_lines(test_file):
4263
output = subprocess.check_output([
4364
"grep",
@@ -50,6 +71,18 @@ def find_run_lines(test_file):
5071
return output.splitlines()
5172

5273

74+
def find_requires_lines(test_file):
75+
output = subprocess.check_output([
76+
"grep",
77+
"--extended-regexp",
78+
"--no-filename",
79+
"-e",
80+
"REQUIRES[:]",
81+
str(test_file),
82+
], text=True)
83+
return output.splitlines()
84+
85+
5386
def check_existing_requires(test_file, feature):
5487
returncode = subprocess.call([
5588
"grep",
@@ -62,6 +95,21 @@ def check_existing_requires(test_file, feature):
6295
return returncode != 0
6396

6497

98+
def check_existing_feature_usage(test_file, feature):
99+
returncode = subprocess.call([
100+
"grep",
101+
"--extended-regexp",
102+
"--quiet",
103+
"-e",
104+
(
105+
"RUN[:].*-enable-(experimental|upcoming)-feature (-Xfrontend )?"
106+
+ re.escape(feature)
107+
),
108+
str(test_file),
109+
])
110+
return returncode != 0
111+
112+
65113
def check_existing_error_message_checks(test_file, feature):
66114
returncode = subprocess.call([
67115
"grep",
@@ -103,6 +151,30 @@ def check_test_file_feature_usage(test_file):
103151
return num_failures == 0
104152

105153

154+
def check_test_file_marker_usage(test_file):
155+
require_lines = find_requires_lines(test_file)
156+
features = set(
157+
feature
158+
for line in require_lines
159+
for feature in FEATURE_LIT_MARKER_RE.findall(line)
160+
)
161+
num_failures = 0
162+
for feature in features:
163+
# No warning if -enable-experimental/upcoming-feature is there
164+
if not check_existing_feature_usage(test_file, feature):
165+
continue
166+
167+
# For everything else, print a warning and add to the invalid exit code
168+
print(
169+
"error: {}: Missing '-enable-experimental/upcoming-feature: {}'".format(
170+
str(test_file),
171+
feature
172+
)
173+
)
174+
num_failures += 1
175+
return num_failures == 0
176+
177+
106178
def main():
107179
if len(sys.argv) < 2:
108180
print('Invalid number of arguments.')
@@ -121,6 +193,17 @@ def main():
121193
if not check_test_file_feature_usage(test_file):
122194
num_failures += 1
123195

196+
test_files_with_marker_usage = find_test_files_with_marker_usage(swift_src_root)
197+
for test_file in test_files_with_marker_usage:
198+
test_file = pathlib.Path(test_file)
199+
200+
# First lets check this is not one of the exceptional files
201+
if test_file.relative_to(swift_src_root) in EXCEPTIONAL_FILES:
202+
continue
203+
204+
if not check_test_file_marker_usage(test_file):
205+
num_failures += 1
206+
124207
if num_failures > 0:
125208
sys.exit(1)
126209

0 commit comments

Comments
 (0)