"""Composite writes: a file at the target path is always a complete JPEG. Every renderer resumes by skipping composites that already exist, so a JPEG cut short by a kill mid-write would be kept forever. The real 2024 run was killed exactly that way when an unrelated process exhausted host memory. """ import os import pytest from PIL import Image import bench import merger_FITS @pytest.fixture def composite(monkeypatch): monkeypatch.setattr(merger_FITS, "composite_from_arrays", lambda arrays, timestamp: Image.new("RGB", (64, 36), (200, 90, 10))) def test_a_rendered_composite_is_a_complete_jpeg(tmp_path, composite): target = str(tmp_path / "Composite-1.jpg") path, error = bench._render_one(([], 1, target)) assert (path, error) == (target, None) with open(target, "rb") as handle: data = handle.read() assert data[:2] == b"\xff\xd8" and data[-2:] == b"\xff\xd9" assert os.listdir(tmp_path) == ["Composite-1.jpg"] def test_a_write_cut_short_leaves_no_composite(tmp_path, composite, monkeypatch): """The interrupted bytes never appear at the target, and nothing is left over.""" def dies_mid_write(self, fp, format=None, **params): with open(fp, "wb") as handle: handle.write(b"\xff\xd8 half a jpeg") raise OSError("killed") monkeypatch.setattr(Image.Image, "save", dies_mid_write) target = str(tmp_path / "Composite-1.jpg") path, error = bench._render_one(([], 1, target)) assert path == target and "killed" in error assert os.listdir(tmp_path) == [] def test_a_failed_render_never_touches_an_existing_composite(tmp_path, monkeypatch): def broken(arrays, timestamp): raise ValueError("bad arrays") monkeypatch.setattr(merger_FITS, "composite_from_arrays", broken) target = tmp_path / "Composite-1.jpg" target.write_bytes(b"done") _, error = bench._render_one(([], 1, str(target))) assert "bad arrays" in error assert target.read_bytes() == b"done" assert os.listdir(tmp_path) == ["Composite-1.jpg"]