Skip to content

Commit 01abb1a

Browse files
authored
Add support for tests that fail at runtime (#418)
That is compilation must be successful, but running the test should return a non-zero exit code. This is useful for testing that code correctly asserts.
1 parent c7eb05d commit 01abb1a

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

libcudacxx/.upstream-tests/test/lit.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ if 'PYLINT_IMPORT' in os.environ:
1515
config.name = 'libcu++'
1616

1717
# suffixes: A list of file extensions to treat as test files.
18-
config.suffixes = ['.pass.cpp', '.fail.cpp', '.sh.cpp']
18+
config.suffixes = ['.pass.cpp', '.fail.cpp', '.runfail.cpp', '.sh.cpp']
1919

2020
# test_source_root: The root path where tests are located.
2121
config.test_source_root = os.path.dirname(__file__)

libcudacxx/.upstream-tests/utils/libcudacxx/test/format.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class LibcxxTestFormat(object):
2929
FOO.pass.cpp - Executable test which should compile, run, and exit with
3030
code 0.
3131
FOO.fail.cpp - Negative test case which is expected to fail compilation.
32+
FOO.runfail.cpp - Negative test case which is expected to compile, run,
33+
and exit with non-zero exit code.
3234
FOO.sh.cpp - A test that uses LIT's ShTest format.
3335
"""
3436

@@ -88,6 +90,7 @@ def _execute(self, test, lit_config):
8890
is_sh_test = name_root.endswith('.sh')
8991
is_pass_test = name.endswith('.pass.cpp') or name.endswith('.pass.mm')
9092
is_fail_test = name.endswith('.fail.cpp') or name.endswith('.fail.mm')
93+
is_runfail_test = name.endswith('.runfail.cpp') or name.endswith('.runfail.mm')
9194
is_objcxx_test = name.endswith('.mm')
9295
is_objcxx_arc_test = name.endswith('.arc.pass.mm') or \
9396
name.endswith('.arc.fail.mm')
@@ -166,6 +169,10 @@ def _execute(self, test, lit_config):
166169
elif is_pass_test:
167170
return self._evaluate_pass_test(test, tmpBase, lit_config,
168171
test_cxx, parsers)
172+
elif is_runfail_test:
173+
return self._evaluate_pass_test(test, tmpBase, lit_config,
174+
test_cxx, parsers,
175+
run_should_pass=False)
169176
else:
170177
# No other test type is supported
171178
assert False
@@ -174,7 +181,7 @@ def _clean(self, exec_path): # pylint: disable=no-self-use
174181
libcudacxx.util.cleanFile(exec_path)
175182

176183
def _evaluate_pass_test(self, test, tmpBase, lit_config,
177-
test_cxx, parsers):
184+
test_cxx, parsers, run_should_pass=True):
178185
execDir = os.path.dirname(test.getExecPath())
179186
source_path = test.getSourcePath()
180187
exec_path = tmpBase + '.exe'
@@ -210,14 +217,18 @@ def _evaluate_pass_test(self, test, tmpBase, lit_config,
210217
env)
211218
report = "Compiled With: '%s'\n" % ' '.join(compile_cmd)
212219
report += libcudacxx.util.makeReport(cmd, out, err, rc)
213-
if rc == 0:
220+
result_expected = (rc == 0) == run_should_pass
221+
if result_expected:
214222
res = lit.Test.PASS if retry_count == 0 else lit.Test.FLAKYPASS
215223
return lit.Test.Result(res, report)
216224
# Rarely devices are unavailable, so just restart the test to avoid false negatives.
217225
elif rc != 0 and "cudaErrorDevicesUnavailable" in out and max_retry <= 5:
218226
max_retry += 1
219-
elif rc != 0 and retry_count + 1 >= max_retry:
220-
report += "Compiled test failed unexpectedly!"
227+
elif retry_count + 1 == max_retry:
228+
if run_should_pass:
229+
report += "Compiled test failed unexpectedly!"
230+
else:
231+
report += "Compiled test succeeded unexpectedly!"
221232
return lit.Test.Result(lit.Test.FAIL, report)
222233

223234
assert False # Unreachable

libcudacxx/libcxx/utils/libcxx/test/format.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class LibcxxTestFormat(object):
2929
FOO.pass.cpp - Executable test which should compile, run, and exit with
3030
code 0.
3131
FOO.fail.cpp - Negative test case which is expected to fail compilation.
32+
FOO.runfail.cpp - Negative test case which is expected to compile, run,
33+
and exit with non-zero exit code.
3234
FOO.sh.cpp - A test that uses LIT's ShTest format.
3335
"""
3436

@@ -88,6 +90,7 @@ def _execute(self, test, lit_config):
8890
is_sh_test = name_root.endswith('.sh')
8991
is_pass_test = name.endswith('.pass.cpp') or name.endswith('.pass.mm')
9092
is_fail_test = name.endswith('.fail.cpp') or name.endswith('.fail.mm')
93+
is_runfail_test = name.endswith('.runfail.cpp') or name.endswith('.runfail.mm')
9194
is_objcxx_test = name.endswith('.mm')
9295
is_objcxx_arc_test = name.endswith('.arc.pass.mm') or \
9396
name.endswith('.arc.fail.mm')
@@ -163,15 +166,18 @@ def _execute(self, test, lit_config):
163166
elif is_pass_test:
164167
return self._evaluate_pass_test(test, tmpBase, lit_config,
165168
test_cxx, parsers)
169+
elif is_runfail_test:
170+
return self._evaluate_pass_test(test, tmpBase, lit_config,
171+
test_cxx, parsers,
172+
run_should_pass=False)
166173
else:
167-
# No other test type is supported
168-
assert False
174+
assert False and "no other test" # No other test type is supported
169175

170176
def _clean(self, exec_path): # pylint: disable=no-self-use
171177
libcxx.util.cleanFile(exec_path)
172178

173179
def _evaluate_pass_test(self, test, tmpBase, lit_config,
174-
test_cxx, parsers):
180+
test_cxx, parsers, run_should_pass=True):
175181
execDir = os.path.dirname(test.getExecPath())
176182
source_path = test.getSourcePath()
177183
exec_path = tmpBase + '.exe'
@@ -207,11 +213,15 @@ def _evaluate_pass_test(self, test, tmpBase, lit_config,
207213
env)
208214
report = "Compiled With: '%s'\n" % ' '.join(compile_cmd)
209215
report += libcxx.util.makeReport(cmd, out, err, rc)
210-
if rc == 0:
216+
result_expected = (rc == 0) == run_should_pass
217+
if result_expected:
211218
res = lit.Test.PASS if retry_count == 0 else lit.Test.FLAKYPASS
212219
return lit.Test.Result(res, report)
213-
elif rc != 0 and retry_count + 1 == max_retry:
214-
report += "Compiled test failed unexpectedly!"
220+
elif retry_count + 1 == max_retry:
221+
if run_should_pass:
222+
report += "Compiled test failed unexpectedly!"
223+
else:
224+
report += "Compiled test succeeded unexpectedly!"
215225
return lit.Test.Result(lit.Test.FAIL, report)
216226

217227
assert False # Unreachable

0 commit comments

Comments
 (0)