def test_trace_includes_rule_exception_traceback(self): # Execute a request that will trigger the nested raise, and then directly inspect its trace. request = self.scheduler.execution_request([A], [B()]) _, throws = self.scheduler.execute(request) with self.assertRaises(ExecutionError) as cm: self.scheduler._raise_on_error([t for _, t in throws]) trace = remove_locations_from_traceback(str(cm.exception)) assert_equal_with_printing( self, dedent( """\ 1 Exception encountered: Engine traceback: in select in Nested raise Traceback (most recent call last): File LOCATION-INFO, in nested_raise fn_raises(b) File LOCATION-INFO, in fn_raises raise Exception(f"An exception for {type(x).__name__}") Exception: An exception for B """ ), trace, )
def test_unreachable_rule(self) -> None: """Test that when one rule "shadows" another, we get an error.""" @rule def d_singleton() -> D: return D() @rule def d_for_b(b: B) -> D: return D() rules = [d_singleton, d_for_b, QueryRule(D, (B,))] with pytest.raises(Exception) as cm: create_scheduler(rules) assert_equal_with_printing( dedent( f"""\ Rules with errors: 1 {fmt_rule(d_for_b)}: Was not reachable, either because no rules could produce the params or because it was shadowed by another @rule. """ ).strip(), str(cm.value), )
def test_no_include_trace_error_raises_boring_error( self, tmp_path: Path) -> None: rules = [nested_raise, QueryRule(A, (B, ))] scheduler = self.scheduler(tmp_path, rules, include_trace_on_error=False) with pytest.raises(ExecutionError) as cm: list(scheduler.product_request(A, subjects=[(B())])) assert_equal_with_printing( "1 Exception encountered:\n\n Exception: An exception for B\n", str(cm.value))
def test_no_include_trace_error_multiple_paths_raises_executionerror( self, tmp_path: Path) -> None: rules = [nested_raise, QueryRule(A, (B, ))] scheduler = self.scheduler(tmp_path, rules, include_trace_on_error=False) with pytest.raises(ExecutionError) as cm: list(scheduler.product_request(A, subjects=[B(), B()])) assert_equal_with_printing( dedent(""" 2 Exceptions encountered: Exception: An exception for B Exception: An exception for B """).lstrip(), str(cm.value), )
def test_include_trace_error_raises_error_with_trace( self, tmp_path: Path) -> None: rules = [nested_raise, QueryRule(A, (B, ))] scheduler = self.scheduler(tmp_path, rules, include_trace_on_error=True) with pytest.raises(ExecutionError) as cm: list(scheduler.product_request(A, subjects=[(B())])) assert_equal_with_printing( dedent(""" 1 Exception encountered: Engine traceback: in select in pants.engine.internals.engine_test.nested_raise Traceback (most recent call last): File LOCATION-INFO, in nested_raise fn_raises(x) File LOCATION-INFO, in fn_raises raise Exception(f"An exception for {type(x).__name__}") Exception: An exception for B """).lstrip(), remove_locations_from_traceback(str(cm.value)), )
def assert_equal_graph_output(expected, actual): return assert_equal_with_printing( expected, actual, uniform_formatter=remove_whitespace_from_graph_output)