Option C Tools
Loading...
Searching...
No Matches
test_log_handle_encapsulation.py
Go to the documentation of this file.
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
# tests/tests_linter/test_log_handle_encapsulation.py
4
5
"""
6
Purpose
7
-------
8
OI-513 regression coverage — ``LOG_HANDLE`` must not exist as a
9
module-level global on :mod:`oct.linter.oct_lint`. All log state lives
10
on :class:`LinterContext` so that concurrent linter invocations (MCP,
11
parallel ``--jobs``, health dashboard) never share mutable state.
12
13
Responsibilities
14
----------------
15
- Verify ``oct.linter.oct_lint`` exposes no ``LOG_HANDLE`` attribute.
16
- Verify ``log()`` writes through ``ctx.log_handle`` only.
17
- Verify two concurrent contexts never cross-pollute handles.
18
19
Diagnostics
20
-----------
21
Domain: LINTER-TESTS
22
Levels:
23
L2 — test lifecycle
24
L3 — assertion details
25
L4 — deep tracing
26
27
Contracts
28
---------
29
- ``oct.linter.oct_lint`` exposes no ``LOG_HANDLE`` attribute.
30
- :func:`log` writes through ``ctx.log_handle`` only; silent when None.
31
- Two contexts in flight never cross-pollute handles.
32
"""
33
34
from
__future__
import
annotations
35
36
import
io
37
import
threading
38
from
pathlib
import
Path
39
40
from
oct.linter
import
oct_lint
41
from
oct.linter.oct_lint
import
LinterContext, log
42
43
44
def
_make_ctx
(tmp_path: Path, handle) -> LinterContext:
45
return
LinterContext
(
46
project_root=tmp_path,
47
project_name=
"demo"
,
48
diagnostics_dir=tmp_path /
"oc_diagnostics"
,
49
tests_dir=tmp_path /
"tests"
,
50
docs_dir=tmp_path /
"docs"
,
51
log_handle=handle,
52
log_lock=threading.Lock(),
53
)
54
55
56
def
test_no_module_level_log_handle
():
57
"""OI-513: the deprecated module global is gone."""
58
assert
not
hasattr(oct_lint,
"LOG_HANDLE"
)
59
60
61
def
test_log_writes_through_ctx_handle
(tmp_path: Path):
62
"""OI-513: ``log()`` routes through ``ctx.log_handle``."""
63
buf = io.StringIO()
64
ctx =
_make_ctx
(tmp_path, buf)
65
log(
"hello"
, ctx)
66
assert
buf.getvalue() ==
"hello\n"
67
68
69
def
test_log_is_silent_without_ctx_or_handle
(tmp_path: Path):
70
"""OI-513: ``log()`` is a no-op when ctx is None or handle is None."""
71
# No ctx at all — must not raise.
72
log(
"dropped"
,
None
)
73
# ctx with no handle — still silent.
74
ctx =
_make_ctx
(tmp_path,
None
)
75
log(
"also dropped"
, ctx)
# no exception, nothing written.
76
77
78
def
test_two_contexts_isolate_handles
(tmp_path: Path):
79
"""OI-513: parallel runs do not share a global handle."""
80
buf_a = io.StringIO()
81
buf_b = io.StringIO()
82
ctx_a =
_make_ctx
(tmp_path, buf_a)
83
ctx_b =
_make_ctx
(tmp_path, buf_b)
84
log(
"A1"
, ctx_a)
85
log(
"B1"
, ctx_b)
86
log(
"A2"
, ctx_a)
87
assert
buf_a.getvalue() ==
"A1\nA2\n"
88
assert
buf_b.getvalue() ==
"B1\n"
oct.linter.oct_lint.LinterContext
Definition
oct_lint.py:421
oct.linter.oct_lint
Definition
oct_lint.py:1
oct.linter
Definition
__init__.py:1
tests_linter.test_log_handle_encapsulation.test_log_is_silent_without_ctx_or_handle
test_log_is_silent_without_ctx_or_handle(Path tmp_path)
Definition
test_log_handle_encapsulation.py:69
tests_linter.test_log_handle_encapsulation.test_no_module_level_log_handle
test_no_module_level_log_handle()
Definition
test_log_handle_encapsulation.py:56
tests_linter.test_log_handle_encapsulation._make_ctx
LinterContext _make_ctx(Path tmp_path, handle)
Definition
test_log_handle_encapsulation.py:44
tests_linter.test_log_handle_encapsulation.test_log_writes_through_ctx_handle
test_log_writes_through_ctx_handle(Path tmp_path)
Definition
test_log_handle_encapsulation.py:61
tests_linter.test_log_handle_encapsulation.test_two_contexts_isolate_handles
test_two_contexts_isolate_handles(Path tmp_path)
Definition
test_log_handle_encapsulation.py:78
tests
tests_linter
test_log_handle_encapsulation.py
Generated by
1.15.0