Skip to content

Commit e9f345c

Browse files
Edward AlmondEdward Almond
authored andcommitted
Fix S3 pagination and integration tests
- Fix pagination bug: move max_keys check AFTER adding object to ensure last_key is properly set for continuation token - Update test to include MaxKeys in all paginated requests (AWS S3 doesn't remember MaxKeys across continuation tokens) - Default to localhost:4566 endpoint for local testing - Set dummy AWS credentials for boto3 if not provided
1 parent 580329e commit e9f345c

2 files changed

Lines changed: 35 additions & 16 deletions

File tree

ruststack-s3/src/storage/ephemeral.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,6 @@ impl ObjectStorage for EphemeralStorage {
248248
}
249249
}
250250

251-
if objects.len() >= max_keys {
252-
has_more = true;
253-
break;
254-
}
255-
256251
last_key = Some(key.clone());
257252
if let Some(entry) = bucket_ref.objects.get(&key) {
258253
objects.push(ObjectSummary {
@@ -263,6 +258,11 @@ impl ObjectStorage for EphemeralStorage {
263258
storage_class: "STANDARD".to_string(),
264259
});
265260
}
261+
262+
if objects.len() >= max_keys {
263+
has_more = true;
264+
break;
265+
}
266266
}
267267

268268
// Sort by key

tests/integration/test_docker.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@
2626
from botocore.client import BaseClient
2727
from botocore.exceptions import ClientError
2828

29-
# Configure endpoint - default to docker service name
30-
ENDPOINT_URL = os.environ.get("AWS_ENDPOINT_URL", "http://ruststack:4566")
29+
# Configure endpoint - default to local process
30+
ENDPOINT_URL = os.environ.get("AWS_ENDPOINT_URL", "http://localhost:4566")
3131
REGION = "us-east-1"
3232

33+
# Set dummy credentials for boto3 if not already in environment
34+
os.environ.setdefault("AWS_ACCESS_KEY_ID", "test")
35+
os.environ.setdefault("AWS_SECRET_ACCESS_KEY", "test")
36+
3337

3438
class TestRustStackHealth:
3539
"""Basic health check tests."""
@@ -206,28 +210,43 @@ def test_list_objects_pagination(self, client):
206210
client.put_object(Bucket=bucket_name, Key=f"file{i:04d}.txt", Body=f"content {i}")
207211

208212
# First request with small max-keys
209-
result = client.list_objects_v2(Bucket=bucket_name, MaxKeys=10)
213+
result = client.list_objects_v2(Bucket=bucket_name, MaxKeys=15)
210214

211-
assert len(result["Contents"]) == 10
215+
assert len(result["Contents"]) == 15
212216
assert result["IsTruncated"] is True
213217
assert "NextContinuationToken" in result
214218

215-
# Second request with continuation token - should get more objects
219+
# Second request with continuation token
216220
token = result["NextContinuationToken"]
217-
result2 = client.list_objects_v2(Bucket=bucket_name, ContinuationToken=token)
221+
result2 = client.list_objects_v2(Bucket=bucket_name, ContinuationToken=token, MaxKeys=15)
222+
223+
assert len(result2["Contents"]) == 15
224+
assert result2["IsTruncated"] is True
225+
assert "NextContinuationToken" in result2
226+
227+
# Third request
228+
token2 = result2["NextContinuationToken"]
229+
result3 = client.list_objects_v2(Bucket=bucket_name, ContinuationToken=token2, MaxKeys=15)
230+
231+
assert len(result3["Contents"]) == 15
232+
assert result3["IsTruncated"] is True
233+
234+
# Fourth request - should get remaining 5
235+
token3 = result3["NextContinuationToken"]
236+
result4 = client.list_objects_v2(Bucket=bucket_name, ContinuationToken=token3, MaxKeys=15)
218237

219-
# Should have some objects (at least some from the remaining 40)
220-
assert len(result2["Contents"]) > 0
221-
assert len(result2["Contents"]) < 50
238+
assert len(result4["Contents"]) == 5
239+
assert result4["IsTruncated"] is False
240+
assert "NextContinuationToken" not in result4
222241

223242
# Verify all objects can be retrieved by continuing
224243
all_keys = []
225244
token = None
226245
while True:
227246
if token:
228-
result = client.list_objects_v2(Bucket=bucket_name, ContinuationToken=token)
247+
result = client.list_objects_v2(Bucket=bucket_name, ContinuationToken=token, MaxKeys=20)
229248
else:
230-
result = client.list_objects_v2(Bucket=bucket_name)
249+
result = client.list_objects_v2(Bucket=bucket_name, MaxKeys=20)
231250

232251
all_keys.extend([obj["Key"] for obj in result.get("Contents", [])])
233252

0 commit comments

Comments
 (0)