Skip to content

Commit 647f990

Browse files
committed
Test: Add tests for Bucket class
1 parent b23a05a commit 647f990

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

tests/s3/__init__.py

Whitespace-only changes.

tests/s3/test_bucket.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
"""
2+
Test the `Bucket` class in `src/gardenlinux/s3/bucket.py` by using
3+
mock AWS interactions provided by the `moto` module.
4+
5+
The `@mock_aws` decorator `moto` provides ensures a fresh
6+
but fake AWS-like environment.
7+
"""
8+
9+
import io
10+
import pytest
11+
import boto3
12+
from moto import mock_aws
13+
from pathlib import Path
14+
15+
from gardenlinux.s3.bucket import Bucket
16+
17+
18+
BUCKET_NAME = "test-bucket"
19+
REGION = "us-east-1"
20+
21+
22+
23+
@mock_aws
24+
def test_objects_empty():
25+
"""
26+
List objects from empty bucket.
27+
"""
28+
# Arrange
29+
s3 = boto3.resource("s3", region_name=REGION)
30+
s3.create_bucket(Bucket=BUCKET_NAME)
31+
32+
# Act
33+
bucket = Bucket(bucket_name=BUCKET_NAME, s3_resource_config={"region_name": REGION})
34+
objects = list(bucket.objects)
35+
36+
# Assert
37+
assert objects == []
38+
39+
40+
@mock_aws
41+
def test_upload_file_and_list(tmp_path):
42+
"""
43+
Create a fake file in a temporary directory, upload and try
44+
to list it
45+
"""
46+
# Arrange
47+
s3 = boto3.resource("s3", region_name=REGION)
48+
s3.create_bucket(Bucket=BUCKET_NAME)
49+
50+
test_file = tmp_path / "example.txt"
51+
test_file.write_text("hello moto")
52+
53+
# Act
54+
bucket = Bucket(bucket_name=BUCKET_NAME, s3_resource_config={"region_name": REGION})
55+
bucket.upload_file(str(test_file), "example.txt")
56+
57+
all_keys = [obj.key for obj in bucket.objects]
58+
59+
# Assert
60+
assert "example.txt" in all_keys
61+
62+
63+
@mock_aws
64+
def test_download_file(tmp_path):
65+
"""
66+
Try to download a file pre-existing in the bucket
67+
"""
68+
# Arrange
69+
s3 = boto3.resource("s3", region_name=REGION)
70+
s3.create_bucket(Bucket=BUCKET_NAME)
71+
s3.Object(BUCKET_NAME, "file.txt").put(Body=b"some data")
72+
73+
# Act
74+
bucket = Bucket(bucket_name=BUCKET_NAME, s3_resource_config={"region_name": REGION})
75+
76+
target_path = tmp_path / "downloaded.txt"
77+
bucket.download_file("file.txt", str(target_path))
78+
79+
# Assert
80+
assert target_path.read_text() == "some data"
81+
82+
83+
@mock_aws
84+
def test_upload_fileobj():
85+
"""
86+
Upload a file-like in-memory object to the bucket
87+
"""
88+
# Arrange
89+
s3 = boto3.resource("s3", region_name=REGION)
90+
s3.create_bucket(Bucket=BUCKET_NAME)
91+
92+
# Act
93+
# Create in-memory binary stream (file content)
94+
data = io.BytesIO(b"Test Data")
95+
bucket = Bucket(bucket_name=BUCKET_NAME, s3_resource_config={"region_name": REGION})
96+
bucket.upload_fileobj(data, "binary.obj")
97+
98+
obj = s3.Object(BUCKET_NAME, "binary.obj").get()
99+
100+
# Assert
101+
assert obj["Body"].read() == b"Test Data"
102+
103+
104+
@mock_aws
105+
def test_download_fileobj():
106+
"""
107+
Download data into a in-memory object
108+
"""
109+
# Arange
110+
s3 = boto3.resource("s3", region_name=REGION)
111+
s3.create_bucket(Bucket=BUCKET_NAME)
112+
# Put some object in the bucket
113+
s3.Object(BUCKET_NAME, "somekey").put(Body=b"123abc")
114+
115+
# Act
116+
bucket = Bucket(bucket_name=BUCKET_NAME, s3_resource_config={"region_name": REGION})
117+
118+
# Create empty in-memory bytestream to act as a writable file
119+
output = io.BytesIO()
120+
bucket.download_fileobj("somekey", output)
121+
122+
# Reset binary cursor to prepare for read
123+
output.seek(0)
124+
125+
# Assert
126+
assert output.read() == b"123abc"
127+
128+
129+
@mock_aws
130+
def test_getattr_delegates():
131+
"""
132+
Verify that attribute access is delegated to the underlying boto3 Bucket.
133+
134+
This checks that accessing e.g. `.name` on our custom Bucket works by forwarding
135+
the call to the real boto3 bucket.
136+
"""
137+
# Arrange
138+
s3 = boto3.resource("s3", region_name=REGION)
139+
s3.create_bucket(Bucket=BUCKET_NAME)
140+
141+
# Act
142+
bucket = Bucket(bucket_name=BUCKET_NAME, s3_resource_config={"region_name": REGION})
143+
144+
# Assert
145+
# __getattr__ should delegate this to the underlying boto3 Bucket object
146+
assert bucket.name == BUCKET_NAME

0 commit comments

Comments
 (0)