Skip to content

Commit bb51fbd

Browse files
Add individual tests for each supported Put* operation (#29)
Added individual resources and tests for each of the `Put*` operations. I chose to test them all separately so that errors in one do not impact any of the others.
1 parent 4447657 commit bb51fbd

9 files changed

+256
-57
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: s3.services.k8s.aws/v1alpha1
2+
kind: Bucket
3+
metadata:
4+
name: $BUCKET_NAME
5+
spec:
6+
name: $BUCKET_NAME
7+
accelerate:
8+
status: Enabled

test/e2e/resources/bucket_cors.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: s3.services.k8s.aws/v1alpha1
2+
kind: Bucket
3+
metadata:
4+
name: $BUCKET_NAME
5+
spec:
6+
name: $BUCKET_NAME
7+
cors:
8+
corsRules:
9+
- allowedMethods:
10+
- GET
11+
- PUT
12+
allowedOrigins:
13+
- localhost
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: s3.services.k8s.aws/v1alpha1
2+
kind: Bucket
3+
metadata:
4+
name: $BUCKET_NAME
5+
spec:
6+
name: $BUCKET_NAME
7+
encryption:
8+
rules:
9+
- bucketKeyEnabled: false
10+
applyServerSideEncryptionByDefault:
11+
sseAlgorithm: AES256
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: s3.services.k8s.aws/v1alpha1
2+
kind: Bucket
3+
metadata:
4+
name: $BUCKET_NAME
5+
spec:
6+
name: $BUCKET_NAME
7+
acl: log-delivery-write
8+
logging:
9+
loggingEnabled:
10+
targetBucket: $BUCKET_NAME
11+
targetPrefix: "logging-"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: s3.services.k8s.aws/v1alpha1
2+
kind: Bucket
3+
metadata:
4+
name: $BUCKET_NAME
5+
spec:
6+
name: $BUCKET_NAME
7+
ownershipControls:
8+
rules:
9+
- objectOwnership: ObjectWriter
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: s3.services.k8s.aws/v1alpha1
2+
kind: Bucket
3+
metadata:
4+
name: $BUCKET_NAME
5+
spec:
6+
name: $BUCKET_NAME
7+
requestPayment:
8+
payer: Requester
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: s3.services.k8s.aws/v1alpha1
2+
kind: Bucket
3+
metadata:
4+
name: $BUCKET_NAME
5+
spec:
6+
name: $BUCKET_NAME
7+
tagging:
8+
tagSet:
9+
- key: "first"
10+
value: "1"
11+
- key: "second"
12+
value: "2"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: s3.services.k8s.aws/v1alpha1
2+
kind: Bucket
3+
metadata:
4+
name: $BUCKET_NAME
5+
spec:
6+
name: $BUCKET_NAME
7+
website:
8+
indexDocument:
9+
suffix: index.html
10+
errorDocument:
11+
key: error.html

test/e2e/tests/test_bucket.py

Lines changed: 173 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import pytest
1919
import time
2020
import logging
21-
from typing import Dict, Tuple
2221

2322
from acktest.resources import random_suffix_name
2423
from acktest.k8s import resource as k8s
@@ -31,66 +30,183 @@
3130
CREATE_WAIT_AFTER_SECONDS = 10
3231
DELETE_WAIT_AFTER_SECONDS = 10
3332

33+
def get_bucket(s3_resource, bucket_name: str):
34+
return s3_resource.Bucket(bucket_name)
35+
36+
def bucket_exists(s3_client, bucket_name: str) -> bool:
37+
try:
38+
resp = s3_client.list_buckets()
39+
except Exception as e:
40+
logging.debug(e)
41+
return False
42+
43+
buckets = resp["Buckets"]
44+
for bucket in buckets:
45+
if bucket["Name"] == bucket_name:
46+
return True
47+
48+
return False
49+
50+
def create_bucket(s3_client, resource_file_name: str):
51+
resource_name = random_suffix_name("s3-bucket", 24)
52+
53+
replacements = REPLACEMENT_VALUES.copy()
54+
replacements["BUCKET_NAME"] = resource_name
55+
56+
# Load Bucket CR
57+
resource_data = load_s3_resource(
58+
resource_file_name,
59+
additional_replacements=replacements,
60+
)
61+
logging.debug(resource_data)
62+
63+
# Create k8s resource
64+
ref = k8s.CustomResourceReference(
65+
CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
66+
resource_name, namespace="default",
67+
)
68+
k8s.create_custom_resource(ref, resource_data)
69+
cr = k8s.wait_resource_consumed_by_controller(ref)
70+
71+
assert cr is not None
72+
assert k8s.get_resource_exists(ref)
73+
74+
time.sleep(CREATE_WAIT_AFTER_SECONDS)
75+
76+
# Check S3 Bucket exists
77+
exists = bucket_exists(s3_client, resource_name)
78+
assert exists
79+
80+
return (ref, resource_name, resource_data)
81+
82+
def delete_bucket(s3_client, ref, resource_name):
83+
# Delete k8s resource
84+
_, deleted = k8s.delete_custom_resource(ref)
85+
assert deleted is True
86+
87+
time.sleep(DELETE_WAIT_AFTER_SECONDS)
88+
89+
# Check S3 Bucket doesn't exists
90+
exists = bucket_exists(s3_client, resource_name)
91+
assert not exists
92+
3493
@pytest.fixture(scope="module")
3594
def s3_client():
3695
return boto3.client("s3")
3796

97+
@pytest.fixture(scope="module")
98+
def s3_resource():
99+
return boto3.resource("s3")
100+
38101
@service_marker
39102
@pytest.mark.canary
40103
class TestBucket:
41-
def get_bucket(self, s3_client, bucket_name: str) -> dict:
42-
try:
43-
resp = s3_client.list_buckets()
44-
except Exception as e:
45-
logging.debug(e)
46-
return None
47-
48-
buckets = resp["Buckets"]
49-
for bucket in buckets:
50-
if bucket["Name"] == bucket_name:
51-
return bucket
52-
53-
return None
54-
55-
def bucket_exists(self, s3_client, bucket_name: str) -> bool:
56-
return self.get_bucket(s3_client, bucket_name) is not None
57-
58-
def test_smoke(self, s3_client):
59-
resource_name = random_suffix_name("s3-bucket", 24)
60-
61-
replacements = REPLACEMENT_VALUES.copy()
62-
replacements["BUCKET_NAME"] = resource_name
63-
64-
# Load Bucket CR
65-
resource_data = load_s3_resource(
66-
"bucket",
67-
additional_replacements=replacements,
68-
)
69-
logging.debug(resource_data)
70-
71-
# Create k8s resource
72-
ref = k8s.CustomResourceReference(
73-
CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL,
74-
resource_name, namespace="default",
75-
)
76-
k8s.create_custom_resource(ref, resource_data)
77-
cr = k8s.wait_resource_consumed_by_controller(ref)
78-
79-
assert cr is not None
80-
assert k8s.get_resource_exists(ref)
81-
82-
time.sleep(CREATE_WAIT_AFTER_SECONDS)
83-
84-
# Check S3 Bucket exists
85-
exists = self.bucket_exists(s3_client, resource_name)
86-
assert exists
87-
88-
# Delete k8s resource
89-
_, deleted = k8s.delete_custom_resource(ref)
90-
assert deleted is True
91-
92-
time.sleep(DELETE_WAIT_AFTER_SECONDS)
93-
94-
# Check S3 Bucket doesn't exists
95-
exists = self.bucket_exists(s3_client, resource_name)
96-
assert not exists
104+
def test_basic(self, s3_client):
105+
(ref, resource_name, _) = create_bucket(s3_client, "bucket")
106+
delete_bucket(s3_client, ref, resource_name)
107+
108+
def test_accelerate(self, s3_client):
109+
(ref, resource_name, resource_data) = create_bucket(s3_client, "bucket_accelerate")
110+
111+
accelerate_configuration = s3_client.get_bucket_accelerate_configuration(Bucket=resource_name)
112+
assert resource_data["spec"]["accelerate"]["status"] == accelerate_configuration["Status"]
113+
114+
delete_bucket(s3_client, ref, resource_name)
115+
116+
def test_cors(self, s3_client, s3_resource):
117+
(ref, resource_name, resource_data) = create_bucket(s3_client, "bucket_cors")
118+
119+
# Do checks
120+
bucket = get_bucket(s3_resource, resource_name)
121+
cors = bucket.Cors()
122+
123+
desired_rule = resource_data["spec"]["cors"]["corsRules"][0]
124+
latest_rule = cors.cors_rules[0]
125+
126+
assert desired_rule.get("allowedMethods", []) == latest_rule.get("AllowedMethods", [])
127+
assert desired_rule.get("allowedOrigins", []) == latest_rule.get("AllowedOrigins", [])
128+
assert desired_rule.get("allowedHeaders", []) == latest_rule.get("AllowedHeaders", [])
129+
assert desired_rule.get("exposeHeaders", []) == latest_rule.get("ExposeHeaders", [])
130+
131+
delete_bucket(s3_client, ref, resource_name)
132+
133+
def test_encryption(self, s3_client):
134+
(ref, resource_name, resource_data) = create_bucket(s3_client, "bucket_encryption")
135+
136+
encryption = s3_client.get_bucket_encryption(Bucket=resource_name)
137+
138+
desired_rule = resource_data["spec"]["encryption"]["rules"][0]
139+
latest_rule = encryption["ServerSideEncryptionConfiguration"]["Rules"][0]
140+
141+
assert desired_rule["applyServerSideEncryptionByDefault"]["sseAlgorithm"] == \
142+
latest_rule["ApplyServerSideEncryptionByDefault"]["SSEAlgorithm"]
143+
144+
delete_bucket(s3_client, ref, resource_name)
145+
146+
def test_logging(self, s3_client, s3_resource):
147+
(ref, resource_name, resource_data) = create_bucket(s3_client, "bucket_logging")
148+
149+
bucket = get_bucket(s3_resource, resource_name)
150+
logging = bucket.Logging()
151+
152+
desired = resource_data["spec"]["logging"]["loggingEnabled"]
153+
latest = logging.logging_enabled
154+
155+
assert desired["targetBucket"] == latest["TargetBucket"]
156+
assert desired["targetPrefix"] == latest["TargetPrefix"]
157+
158+
delete_bucket(s3_client, ref, resource_name)
159+
160+
def test_ownership_controls(self, s3_client):
161+
(ref, resource_name, resource_data) = create_bucket(s3_client, "bucket_ownership_controls")
162+
163+
ownership_controls = s3_client.get_bucket_ownership_controls(Bucket=resource_name)
164+
165+
desired_rule = resource_data["spec"]["ownershipControls"]["rules"][0]
166+
latest_rule = ownership_controls["OwnershipControls"]["Rules"][0]
167+
168+
assert desired_rule["objectOwnership"] == latest_rule["ObjectOwnership"]
169+
170+
delete_bucket(s3_client, ref, resource_name)
171+
172+
def test_request_payment(self, s3_client, s3_resource):
173+
(ref, resource_name, resource_data) = create_bucket(s3_client, "bucket_request_payment")
174+
175+
bucket = get_bucket(s3_resource, resource_name)
176+
request_payment = bucket.RequestPayment()
177+
178+
desired = resource_data["spec"]["requestPayment"]["payer"]
179+
latest = request_payment.payer
180+
181+
assert desired == latest
182+
183+
delete_bucket(s3_client, ref, resource_name)
184+
185+
def test_tagging(self, s3_client, s3_resource):
186+
(ref, resource_name, resource_data) = create_bucket(s3_client, "bucket_tagging")
187+
188+
bucket = get_bucket(s3_resource, resource_name)
189+
tagging = bucket.Tagging()
190+
191+
desired = resource_data["spec"]["tagging"]["tagSet"]
192+
latest = tagging.tag_set
193+
194+
for i in range(2):
195+
assert desired[i]["key"] == latest[i]["Key"]
196+
assert desired[i]["value"] == latest[i]["Value"]
197+
198+
delete_bucket(s3_client, ref, resource_name)
199+
200+
def test_website(self, s3_client, s3_resource):
201+
(ref, resource_name, resource_data) = create_bucket(s3_client, "bucket_website")
202+
203+
bucket = get_bucket(s3_resource, resource_name)
204+
website = bucket.Website()
205+
206+
desired = resource_data["spec"]["website"]
207+
latest = website
208+
209+
assert desired["errorDocument"]["key"] == latest.error_document["Key"]
210+
assert desired["indexDocument"]["suffix"] == latest.index_document["Suffix"]
211+
212+
delete_bucket(s3_client, ref, resource_name)

0 commit comments

Comments
 (0)