Skip to content

Commit 70e0b74

Browse files
DinoVmeta-codesync[bot]
authored andcommitted
Reduce skip noise
Summary: This came up while talking to jbower-fb... With increased number of tests in buck we're also seeing increased skip noise which makes it hard to pick out genuine yellow signal on our diffs. This gets rid of all of the skips which are there for reasons which aren't really broken (e.g. only tested on a certain version of Python, tests that require the JIT in a certain state, unimplemented functionality covered by a task, etc...) There are a few skips that are left that look more like genuine issues - e.g. ASAN failures. Differential Revision: D87361902 fbshipit-source-id: 8720f11966eedaa9e16797f96e65880cab94ec53
1 parent 2299600 commit 70e0b74

46 files changed

Lines changed: 312 additions & 234 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cinderx/PythonLib/cinderx/test_support.py

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
import abc
55
import ctypes
66
import dis
7+
import functools
78
import importlib
89
import multiprocessing
910
import os.path
1011
import sys
1112
import tempfile
13+
import types
1214
import unittest
1315

1416
from contextlib import contextmanager
@@ -91,20 +93,78 @@ def compiles_after_one_call() -> bool:
9193
return cinderx.jit.get_compile_after_n_calls() == 0
9294

9395

96+
_FT = TypeVar("_FT", bound=Callable[..., object])
97+
98+
99+
# pyre-ignore[34]: Type variable isn't present in parameters
100+
def passAlways(reason: str) -> Callable[[_FT], _FT]:
101+
"""
102+
Force a test to always pass.
103+
Useful when `skip` is not desired
104+
(e.g. intentionally skipping tests that shouldn't be deleted)
105+
"""
106+
107+
def decorator(test_item: object) -> object:
108+
if isinstance(test_item, type):
109+
# apply this decorator to all "test_" methods of the test case
110+
for attr_name in dir(test_item):
111+
if attr_name.startswith("test_"):
112+
attr = getattr(test_item, attr_name)
113+
setattr(test_item, attr_name, passAlways(attr))
114+
115+
else:
116+
117+
@functools.wraps(test_item)
118+
def pass_wrapper(*args: object, **kwargs: object) -> None:
119+
return
120+
121+
test_item = pass_wrapper
122+
123+
test_item.__unittest_skip_why__ = reason
124+
return test_item
125+
126+
if isinstance(reason, types.FunctionType):
127+
test_item = reason
128+
reason = ""
129+
return decorator(test_item)
130+
# pyre-ignore[7]: bad return type
131+
return decorator
132+
133+
134+
# pyre-ignore[34]: Type variable isn't present in parameters
135+
def passIf(condition: object, reason: str) -> Callable[[_FT], _FT]:
136+
"""
137+
Force a test to pass if the condition is true.
138+
"""
139+
if condition:
140+
return passAlways(reason)
141+
return lambda obj: obj
142+
143+
144+
# pyre-ignore[34]: Type variable isn't present in parameters
145+
def passUnless(condition: object, reason: str) -> Callable[[_FT], _FT]:
146+
"""
147+
Force a test to pass unless the condition is true.
148+
"""
149+
if not condition:
150+
return passAlways(reason)
151+
return lambda obj: obj
152+
153+
94154
def skip_if_jit(reason: str) -> Callable[[Callable[..., None]], Callable[..., None]]:
95-
return unittest.skipIf(cinderx.jit.is_enabled(), reason)
155+
return passIf(cinderx.jit.is_enabled(), reason)
96156

97157

98158
def skip_unless_jit(
99159
reason: str,
100160
) -> Callable[[Callable[..., None]], Callable[..., None]]:
101-
return unittest.skipUnless(cinderx.jit.is_enabled(), reason)
161+
return passUnless(cinderx.jit.is_enabled(), reason)
102162

103163

104164
def skip_unless_lazy_imports(
105165
reason: str = "Depends on Lazy Imports being enabled",
106166
) -> Callable[[Callable[..., None]], Callable[..., None]]:
107-
return unittest.skipUnless(hasattr(importlib, "set_lazy_imports"), reason)
167+
return passUnless(hasattr(importlib, "set_lazy_imports"), reason)
108168

109169

110170
TRet = TypeVar("TRet")

cinderx/PythonLib/test_cinderx/test_asynclazyvalue.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from time import time
1616

1717
import cinderx.test_support as cinder_support
18+
from cinderx.test_support import passIf, passUnless
1819

1920

2021
if cinder_support.hasCinderX():
@@ -163,8 +164,8 @@ async def g(fut):
163164
except IndexError as e:
164165
self.assertTrue(type(e.__context__) is Exc)
165166

166-
@unittest.skipUnless(cinder_support.hasCinderX(), "Tests CinderX features")
167-
@unittest.skipIf(sys.version_info >= (3, 14), "no awaiter support")
167+
@passUnless(cinder_support.hasCinderX(), "Tests CinderX features")
168+
@passIf(sys.version_info >= (3, 14), "no awaiter support")
168169
@async_test
169170
async def test_get_awaiter(self) -> None:
170171
async def g(f):
@@ -194,8 +195,8 @@ async def f():
194195
self.assertIs(await_stack[0].cr_code, g.__code__)
195196
self.assertIs(await_stack[1], h_coro)
196197

197-
@unittest.skipUnless(cinder_support.hasCinderX(), "Tests CinderX features")
198-
@unittest.skipIf(sys.version_info >= (3, 14), "no awaiter support")
198+
@passUnless(cinder_support.hasCinderX(), "Tests CinderX features")
199+
@passIf(sys.version_info >= (3, 14), "no awaiter support")
199200
@async_test
200201
async def test_get_awaiter_from_gathered(self) -> None:
201202
async def g(f):

cinderx/PythonLib/test_cinderx/test_cinderjit.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@
3535
jit_suppress,
3636
jit_unsuppress,
3737
)
38+
3839
from cinderx.test_support import (
3940
CINDERX_PATH,
4041
compiles_after_one_call,
4142
ENCODING,
43+
passIf,
44+
passUnless,
4245
run_in_subprocess,
4346
skip_unless_jit,
4447
)
@@ -138,7 +141,7 @@ def func_that_change_defaults():
138141

139142
class InlinedFunctionTests(unittest.TestCase):
140143
@jit_suppress
141-
@unittest.skipIf(
144+
@passIf(
142145
not cinderx.jit.is_hir_inliner_enabled(),
143146
"meaningless without HIR inliner enabled",
144147
)
@@ -151,7 +154,7 @@ def test_deopt_when_func_defaults_change(self) -> None:
151154

152155
class InlineCacheStatsTests(unittest.TestCase):
153156
@jit_suppress
154-
@unittest.skipIf(
157+
@passIf(
155158
not cinderx.jit.is_inline_cache_stats_collection_enabled(),
156159
"meaningless without inline cache stats collection enabled",
157160
)
@@ -217,7 +220,7 @@ def trigger_load_method_with_stats():
217220

218221
class InlinedFunctionLineNumberTests(unittest.TestCase):
219222
@jit_suppress
220-
@unittest.skipIf(
223+
@passIf(
221224
not cinderx.jit.is_hir_inliner_enabled(),
222225
"meaningless without HIR inliner enabled",
223226
)
@@ -235,7 +238,7 @@ def test_line_numbers_with_sibling_inlined_functions(self) -> None:
235238
self.assertEqual(stacks[1][-2].lineno, firstlineno(get_stack_siblings) + 2)
236239

237240
@jit_suppress
238-
@unittest.skipIf(
241+
@passIf(
239242
not cinderx.jit.is_hir_inliner_enabled(),
240243
"meaningless without HIR inliner enabled",
241244
)
@@ -251,7 +254,7 @@ def test_line_numbers_at_multiple_points_in_inlined_functions(self) -> None:
251254
self.assertEqual(stacks[1][-2].lineno, firstlineno(call_get_stack_multi) + 3)
252255

253256
@jit_suppress
254-
@unittest.skipIf(
257+
@passIf(
255258
not cinderx.jit.is_hir_inliner_enabled(),
256259
"meaningless without HIR inliner enabled",
257260
)
@@ -271,7 +274,7 @@ def test_inline_function_stats(self) -> None:
271274
)
272275

273276
@jit_suppress
274-
@unittest.skipIf(
277+
@passIf(
275278
not cinderx.jit.is_hir_inliner_enabled(),
276279
"meaningless without HIR inliner enabled",
277280
)
@@ -1573,7 +1576,7 @@ def g():
15731576
if compiles_after_one_call():
15741577
self.assertTrue(is_jit_compiled(g))
15751578

1576-
@unittest.skipIf(
1579+
@passIf(
15771580
not cinderx.jit.is_hir_inliner_enabled(),
15781581
"meaningless without HIR inliner enabled",
15791582
)
@@ -1603,9 +1606,8 @@ def test_max_code_size_slow(self) -> None:
16031606
# TODO(T240152676): Improve stability of this test
16041607
call_limit = cinderx.jit.get_compile_after_n_calls()
16051608
if call_limit is None or call_limit > 10000:
1606-
raise unittest.SkipTest(
1607-
"Expecting the JIT to be compiling a bunch of code automatically"
1608-
)
1609+
# Expecting the JIT to be compiling a bunch of code automatically
1610+
return
16091611

16101612
code = textwrap.dedent(
16111613
"""
@@ -1827,14 +1829,14 @@ def foo(self):
18271829

18281830

18291831
class OtherTests(unittest.TestCase):
1830-
@unittest.skipIf(
1832+
@passIf(
18311833
not cinderx.jit.is_enabled(),
18321834
"meaningless without JIT enabled",
18331835
)
18341836
def test_mlock_profiler_dependencies(self) -> None:
18351837
cinderx.jit.mlock_profiler_dependencies()
18361838

1837-
@unittest.skipUnless(cinderx.jit.is_enabled(), "not jitting")
1839+
@passUnless(cinderx.jit.is_enabled(), "not jitting")
18381840
def test_page_in_profiler_dependencies(self) -> None:
18391841
qualnames = cinderx.jit.page_in_profiler_dependencies()
18401842
self.assertTrue(len(qualnames) > 0)
@@ -2419,7 +2421,7 @@ def builtins_getter():
24192421
return _testcindercapi._pyeval_get_builtins()
24202422

24212423

2422-
@unittest.skipIf(AT_LEAST_312, "T214641462: _testcindercapi is only in 3.10.cinder")
2424+
@passIf(AT_LEAST_312, "T214641462: _testcindercapi is only in 3.10.cinder")
24232425
class GetBuiltinsTests(unittest.TestCase):
24242426
def test_get_builtins(self) -> None:
24252427
new_builtins = {}
@@ -2444,7 +2446,7 @@ def test_get_globals(self) -> None:
24442446
self.assertIs(func(), new_globals)
24452447

24462448

2447-
@unittest.skipIf(AT_LEAST_312, "T214641462: _testcindercapi is only in 3.10.cinder")
2449+
@passIf(AT_LEAST_312, "T214641462: _testcindercapi is only in 3.10.cinder")
24482450
class MergeCompilerFlagTests(unittest.TestCase):
24492451
def make_func(self, src, compile_flags=0):
24502452
code = compile(src, "<string>", "exec", compile_flags)
@@ -2515,9 +2517,7 @@ def test_multiple_call_method_same_load_method(self) -> None:
25152517
self.assertTrue(is_jit_compiled(LoadMethodEliminationTests.lme_test_func))
25162518

25172519

2518-
@unittest.skipUnless(
2519-
cinderx.jit.is_enabled(), "Tests functionality on cinderjit module"
2520-
)
2520+
@passUnless(cinderx.jit.is_enabled(), "Tests functionality on cinderjit module")
25212521
class HIROpcodeCountTests(unittest.TestCase):
25222522
def test_hir_opcode_count(self) -> None:
25232523
def f1():
@@ -2538,7 +2538,7 @@ def func():
25382538
self.assertGreaterEqual(decref, 2)
25392539

25402540

2541-
@unittest.skipUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
2541+
@passUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
25422542
class ForceUncompileTests(unittest.TestCase):
25432543
def test_basic(self) -> None:
25442544
def f(x: int) -> int:
@@ -2553,7 +2553,7 @@ def f(x: int) -> int:
25532553
self.assertFalse(is_jit_compiled(f))
25542554

25552555

2556-
@unittest.skipUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
2556+
@passUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
25572557
class LazyCompileTests(unittest.TestCase):
25582558
def test_basic(self) -> None:
25592559
def foo(a, b):
@@ -2565,7 +2565,7 @@ def foo(a, b):
25652565
self.assertTrue(is_jit_compiled(foo))
25662566

25672567

2568-
@unittest.skipUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
2568+
@passUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
25692569
class JITSuppressTests(unittest.TestCase):
25702570
def test_basic(self) -> None:
25712571
def f(x: int) -> int:
@@ -2586,7 +2586,7 @@ def f(x: int) -> int:
25862586
self.assertTrue(is_jit_compiled(f))
25872587

25882588

2589-
@unittest.skipUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
2589+
@passUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
25902590
class BadArgumentTests(unittest.TestCase):
25912591
def test_compile_after_n_calls(self) -> None:
25922592
with self.assertRaises(TypeError):
@@ -2661,7 +2661,7 @@ def test_jit_unsuppress(self) -> None:
26612661
jit_unsuppress(is_jit_compiled)
26622662

26632663

2664-
@unittest.skipUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
2664+
@passUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
26652665
class CompileTimeTests(unittest.TestCase):
26662666
"""
26672667
Test the Cinder APIs that report time spent compiling.
@@ -2691,7 +2691,7 @@ def test_compile_time(self) -> None:
26912691
self.assertGreater(cinderx.jit.get_function_compilation_time(_compile), 0)
26922692

26932693

2694-
@unittest.skipUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
2694+
@passUnless(cinderx.jit.is_enabled(), "Testing the cinderjit module itself")
26952695
class LocalsBuiltinTests(unittest.TestCase):
26962696
def test_locals_not_compiled(self) -> None:
26972697
def foo():

cinderx/PythonLib/test_cinderx/test_compiler/test_api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import re
99
import sys
1010
import unittest
11-
from unittest import skipIf
1211

1312
from cinderx.compiler import compile, compile_code
13+
from cinderx.test_support import passIf
1414

1515
from .common import CompilerTest
1616

@@ -88,7 +88,7 @@ def test_compile_optimized_docstrings(self) -> None:
8888
self.assertNotIn("hi", consts["f"].co_consts)
8989

9090

91-
@skipIf(POST_312, "Python 3.10- only")
91+
@passIf(POST_312, "Python 3.10- only")
9292
class ApiTests310(CompilerTest):
9393
def test_compile_single(self) -> None:
9494
code = compile_code("300", "foo", "single")
@@ -126,7 +126,7 @@ def test_compile_with_annotation_in_except_handler_emits_store_annotation(
126126
self.assertInBytecode(code, "SETUP_ANNOTATIONS")
127127

128128

129-
@skipIf(PRE_312, "Python 3.12+ only")
129+
@passIf(PRE_312, "Python 3.12+ only")
130130
class ApiTests312(CompilerTest):
131131
def test_compile_single(self) -> None:
132132
code = compile_code("256", "foo", "single")

cinderx/PythonLib/test_cinderx/test_compiler/test_cinder.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
from cinderx.compiler.pycodegen import compile as py_compile
1010

11+
from cinderx.test_support import passIf
12+
1113
from ..test_cpython_overrides import test_dis
1214

1315

@@ -18,9 +20,7 @@ def compile(self, code_str):
1820
return self.compiler(dedent(code_str), "<string>", "exec")
1921

2022

21-
@unittest.skipIf(
22-
sys.version_info >= (3, 12), "3.12 has different load super w/ CPython tests"
23-
)
23+
@passIf(sys.version_info >= (3, 12), "3.12 has different load super w/ CPython tests")
2424
class LoadSuperTests(DualCompilerDisTests):
2525
def test_super_zero_args(self) -> None:
2626
src = """
@@ -310,9 +310,7 @@ class LoadSuperPyCompilerTests(LoadSuperTests):
310310
compiler = staticmethod(py_compile)
311311

312312

313-
@unittest.skipIf(
314-
sys.version_info >= (3, 12), "3.12 inline comprehensions are different"
315-
)
313+
@passIf(sys.version_info >= (3, 12), "3.12 inline comprehensions are different")
316314
class ComprehensionInlinerTests(DualCompilerDisTests):
317315
def __init__(self, *args):
318316
super().__init__(*args)
@@ -655,7 +653,7 @@ def f():
655653
self.do_disassembly_test(g["f"], expected)
656654

657655

658-
@unittest.skipIf(
656+
@passIf(
659657
sys.version_info >= (3, 12),
660658
"3.12 has different inline comprehensions w/ CPython tests",
661659
)

0 commit comments

Comments
 (0)