1616import boto3
1717import botocore
1818import pytest
19+ import datetime
1920import logging
2021from typing import Dict , Tuple
2122
@@ -83,7 +84,11 @@ def generate_sagemaker_target(sagemaker_endpoint):
8384 replacements ["SCALABLETARGET_NAME" ] = target_resource_name
8485 replacements ["RESOURCE_ID" ] = resource_id
8586
86- target_reference , target_spec , target_resource = create_applicationautoscaling_resource (
87+ (
88+ target_reference ,
89+ target_spec ,
90+ target_resource ,
91+ ) = create_applicationautoscaling_resource (
8792 resource_plural = TARGET_RESOURCE_PLURAL ,
8893 resource_name = target_resource_name ,
8994 spec_file = "sagemaker_endpoint_autoscaling_target" ,
@@ -92,7 +97,7 @@ def generate_sagemaker_target(sagemaker_endpoint):
9297
9398 assert target_resource is not None
9499
95- yield (resource_id , target_spec , target_reference )
100+ yield (resource_id , target_reference , target_spec , target_resource )
96101
97102 if k8s .get_resource_exists (target_reference ):
98103 _ , deleted = k8s .delete_custom_resource (target_reference )
@@ -101,14 +106,23 @@ def generate_sagemaker_target(sagemaker_endpoint):
101106
102107@pytest .fixture (scope = "module" )
103108def generate_sagemaker_policy (generate_sagemaker_target ):
104- resource_id , target_spec , target_reference = generate_sagemaker_target
109+ (
110+ resource_id ,
111+ target_reference ,
112+ target_spec ,
113+ target_resource ,
114+ ) = generate_sagemaker_target
105115 policy_resource_name = random_suffix_name ("sagemaker-scaling-policy" , 32 )
106116
107117 replacements = REPLACEMENT_VALUES .copy ()
108118 replacements ["SCALINGPOLICY_NAME" ] = policy_resource_name
109119 replacements ["RESOURCE_ID" ] = resource_id
110120
111- policy_reference , policy_spec , policy_resource = create_applicationautoscaling_resource (
121+ (
122+ policy_reference ,
123+ policy_spec ,
124+ policy_resource ,
125+ ) = create_applicationautoscaling_resource (
112126 resource_plural = POLICY_RESOURCE_PLURAL ,
113127 resource_name = policy_resource_name ,
114128 spec_file = "sagemaker_endpoint_autoscaling_policy" ,
@@ -117,7 +131,15 @@ def generate_sagemaker_policy(generate_sagemaker_target):
117131
118132 assert policy_resource is not None
119133
120- yield (resource_id , target_spec , target_reference , policy_resource , policy_spec , policy_reference )
134+ yield (
135+ resource_id ,
136+ target_reference ,
137+ target_spec ,
138+ target_resource ,
139+ policy_resource ,
140+ policy_spec ,
141+ policy_reference ,
142+ )
121143
122144 if k8s .get_resource_exists (policy_reference ):
123145 _ , deleted = k8s .delete_custom_resource (policy_reference )
@@ -127,6 +149,23 @@ def generate_sagemaker_policy(generate_sagemaker_target):
127149@service_marker
128150@pytest .mark .canary
129151class TestSageMakerEndpointAutoscaling :
152+ def wait_until_update (
153+ self , reference , previous_modified_time , wait_period = 2 , wait_time = 30
154+ ):
155+ for i in range (wait_period ):
156+ resource = k8s .get_resource (reference )
157+ assert resource is not None
158+ assert "lastModifiedTime" in resource ["status" ]
159+ last_modified_time = resource ["status" ]["lastModifiedTime" ]
160+ d1 = datetime .datetime .strptime (last_modified_time , "%Y-%m-%dT%H:%M:%SZ" )
161+ d2 = datetime .datetime .strptime (
162+ previous_modified_time , "%Y-%m-%dT%H:%M:%SZ"
163+ )
164+ if d1 > d2 :
165+ return True
166+ sleep (wait_time )
167+ return False
168+
130169 def get_sagemaker_scalable_target_description (
131170 self , applicationautoscaling_client , resource_id : str , expectedTargets : int
132171 ):
@@ -163,8 +202,9 @@ def get_sagemaker_scaling_policy_description(
163202 def test_create (self , applicationautoscaling_client , generate_sagemaker_policy ):
164203 (
165204 resource_id ,
166- target_spec ,
167205 target_reference ,
206+ target_spec ,
207+ target_resource ,
168208 policy_resource ,
169209 policy_spec ,
170210 policy_reference ,
@@ -189,46 +229,56 @@ def test_create(self, applicationautoscaling_client, generate_sagemaker_policy):
189229 def test_update (self , applicationautoscaling_client , generate_sagemaker_policy ):
190230 (
191231 resource_id ,
192- target_spec ,
193232 target_reference ,
233+ target_spec ,
234+ target_resource ,
194235 policy_resource ,
195236 policy_spec ,
196237 policy_reference ,
197238 ) = generate_sagemaker_policy
198239
199240 updatedMaxCapacity = 4
200241 updatedTargetValue = 120
201-
242+
202243 # Update the ScalableTarget
203244 target_spec ["spec" ]["maxCapacity" ] = updatedMaxCapacity
245+ assert "lastModifiedTime" in target_resource ["status" ]
246+ last_modified_time = target_resource ["status" ]["lastModifiedTime" ]
204247 k8s .patch_custom_resource (target_reference , target_spec )
205- sleep ( 5 )
206-
248+ assert self . wait_until_update ( target_reference , last_modified_time ) == True
249+
207250 updated_target_description = self .get_sagemaker_scalable_target_description (
208251 applicationautoscaling_client , resource_id , 1
209252 )
210253 assert updated_target_description is not None
211- assert (
212- updated_target_description [0 ]["MaxCapacity" ] == updatedMaxCapacity
213- )
254+ assert updated_target_description [0 ]["MaxCapacity" ] == updatedMaxCapacity
214255
215256 # Update the ScalingPolicy
216- policy_spec ["spec" ]["targetTrackingScalingPolicyConfiguration" ]["targetValue" ] = updatedTargetValue
257+ policy_spec ["spec" ]["targetTrackingScalingPolicyConfiguration" ][
258+ "targetValue"
259+ ] = updatedTargetValue
260+ assert "lastModifiedTime" in policy_resource ["status" ]
261+ last_modified_time = policy_resource ["status" ]["lastModifiedTime" ]
217262 k8s .patch_custom_resource (policy_reference , policy_spec )
218- sleep (5 )
263+ assert self .wait_until_update (policy_reference , last_modified_time ) == True
264+
219265 updated_policy_description = self .get_sagemaker_scaling_policy_description (
220266 applicationautoscaling_client , resource_id , 1
221267 )
222268 assert updated_policy_description is not None
223269 assert (
224- updated_policy_description [0 ]["TargetTrackingScalingPolicyConfiguration" ]["TargetValue" ] == updatedTargetValue
270+ updated_policy_description [0 ]["TargetTrackingScalingPolicyConfiguration" ][
271+ "TargetValue"
272+ ]
273+ == updatedTargetValue
225274 )
226275
227276 def test_delete (self , applicationautoscaling_client , generate_sagemaker_policy ):
228277 (
229278 resource_id ,
230- target_spec ,
231279 target_reference ,
280+ target_spec ,
281+ target_resource ,
232282 policy_resource ,
233283 policy_spec ,
234284 policy_reference ,
@@ -249,4 +299,4 @@ def test_delete(self, applicationautoscaling_client, generate_sagemaker_policy):
249299 # TODO: Ideally this check should pass after line 188 itself; but it requires the scalabletarget to be deleted too.
250300 policy_description = self .get_sagemaker_scaling_policy_description (
251301 applicationautoscaling_client , resource_id , 0
252- )
302+ )
0 commit comments