@@ -89,6 +89,39 @@ class TestPreflightPassthrough: |
| 89 | 89 | assert ok is True |
| 90 | 90 | |
| 91 | 91 | |
| 92 | +class TestConcurrencyFlagComposition: |
| 93 | + """F06 regression — wrapper's ``safe_for_concurrent_views`` is the |
| 94 | + AND of the two inner backends' flags, defaulting to ``False`` when |
| 95 | + either is absent. Before F06, the attribute was missing entirely and |
| 96 | + the runner defaulted to ``False`` even when both inners set ``True``. |
| 97 | + """ |
| 98 | + |
| 99 | + def test_missing_on_both_defaults_false(self) -> None: |
| 100 | + base = DummyDifferentialBackend(base=DummyResponses(), ft=DummyResponses()) |
| 101 | + ft = DummyDifferentialBackend(base=DummyResponses(), ft=DummyResponses()) |
| 102 | + wrapper = TwoModelDifferential(base=base, ft=ft) |
| 103 | + # Dummy has safe_for_concurrent_views=False by class default. |
| 104 | + assert wrapper.safe_for_concurrent_views is False |
| 105 | + |
| 106 | + def test_both_true_composes_true(self) -> None: |
| 107 | + class SafeDummy(DummyDifferentialBackend): |
| 108 | + safe_for_concurrent_views = True |
| 109 | + |
| 110 | + base = SafeDummy(base=DummyResponses(), ft=DummyResponses()) |
| 111 | + ft = SafeDummy(base=DummyResponses(), ft=DummyResponses()) |
| 112 | + wrapper = TwoModelDifferential(base=base, ft=ft) |
| 113 | + assert wrapper.safe_for_concurrent_views is True |
| 114 | + |
| 115 | + def test_one_true_one_false_composes_false(self) -> None: |
| 116 | + class SafeDummy(DummyDifferentialBackend): |
| 117 | + safe_for_concurrent_views = True |
| 118 | + |
| 119 | + base = SafeDummy(base=DummyResponses(), ft=DummyResponses()) |
| 120 | + ft = DummyDifferentialBackend(base=DummyResponses(), ft=DummyResponses()) |
| 121 | + wrapper = TwoModelDifferential(base=base, ft=ft) |
| 122 | + assert wrapper.safe_for_concurrent_views is False |
| 123 | + |
| 124 | + |
| 92 | 125 | class TestSpecAcceptsDifferentialFalse: |
| 93 | 126 | def test_loader_accepts_false_then_uses_two_separate(self, tmp_path) -> None: |
| 94 | 127 | """The CLI path: spec.defaults.differential=False routes through |