Skip to content

Commit 3485247

Browse files
committed
Integrate CR feedback - integration tests update
1 parent b79b571 commit 3485247

File tree

3 files changed

+96
-77
lines changed

3 files changed

+96
-77
lines changed

pkg/resource/managed_prefix_list/hooks.go

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,13 @@ func (rm *resourceManager) customUpdateManagedPrefixList(
138138
input.RemoveEntries = removeEntries
139139
}
140140

141-
// Set current version for optimistic locking
141+
// Set current version for optimistic locking (required by AWS)
142142
if latest.ko.Status.Version != nil {
143143
input.CurrentVersion = latest.ko.Status.Version
144144
}
145145
}
146146

147147
// Only call ModifyManagedPrefixList if there are actual changes
148-
needsRead := false
149148
if input.PrefixListName != nil || input.MaxEntries != nil ||
150149
len(input.AddEntries) > 0 || len(input.RemoveEntries) > 0 {
151150
resp, err := rm.sdkapi.ModifyManagedPrefixList(ctx, input)
@@ -163,9 +162,6 @@ func (rm *resourceManager) customUpdateManagedPrefixList(
163162
desired.ko.Status.Version = resp.PrefixList.Version
164163
}
165164
}
166-
167-
// Mark that we need to read the resource again to get the latest state
168-
needsRead = true
169165
}
170166

171167
// Handle tag updates separately
@@ -178,17 +174,5 @@ func (rm *resourceManager) customUpdateManagedPrefixList(
178174
}
179175
}
180176

181-
// After modifying the prefix list, read it again to get the current state
182-
// This ensures we have the latest version and state information
183-
if needsRead {
184-
updated, err := rm.sdkFind(ctx, desired)
185-
if err != nil {
186-
return nil, err
187-
}
188-
if updated != nil {
189-
return updated, nil
190-
}
191-
}
192-
193177
return desired, nil
194178
}

test/e2e/tests/helper.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,17 @@ def get_launch_template_version(self, launch_template_id: str, version: str) ->
386386
return None
387387

388388
def get_managed_prefix_list(self, prefix_list_id: str) -> Union[None, Dict]:
389-
"""Get a managed prefix list by ID."""
389+
"""Get a managed prefix list by ID, including its entries."""
390390
try:
391391
aws_res = self.ec2_client.describe_managed_prefix_lists(PrefixListIds=[prefix_list_id])
392392
if len(aws_res["PrefixLists"]) > 0:
393-
return aws_res["PrefixLists"][0]
393+
prefix_list = aws_res["PrefixLists"][0]
394+
395+
# Also fetch the entries
396+
entries_res = self.ec2_client.get_managed_prefix_list_entries(PrefixListId=prefix_list_id)
397+
prefix_list["Entries"] = entries_res.get("Entries", [])
398+
399+
return prefix_list
394400
return None
395401
except self.ec2_client.exceptions.ClientError:
396402
return None

test/e2e/tests/test_managed_prefix_list.py

Lines changed: 87 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def test_create_delete_ipv4(self, prefix_list_ipv4, ec2_validator):
125125
assert cr is not None
126126
assert 'status' in cr
127127
assert 'prefixListID' in cr['status']
128-
128+
129129
prefix_list_id = cr['status']['prefixListID']
130130
assert prefix_list_id is not None
131131
assert prefix_list_id.startswith('pl-')
@@ -136,17 +136,21 @@ def test_create_delete_ipv4(self, prefix_list_ipv4, ec2_validator):
136136
assert state in ['create-in-progress', 'create-complete']
137137

138138
# Wait for AWS to complete creation
139-
logging.info(f"Waiting for prefix list {prefix_list_id} to reach create-complete state...")
140139
state_reached = ec2_validator.wait_managed_prefix_list_state(
141140
prefix_list_id,
142141
'create-complete',
143142
max_wait_seconds=180
144143
)
145144
assert state_reached, f"Prefix list {prefix_list_id} did not reach create-complete state within timeout"
146145

147-
# Get updated resource from K8s
146+
# Wait for K8s controller to sync the state from AWS
147+
assert k8s.wait_on_condition(ref, "ACK.ResourceSynced", "True", wait_periods=30), \
148+
"Resource did not sync within timeout"
149+
150+
# Verify final state
148151
cr = k8s.get_resource(ref)
149-
assert cr['status']['state'] == 'create-complete', f"K8s state is {cr['status']['state']}, expected create-complete"
152+
assert cr['status'].get('state') == 'create-complete', \
153+
f"Expected state create-complete, got {cr['status'].get('state')}"
150154

151155
# Check that version was set
152156
assert 'version' in cr['status']
@@ -160,7 +164,7 @@ def test_create_delete_ipv6(self, prefix_list_ipv6, ec2_validator):
160164
assert cr is not None
161165
assert 'status' in cr
162166
assert 'prefixListID' in cr['status']
163-
167+
164168
prefix_list_id = cr['status']['prefixListID']
165169
assert prefix_list_id is not None
166170
assert prefix_list_id.startswith('pl-')
@@ -169,41 +173,48 @@ def test_create_delete_ipv6(self, prefix_list_ipv6, ec2_validator):
169173
assert cr['spec']['addressFamily'] == 'IPv6'
170174

171175
# Wait for AWS to complete creation
172-
logging.info(f"Waiting for IPv6 prefix list {prefix_list_id} to reach create-complete state...")
173176
state_reached = ec2_validator.wait_managed_prefix_list_state(
174177
prefix_list_id,
175178
'create-complete',
176179
max_wait_seconds=180
177180
)
178181
assert state_reached, f"Prefix list {prefix_list_id} did not reach create-complete state within timeout"
179182

180-
# Get updated resource from K8s
183+
# Wait for K8s controller to sync the state from AWS
184+
assert k8s.wait_on_condition(ref, "ACK.ResourceSynced", "True", wait_periods=30), \
185+
"Resource did not sync within timeout"
186+
187+
# Verify final state
181188
cr = k8s.get_resource(ref)
182-
assert cr['status']['state'] == 'create-complete', f"K8s state is {cr['status']['state']}, expected create-complete"
189+
assert cr['status'].get('state') == 'create-complete', \
190+
f"Expected state create-complete, got {cr['status'].get('state')}"
183191

184192
def test_update_entries(self, prefix_list_ipv4, ec2_validator):
185-
"""Test updating prefix list entries."""
193+
"""Test adding and removing prefix list entries."""
186194
(ref, cr) = prefix_list_ipv4
187195

188196
# Get the prefix list ID
189197
assert 'prefixListID' in cr['status'], "PrefixListID should be present in status"
190198
prefix_list_id = cr['status']['prefixListID']
191199

192200
# Wait for initial creation to complete in AWS
193-
logging.info(f"Waiting for prefix list {prefix_list_id} to reach create-complete state before update...")
194201
state_reached = ec2_validator.wait_managed_prefix_list_state(
195202
prefix_list_id,
196203
'create-complete',
197204
max_wait_seconds=180
198205
)
199-
assert state_reached, f"Prefix list {prefix_list_id} did not reach create-complete state before update"
206+
assert state_reached, f"Prefix list {prefix_list_id} did not reach create-complete state"
207+
208+
# Verify initial state - should have 3 entries
209+
aws_prefix_list = ec2_validator.get_managed_prefix_list(prefix_list_id)
210+
initial_count = len(aws_prefix_list.get('Entries', []))
211+
assert initial_count == 3, f"Expected 3 initial entries, got {initial_count}"
200212

201-
# Get the latest resource with the initial version
213+
# Get the latest resource
202214
cr = k8s.get_resource(ref)
203215
assert cr['status']['state'] == 'create-complete', f"K8s state is {cr['status']['state']}, expected create-complete"
204-
initial_version = cr['status']['version']
205216

206-
# Update the entries - add a new CIDR block
217+
# ===== TEST 1: Add an entry (3 → 4) =====
207218
cr['spec']['entries'].append({
208219
'cidr': '10.0.2.0/24',
209220
'description': 'New network C'
@@ -212,55 +223,69 @@ def test_update_entries(self, prefix_list_ipv4, ec2_validator):
212223
# Apply the update
213224
k8s.patch_custom_resource(ref, cr)
214225

215-
# Wait for the prefix list to complete modification in AWS
216-
# This can take some time as AWS needs to propagate the changes
217-
logging.info(f"Waiting for prefix list {prefix_list_id} to reach modify-complete state...")
226+
# Give AWS time to process the async modification
227+
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
228+
229+
# Wait for the controller to process and sync the change
230+
assert k8s.wait_on_condition(ref, "ACK.ResourceSynced", "True", wait_periods=40), \
231+
"Resource did not sync after add"
232+
233+
# Now wait for AWS to complete the modification
234+
state_reached = ec2_validator.wait_managed_prefix_list_state(
235+
prefix_list_id,
236+
'modify-complete',
237+
max_wait_seconds=180
238+
)
239+
assert state_reached, f"Prefix list {prefix_list_id} did not reach modify-complete state after add"
240+
241+
# Verify in AWS
242+
aws_prefix_list = ec2_validator.get_managed_prefix_list(prefix_list_id)
243+
after_add_count = len(aws_prefix_list.get('Entries', []))
244+
assert after_add_count == 4, f"Expected 4 entries after add, got {after_add_count}"
245+
246+
# ===== TEST 2: Remove an entry (4 → 3) =====
247+
cr = k8s.get_resource(ref)
248+
original_entries = cr['spec']['entries'][:]
249+
250+
# Remove the entry we just added
251+
entry_to_remove = '10.0.2.0/24'
252+
cr['spec']['entries'] = [e for e in original_entries if e['cidr'] != entry_to_remove]
253+
254+
# Apply the update
255+
k8s.patch_custom_resource(ref, cr)
256+
257+
# Give AWS time to process the async modification
258+
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
259+
260+
# Wait for the controller to process and sync the change
261+
assert k8s.wait_on_condition(ref, "ACK.ResourceSynced", "True", wait_periods=40), \
262+
"Resource did not sync after removal"
263+
264+
# Now wait for AWS to complete the modification
218265
state_reached = ec2_validator.wait_managed_prefix_list_state(
219266
prefix_list_id,
220267
'modify-complete',
221268
max_wait_seconds=180
222269
)
223-
assert state_reached, f"Prefix list {prefix_list_id} did not reach modify-complete state within timeout"
224-
225-
# Wait for the controller to sync the status from AWS to K8s
226-
# Poll K8s status until version is incremented AND state is modify-complete
227-
logging.info(f"Waiting for K8s controller to sync updated version and state from AWS...")
228-
version_updated = False
229-
state_updated = False
230-
max_sync_tries = 30 # 30 * 5 = 150 seconds
231-
for try_num in range(max_sync_tries):
232-
cr = k8s.get_resource(ref)
233-
current_state = cr['status'].get('state', '')
234-
if 'version' in cr['status']:
235-
current_version = cr['status']['version']
236-
if current_version > initial_version and current_state == 'modify-complete':
237-
version_updated = True
238-
state_updated = True
239-
updated_version = current_version
240-
logging.info(f"Version updated from {initial_version} to {updated_version} and state is {current_state} after {try_num * 5} seconds")
241-
break
242-
elif current_version > initial_version:
243-
logging.info(f"Version updated to {current_version} but state is still {current_state}, waiting...")
244-
time.sleep(5)
245-
246-
assert version_updated, \
247-
f"K8s status version did not increment from {initial_version} within {max_sync_tries * 5} seconds"
248-
249-
assert state_updated, \
250-
f"K8s status state did not reach modify-complete within {max_sync_tries * 5} seconds, last state: {cr['status'].get('state', 'unknown')}"
251-
252-
# Check that version was incremented
253-
assert updated_version > initial_version, \
254-
f"Version should have incremented from {initial_version} to greater value, got {updated_version}"
255-
256-
# Verify entries were updated in K8s spec
257-
assert len(cr['spec']['entries']) == 4, \
258-
f"Expected 4 entries (3 original + 1 new), got {len(cr['spec']['entries'])}"
259-
260-
# Verify entries in AWS
270+
assert state_reached, f"Prefix list {prefix_list_id} did not reach modify-complete state after removal"
271+
272+
# Verify in AWS
261273
aws_prefix_list = ec2_validator.get_managed_prefix_list(prefix_list_id)
262-
assert aws_prefix_list['Version'] == updated_version, \
263-
f"AWS version {aws_prefix_list['Version']} should match K8s version {updated_version}"
274+
after_remove_entries = aws_prefix_list.get('Entries', [])
275+
after_remove_count = len(after_remove_entries)
276+
aws_cidrs = [e['Cidr'] for e in after_remove_entries]
277+
278+
# Verify deletion happened
279+
assert after_remove_count == 3, f"Expected 3 entries after removal, got {after_remove_count}"
280+
assert entry_to_remove not in aws_cidrs, \
281+
f"Entry {entry_to_remove} should have been removed but is still in AWS: {aws_cidrs}"
282+
283+
# Final verification - check K8s matches AWS
284+
cr = k8s.get_resource(ref)
285+
k8s_cidrs = [e['cidr'] for e in cr['spec'].get('entries', [])]
286+
assert len(k8s_cidrs) == 3, f"Expected 3 entries in K8s, got {len(k8s_cidrs)}"
287+
assert entry_to_remove not in k8s_cidrs, \
288+
f"Entry {entry_to_remove} should not be in K8s: {k8s_cidrs}"
264289

265290
def test_update_tags(self, prefix_list_ipv4):
266291
"""Test updating prefix list tags."""
@@ -282,9 +307,13 @@ def test_update_tags(self, prefix_list_ipv4):
282307
k8s.patch_custom_resource(ref, cr)
283308
time.sleep(UPDATE_WAIT_AFTER_SECONDS)
284309

310+
# Wait for the resource to be synced
311+
assert k8s.wait_on_condition(ref, "ACK.ResourceSynced", "True", wait_periods=5), \
312+
"Resource did not sync after tag update"
313+
285314
# Get the updated resource
286315
cr = k8s.get_resource(ref)
287-
316+
288317
# Verify tag was added
289318
tags = cr['spec'].get('tags', [])
290319
assert any(tag['key'] == 'Environment' and tag['value'] == 'Test' for tag in tags)

0 commit comments

Comments
 (0)