4040# a suffix swap would look for an object that is not there.
4141VIDEO_TYPE = ".mkv"
4242
43- # Pinned for reproducibility. testcontainers' own default is a 2022 build that is
44- # amd64 only and will not start on an arm64 host.
45- MINIO_IMAGE = "minio/minio:RELEASE.2025-09-07T16-13-09Z"
43+ # Pinned for reproducibility, and built for both amd64 and arm64.
44+ RUSTFS_IMAGE = "rustfs/rustfs:1.0.0-rc.6"
4645
4746
4847def _docker_is_available () -> bool :
@@ -58,19 +57,19 @@ def _docker_is_available() -> bool:
5857
5958
6059pytestmark = pytest .mark .skipif (
61- not _docker_is_available (), reason = "needs Docker to run MinIO "
60+ not _docker_is_available (), reason = "needs Docker to run RustFS "
6261)
6362
6463
6564@pytest .fixture (scope = "module" )
66- def minio () -> Iterator [dict ]:
67- from testcontainers . minio import MinioContainer
65+ def rustfs () -> Iterator [dict ]:
66+ from tests . utils . rustfs_container import RustFsContainer
6867
6968 # The reaper container bind-mounts the Docker socket, which Docker Desktop
7069 # refuses on some hosts. The context manager below cleans up on a normal
7170 # exit; the reaper only matters if the test process is killed outright.
7271 os .environ .setdefault ("TESTCONTAINERS_RYUK_DISABLED" , "true" )
73- with MinioContainer (image = MINIO_IMAGE ) as container :
72+ with RustFsContainer (image = RUSTFS_IMAGE ) as container :
7473 client = container .get_client ()
7574 client .make_bucket (BUCKET )
7675 for chunk in CHUNKS :
@@ -104,12 +103,12 @@ class Given:
104103 user_source : Path
105104
106105
107- def create_given (minio : dict , tmp_path : Path , hours : float = 1 ) -> Given :
106+ def create_given (rustfs : dict , tmp_path : Path , hours : float = 1 ) -> Given :
108107 user_source = tmp_path / "user-source"
109108 config = S3Config (
110- endpoint_url = minio ["endpoint_url" ],
111- access_key = minio ["access_key" ],
112- secret_key = minio ["secret_key" ],
109+ endpoint_url = rustfs ["endpoint_url" ],
110+ access_key = rustfs ["access_key" ],
111+ secret_key = rustfs ["secret_key" ],
113112 bucket = BUCKET ,
114113 region = None ,
115114 key_prefix = PREFIX ,
@@ -151,14 +150,14 @@ def create_video_target(given: Given) -> S3VideoFileProvider:
151150 )
152151
153152
154- class TestLoadFromMinio :
153+ class TestLoadFromRustFs :
155154 """#Requirement https://openproject.platomo.de/wp/10283"""
156155
157156 async def test_an_over_long_selection_loads_only_up_to_the_cap (
158- self , minio : dict , tmp_path : Path
157+ self , rustfs : dict , tmp_path : Path
159158 ) -> None :
160159 """10:00-11:00 clamps to 10:20, so only the 10:00 and 10:15 chunks load."""
161- given = create_given (minio , tmp_path , hours = 1 )
160+ given = create_given (rustfs , tmp_path , hours = 1 )
162161 target = create_track_target (given )
163162
164163 provided = await target .provide ()
@@ -170,9 +169,9 @@ async def test_an_over_long_selection_loads_only_up_to_the_cap(
170169 given .dialog .report_clamped .assert_called_once ()
171170
172171 async def test_downloads_each_track_file_with_its_video (
173- self , minio : dict , tmp_path : Path
172+ self , rustfs : dict , tmp_path : Path
174173 ) -> None :
175- given = create_given (minio , tmp_path , hours = 1 )
174+ given = create_given (rustfs , tmp_path , hours = 1 )
176175 target = create_track_target (given )
177176
178177 await target .provide ()
@@ -187,9 +186,9 @@ async def test_downloads_each_track_file_with_its_video(
187186 assert staged .is_file (), f"{ staged } was not downloaded"
188187
189188 async def test_stages_objects_under_paths_mirroring_their_keys (
190- self , minio : dict , tmp_path : Path
189+ self , rustfs : dict , tmp_path : Path
191190 ) -> None :
192- given = create_given (minio , tmp_path , hours = 1 )
191+ given = create_given (rustfs , tmp_path , hours = 1 )
193192 target = create_track_target (given )
194193
195194 provided = await target .provide ()
@@ -199,20 +198,20 @@ async def test_stages_objects_under_paths_mirroring_their_keys(
199198 )
200199
201200 async def test_reads_the_bytes_that_were_stored (
202- self , minio : dict , tmp_path : Path
201+ self , rustfs : dict , tmp_path : Path
203202 ) -> None :
204- given = create_given (minio , tmp_path , hours = 1 )
203+ given = create_given (rustfs , tmp_path , hours = 1 )
205204 target = create_track_target (given )
206205
207206 provided = await target .provide ()
208207
209208 assert bz2 .decompress (provided [0 ].read_bytes ()).startswith (b"{" )
210209
211210 async def test_pairs_each_track_file_with_the_video_its_metadata_names (
212- self , minio : dict , tmp_path : Path
211+ self , rustfs : dict , tmp_path : Path
213212 ) -> None :
214213 """A suffix swap would have looked for a .mp4 that does not exist."""
215- given = create_given (minio , tmp_path , hours = 1 )
214+ given = create_given (rustfs , tmp_path , hours = 1 )
216215 target = create_track_target (given )
217216
218217 await target .provide ()
@@ -221,8 +220,8 @@ async def test_pairs_each_track_file_with_the_video_its_metadata_names(
221220 assert (staged / f"OTCamera19_FR20_2023-05-24_10-00-00{ VIDEO_TYPE } " ).is_file ()
222221 assert not (staged / "OTCamera19_FR20_2023-05-24_10-00-00.mp4" ).exists ()
223222
224- async def test_videos_load_on_their_own (self , minio : dict , tmp_path : Path ) -> None :
225- given = create_given (minio , tmp_path , hours = 1 )
223+ async def test_videos_load_on_their_own (self , rustfs : dict , tmp_path : Path ) -> None :
224+ given = create_given (rustfs , tmp_path , hours = 1 )
226225 target = create_video_target (given )
227226
228227 provided = await target .provide ()
0 commit comments