2323from airbyte_cdk .utils .traced_exception import AirbyteTracedException
2424
2525_MOCK_USAGE_BELOW = "500000000\n " # 50% of 1 GB
26- _MOCK_USAGE_AT_90 = "910000000 \n " # 91 % of 1 GB (below 95% logging threshold)
27- _MOCK_USAGE_AT_95 = "960000000 \n " # 96 % of 1 GB (above 95% logging threshold )
28- _MOCK_USAGE_AT_98 = "980000000 \n " # 98 % of 1 GB (at critical threshold)
26+ _MOCK_USAGE_AT_85 = "850000000 \n " # 85 % of 1 GB (below 90% high-pressure threshold)
27+ _MOCK_USAGE_AT_92 = "920000000 \n " # 92 % of 1 GB (above 90% high-pressure, below 95% critical )
28+ _MOCK_USAGE_AT_96 = "960000000 \n " # 96 % of 1 GB (above 95% critical threshold)
2929_MOCK_LIMIT = "1000000000\n " # 1 GB
3030
3131# cgroup v2 memory.stat mock content.
3232# The "anon" field is what we parse for the cgroup-level anonymous memory signal.
3333_MOCK_MEMORY_STAT_ANON_HIGH = (
34- "anon 860000000 \n " # 860 MB — 87.7 % of 980 MB usage (above 85% threshold)
34+ "anon 840000000 \n " # 840 MB — 87.5 % of 960 MB usage (above 85% threshold)
3535 "file 100000000\n "
3636 "kernel 20000000\n "
3737)
3838_MOCK_MEMORY_STAT_ANON_LOW = (
39- "anon 300000000\n " # 300 MB — 30.6 % of 980 MB usage (below 85% threshold)
40- "file 650000000 \n "
39+ "anon 300000000\n " # 300 MB — 31.25 % of 960 MB usage (below 85% threshold)
40+ "file 630000000 \n "
4141 "kernel 30000000\n "
4242)
4343_MOCK_MEMORY_STAT_NO_ANON = (
44- "file 650000000 \n " # malformed: missing anon line
44+ "file 630000000 \n " # malformed: missing anon line
4545 "kernel 30000000\n "
4646)
4747
4848# /proc/self/status mock values (fallback when cgroup v2 memory.stat is unavailable).
49- _MOCK_PROC_ANON_HIGH = "RssAnon:\t 840000 kB\n " # ~860 MB — 87.7 % of 980 MB usage
50- _MOCK_PROC_ANON_LOW = "RssAnon:\t 300000 kB\n " # ~307 MB — 31.3 % of 980 MB usage
49+ _MOCK_PROC_ANON_HIGH = "RssAnon:\t 820313 kB\n " # ~840 MB — 87.5 % of 960 MB usage
50+ _MOCK_PROC_ANON_LOW = "RssAnon:\t 300000 kB\n " # ~307 MB — 32.0 % of 960 MB usage
5151
5252
5353def _v2_exists (self : Path ) -> bool :
@@ -134,12 +134,12 @@ def test_noop_when_limit_is_zero(caplog: pytest.LogCaptureFixture) -> None:
134134
135135
136136def test_no_log_below_threshold (caplog : pytest .LogCaptureFixture ) -> None :
137- """No log should be emitted when usage is below 95% ."""
137+ """No log should be emitted when usage is below the 90% high-pressure threshold ."""
138138 monitor = MemoryMonitor (check_interval = 1 )
139139 with (
140140 caplog .at_level (logging .DEBUG , logger = "airbyte" ),
141141 patch .object (Path , "exists" , _v2_exists ),
142- patch .object (Path , "read_text" , _v2_mock_read (usage = _MOCK_USAGE_AT_90 )),
142+ patch .object (Path , "read_text" , _v2_mock_read (usage = _MOCK_USAGE_AT_85 )),
143143 ):
144144 monitor .check_memory_usage ()
145145 # Only the debug probe message, no info/warning
@@ -152,11 +152,11 @@ def test_no_log_below_threshold(caplog: pytest.LogCaptureFixture) -> None:
152152
153153
154154def test_cgroup_v1_activates_high_pressure_mode (caplog : pytest .LogCaptureFixture ) -> None :
155- """Memory reading works with cgroup v1 paths and activates high-pressure mode at 95 %."""
155+ """Memory reading works with cgroup v1 paths and activates high-pressure mode at 90 %."""
156156
157157 def mock_read_text (self : Path ) -> str :
158158 if self == _CGROUP_V1_USAGE :
159- return _MOCK_USAGE_AT_95
159+ return _MOCK_USAGE_AT_92
160160 if self == _CGROUP_V1_LIMIT :
161161 return _MOCK_LIMIT
162162 return ""
@@ -185,7 +185,7 @@ def test_check_interval_skips_intermediate_calls(caplog: pytest.LogCaptureFixtur
185185 with (
186186 caplog .at_level (logging .INFO , logger = "airbyte" ),
187187 patch .object (Path , "exists" , _v2_exists ),
188- patch .object (Path , "read_text" , _v2_mock_read (usage = _MOCK_USAGE_AT_95 )),
188+ patch .object (Path , "read_text" , _v2_mock_read (usage = _MOCK_USAGE_AT_92 )),
189189 ):
190190 # First 4999 calls should be skipped
191191 for _ in range (4999 ):
@@ -290,7 +290,7 @@ def test_read_cgroup_v2_anon_bytes_parses_anon_field() -> None:
290290 """Correctly parses the 'anon' field from cgroup v2 memory.stat."""
291291 with patch .object (Path , "read_text" , return_value = _MOCK_MEMORY_STAT_ANON_HIGH ):
292292 result = _read_cgroup_v2_anon_bytes ()
293- assert result == 860000000
293+ assert result == 840000000
294294
295295
296296def test_read_cgroup_v2_anon_bytes_returns_none_when_anon_absent () -> None :
@@ -314,7 +314,7 @@ def raise_oserror(self: Path) -> str:
314314# ---------------------------------------------------------------------------
315315
316316
317- def _v2_full_mock (usage : str = _MOCK_USAGE_AT_98 , memory_stat : str = _MOCK_MEMORY_STAT_ANON_HIGH ):
317+ def _v2_full_mock (usage : str = _MOCK_USAGE_AT_96 , memory_stat : str = _MOCK_MEMORY_STAT_ANON_HIGH ):
318318 """Return a mock read_text that serves cgroup v2 current/max AND memory.stat."""
319319
320320 def mock_read_text (self : Path ) -> str :
@@ -330,7 +330,7 @@ def mock_read_text(self: Path) -> str:
330330
331331
332332def test_raises_when_cgroup_critical_and_anon_share_of_usage_above_threshold () -> None :
333- """Fail-fast raises when cgroup >= 98 % and anon >= 85% of current usage."""
333+ """Fail-fast raises when cgroup >= 95 % and anon >= 85% of current usage."""
334334 monitor = MemoryMonitor (check_interval = 1 )
335335 with (
336336 patch .object (Path , "exists" , _v2_exists ),
@@ -340,14 +340,14 @@ def test_raises_when_cgroup_critical_and_anon_share_of_usage_above_threshold() -
340340 monitor .check_memory_usage ()
341341 assert exc_info .value .failure_type == FailureType .system_error
342342 assert "critical threshold" in (exc_info .value .message or "" )
343- assert "98 %" in (exc_info .value .message or "" )
343+ assert "96 %" in (exc_info .value .message or "" )
344344 assert "anon share of usage" in (exc_info .value .internal_message or "" )
345345
346346
347347def test_no_raise_when_cgroup_critical_but_anon_share_of_usage_below_threshold (
348348 caplog : pytest .LogCaptureFixture ,
349349) -> None :
350- """No exception when cgroup >= 98 % but anon < 85% of usage; logs once then silences."""
350+ """No exception when cgroup >= 95 % but anon < 85% of usage; logs once then silences."""
351351 monitor = MemoryMonitor (check_interval = 1 )
352352 with (
353353 caplog .at_level (logging .INFO , logger = "airbyte" ),
@@ -368,7 +368,7 @@ def test_falls_back_to_process_rssanon_when_cgroup_v2_anon_unavailable() -> None
368368
369369 def mock_read_text (self : Path ) -> str :
370370 if self == _CGROUP_V2_CURRENT :
371- return _MOCK_USAGE_AT_98
371+ return _MOCK_USAGE_AT_96
372372 if self == _CGROUP_V2_MAX :
373373 return _MOCK_LIMIT
374374 if self == _CGROUP_V2_STAT :
@@ -394,13 +394,13 @@ def test_falls_back_to_process_rssanon_low_and_does_not_raise(
394394
395395 def mock_read_text (self : Path ) -> str :
396396 if self == _CGROUP_V2_CURRENT :
397- return _MOCK_USAGE_AT_98
397+ return _MOCK_USAGE_AT_96
398398 if self == _CGROUP_V2_MAX :
399399 return _MOCK_LIMIT
400400 if self == _CGROUP_V2_STAT :
401401 return _MOCK_MEMORY_STAT_NO_ANON # anon line missing
402402 if self == _PROC_SELF_STATUS :
403- return _MOCK_PROC_ANON_LOW # ~307 MB — 31.3 % of 980 MB usage (below 85%)
403+ return _MOCK_PROC_ANON_LOW # ~307 MB — 32.0 % of 960 MB usage (below 85%)
404404 return ""
405405
406406 monitor = MemoryMonitor (check_interval = 1 )
@@ -421,7 +421,7 @@ def test_no_raise_when_anonymous_memory_signal_unavailable_at_critical_usage(
421421
422422 def mock_read_text (self : Path ) -> str :
423423 if self == _CGROUP_V2_CURRENT :
424- return _MOCK_USAGE_AT_98
424+ return _MOCK_USAGE_AT_96
425425 if self == _CGROUP_V2_MAX :
426426 return _MOCK_LIMIT
427427 if self == _CGROUP_V2_STAT :
@@ -444,17 +444,17 @@ def mock_read_text(self: Path) -> str:
444444 assert monitor ._critical_logged
445445
446446
447- def test_switches_to_high_pressure_check_interval_after_crossing_95_percent (
447+ def test_switches_to_high_pressure_check_interval_after_crossing_90_percent (
448448 caplog : pytest .LogCaptureFixture ,
449449) -> None :
450- """Once usage crosses 95 %, the monitor tightens polling from 5000 to 100 messages."""
450+ """Once usage crosses 90 %, the monitor tightens polling from 5000 to 100 messages."""
451451 monitor = MemoryMonitor (check_interval = 5000 )
452452 assert not monitor ._high_pressure_mode
453453
454454 with (
455455 caplog .at_level (logging .INFO , logger = "airbyte" ),
456456 patch .object (Path , "exists" , _v2_exists ),
457- patch .object (Path , "read_text" , _v2_mock_read (usage = _MOCK_USAGE_AT_95 )),
457+ patch .object (Path , "read_text" , _v2_mock_read (usage = _MOCK_USAGE_AT_92 )),
458458 ):
459459 # Pump 5000 messages to trigger the first real check
460460 for _ in range (5000 ):
0 commit comments