Skip to content

Commit 712ec50

Browse files
committed
add tests for list_object_versions streaming functionality
verifies basic streaming, pagination with uneven last page (33 versions across 7 pages with max_keys=5), and proper handling of delete markers in streams. ensures dual-marker pagination works correctly and that both versions and delete markers are returned when streaming.
1 parent 85080c1 commit 712ec50

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

test/lib/s3_minio_test.exs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,106 @@ defmodule ExAws.S3MinioTest do
311311
assert length(versions) == 2
312312
assert Enum.all?(versions, fn version -> version.key == @test_object end)
313313
end
314+
315+
test "list_object_versions can be streamed", %{bucket: bucket} do
316+
# Enable versioning
317+
version_config =
318+
"<VersioningConfiguration><Status>Enabled</Status></VersioningConfiguration>"
319+
320+
S3.put_bucket_versioning(bucket, version_config) |> ExAws.request()
321+
322+
# Upload multiple versions of multiple objects
323+
for obj <- ["obj1.txt", "obj2.txt", "obj3.txt"] do
324+
S3.put_object(bucket, obj, "#{obj} version 1") |> ExAws.request()
325+
S3.put_object(bucket, obj, "#{obj} version 2") |> ExAws.request()
326+
end
327+
328+
# Stream all versions
329+
versions =
330+
S3.list_object_versions(bucket)
331+
|> ExAws.stream!()
332+
|> Enum.to_list()
333+
334+
# Should have 6 versions total (3 objects × 2 versions each)
335+
assert length(versions) == 6
336+
assert Enum.all?(versions, fn version -> version.key in ["obj1.txt", "obj2.txt", "obj3.txt"] end)
337+
end
338+
339+
test "list_object_versions streams with pagination when max_keys is set", %{bucket: bucket} do
340+
# Enable versioning
341+
version_config =
342+
"<VersioningConfiguration><Status>Enabled</Status></VersioningConfiguration>"
343+
344+
S3.put_bucket_versioning(bucket, version_config) |> ExAws.request()
345+
346+
# Upload 11 objects with 3 versions each = 33 total versions
347+
# With max_keys=5, this gives: 5+5+5+5+5+5+3 (7 pages, last page has only 3 items)
348+
object_names = for i <- 1..11, do: "obj#{i}.txt"
349+
350+
for obj <- object_names do
351+
S3.put_object(bucket, obj, "#{obj} version 1") |> ExAws.request()
352+
S3.put_object(bucket, obj, "#{obj} version 2") |> ExAws.request()
353+
S3.put_object(bucket, obj, "#{obj} version 3") |> ExAws.request()
354+
end
355+
356+
# Stream all versions with max_keys set to 5 to force multiple requests with uneven last page
357+
versions =
358+
S3.list_object_versions(bucket, max_keys: 5)
359+
|> ExAws.stream!()
360+
|> Enum.to_list()
361+
362+
# Should have 33 versions total (11 objects × 3 versions each)
363+
assert length(versions) == 33
364+
365+
# Verify all objects are present
366+
unique_keys = versions |> Enum.map(& &1.key) |> Enum.uniq() |> Enum.sort()
367+
assert length(unique_keys) == 11
368+
assert unique_keys == Enum.sort(object_names)
369+
370+
# Verify each object has 3 versions
371+
for obj <- object_names do
372+
obj_versions = Enum.filter(versions, fn v -> v.key == obj end)
373+
assert length(obj_versions) == 3
374+
end
375+
end
376+
377+
test "list_object_versions includes delete markers in stream", %{bucket: bucket} do
378+
# Enable versioning
379+
version_config =
380+
"<VersioningConfiguration><Status>Enabled</Status></VersioningConfiguration>"
381+
382+
S3.put_bucket_versioning(bucket, version_config) |> ExAws.request()
383+
384+
# Upload multiple objects
385+
for obj <- ["obj1.txt", "obj2.txt", "obj3.txt", "obj4.txt"] do
386+
S3.put_object(bucket, obj, "#{obj} version 1") |> ExAws.request()
387+
S3.put_object(bucket, obj, "#{obj} version 2") |> ExAws.request()
388+
end
389+
390+
# Delete some objects (creates delete markers)
391+
S3.delete_object(bucket, "obj2.txt") |> ExAws.request()
392+
S3.delete_object(bucket, "obj4.txt") |> ExAws.request()
393+
394+
# Stream all versions and delete markers
395+
all_entries =
396+
S3.list_object_versions(bucket)
397+
|> ExAws.stream!()
398+
|> Enum.to_list()
399+
400+
# Should have 8 versions (4 objects × 2 versions) + 2 delete markers = 10 total
401+
assert length(all_entries) == 10
402+
403+
# Separate versions from delete markers using split_with
404+
{versions, delete_markers} = Enum.split_with(all_entries, fn entry -> Map.has_key?(entry, :size) end)
405+
406+
# Verify we have the expected counts
407+
assert length(versions) == 8
408+
assert length(delete_markers) == 2
409+
410+
# Verify delete markers are for the deleted objects
411+
delete_marker_keys = Enum.map(delete_markers, & &1.key) |> Enum.sort()
412+
assert delete_marker_keys == ["obj2.txt", "obj4.txt"]
413+
end
314414
end
315415

316416
describe "Multipart upload operations" do

0 commit comments

Comments
 (0)