@@ -196,47 +196,79 @@ def _run_docker_space_gate(
196196 )
197197
198198
199+ def _storage_rail (rail : str ) -> dict :
200+ """The storage policy's limits for `rail`.
201+
202+ Read rather than restated. These fixtures simulate a daemon sitting above
203+ or below the free-space floor, so every literal here is only meaningful
204+ relative to that floor: hardcoding "30 GiB is plenty" silently became
205+ "30 GiB is not enough" the moment the floor moved to 40, and the failure
206+ surfaced as a release gate refusing to build assets.
207+ """
208+ import tomllib
209+
210+ policy = tomllib .loads (
211+ (PROJECT_ROOT / "config" / "storage-policy.toml" ).read_text (encoding = "utf-8" )
212+ )
213+ return policy ["rails" ][rail ]
214+
215+
199216def test_asset_gate_owns_docker_capacity_preflight (tmp_path : Path ) -> None :
200217 recipe = _just_recipe_block ("_gate-assets:" )
201218
202219 preflight = '"$ROOT/scripts/ensure-docker-space.sh" assets'
203220 assert preflight in recipe
204221 assert recipe .index (preflight ) < recipe .index ("build_arch_lane arm64" )
205222
206- enough = _run_docker_space_gate (tmp_path / "enough" , before_kib = 30 * 1024 * 1024 , after_kib = 0 )
223+ assets = _storage_rail ("assets" )
224+ floor_gib = assets ["minimum_free_gib" ]
225+ keep_gib = assets ["buildkit_keep_gib" ]
226+ # Comfortably clear of the floor, and clearly under it, whatever it is.
227+ ample_gib = floor_gib + 10
228+ starved_gib = max (floor_gib // 4 , 1 )
229+ ample_kib = ample_gib * 1024 * 1024
230+ starved_kib = starved_gib * 1024 * 1024
231+
232+ enough = _run_docker_space_gate (
233+ tmp_path / "enough" , before_kib = ample_kib , after_kib = 0
234+ )
207235 assert enough .returncode == 0 , enough .stderr
208236 assert "Docker storage control [enforce/preflight]" in enough .stdout
209237
210238 reclaimed = _run_docker_space_gate (
211239 tmp_path / "reclaimed" ,
212- before_kib = 8 * 1024 * 1024 ,
213- after_kib = 30 * 1024 * 1024 ,
240+ before_kib = starved_kib ,
241+ after_kib = ample_kib ,
214242 )
215243 assert reclaimed .returncode == 0 , reclaimed .stderr
216244 assert "buildkit-pressure-prune" in reclaimed .stdout
217- assert "8 .0 GiB -> 30 .0 GiB" in reclaimed .stdout
245+ assert f" { starved_gib } .0 GiB -> { ample_gib } .0 GiB" in reclaimed .stdout
218246 reclaimed_commands = (tmp_path / "reclaimed" / "docker-commands" ).read_text ()
219- assert "builder prune --force --keep-storage 24GB " in reclaimed_commands
247+ assert f "builder prune --force --keep-storage { keep_gib } GB " in reclaimed_commands
220248 assert "builder prune -af" not in reclaimed_commands
221249
250+ package = _storage_rail ("package" )
222251 package_reclaimed = _run_docker_space_gate (
223252 tmp_path / "package-reclaimed" ,
224- before_kib = 10 * 1024 * 1024 ,
225- after_kib = 30 * 1024 * 1024 ,
253+ before_kib = starved_kib ,
254+ after_kib = ample_kib ,
226255 rail = "package" ,
227256 )
228257 assert package_reclaimed .returncode == 0 , package_reclaimed .stderr
229- assert "retain 24 GiB" in package_reclaimed .stdout
258+ assert f "retain { package [ 'buildkit_keep_gib' ] } GiB" in package_reclaimed .stdout
230259 package_commands = (tmp_path / "package-reclaimed" / "docker-commands" ).read_text ()
231- assert "builder prune --force --keep-storage 24GB" in package_commands
260+ assert (
261+ f"builder prune --force --keep-storage { package ['buildkit_keep_gib' ]} GB"
262+ in package_commands
263+ )
232264
233265 exhausted = _run_docker_space_gate (
234266 tmp_path / "exhausted" ,
235- before_kib = 8 * 1024 * 1024 ,
236- after_kib = 10 * 1024 * 1024 ,
267+ before_kib = starved_kib ,
268+ after_kib = starved_kib ,
237269 )
238270 assert exhausted .returncode != 0
239- assert "requires 24 .0 GiB free" in exhausted .stderr
271+ assert f "requires { floor_gib } .0 GiB free" in exhausted .stderr
240272
241273 storage_script = (PROJECT_ROOT / "scripts" / "ensure-docker-space.sh" ).read_text ()
242274 controller = (PROJECT_ROOT / "scripts" / "docker-storage-policy.py" ).read_text ()
0 commit comments