@@ -200,6 +200,67 @@ func testSingleHeaderBasedGRPCRoute(ctx context.Context, t *testing.T, config *e
200200 return ctx
201201 }
202202 logrus .Infof ("grpcRoute %q was updated" , resourcesMap [GRPC_ROUTE_KEY ].GetName ())
203+ // Manually promote the canary by removing the pause step to allow rollout to finish
204+ unstructured .RemoveNestedField (resourcesMap [ROLLOUT_KEY ].Object , "metadata" , "resourceVersion" )
205+ // Remove the pause step from the canary strategy steps
206+ steps , found , err := unstructured .NestedSlice (resourcesMap [ROLLOUT_KEY ].Object , "spec" , "strategy" , "canary" , "steps" )
207+ if ! found || err != nil {
208+ logrus .Errorf ("rollout %q canary steps not found or error: %s" , resourcesMap [ROLLOUT_KEY ].GetName (), err )
209+ t .Error ()
210+ return ctx
211+ }
212+ // Filter out the pause step from the steps array
213+ var filteredSteps []interface {}
214+ for _ , step := range steps {
215+ stepMap , ok := step .(map [string ]interface {})
216+ if ! ok {
217+ continue
218+ }
219+ // Skip any step that contains a "pause" key
220+ if _ , hasPause := stepMap ["pause" ]; ! hasPause {
221+ filteredSteps = append (filteredSteps , step )
222+ }
223+ }
224+ err = unstructured .SetNestedSlice (resourcesMap [ROLLOUT_KEY ].Object , filteredSteps , "spec" , "strategy" , "canary" , "steps" )
225+ if err != nil {
226+ logrus .Errorf ("rollout %q steps update failed: %s" , resourcesMap [ROLLOUT_KEY ].GetName (), err )
227+ t .Error ()
228+ return ctx
229+ }
230+ serializedRolloutPromotion , err := json .Marshal (resourcesMap [ROLLOUT_KEY ].Object )
231+ if err != nil {
232+ logrus .Errorf ("rollout %q promotion serializing was failed: %s" , resourcesMap [ROLLOUT_KEY ].GetName (), err )
233+ t .Error ()
234+ return ctx
235+ }
236+ logrus .Infof ("rollout %q promotion was serialized" , resourcesMap [ROLLOUT_KEY ].GetName ())
237+ rolloutPromotionPatch := k8s.Patch {
238+ PatchType : types .MergePatchType ,
239+ Data : serializedRolloutPromotion ,
240+ }
241+ err = clusterResources .Patch (ctx , resourcesMap [ROLLOUT_KEY ], rolloutPromotionPatch )
242+ if err != nil {
243+ logrus .Errorf ("rollout %q promotion was failed: %s" , resourcesMap [ROLLOUT_KEY ].GetName (), err )
244+ t .Error ()
245+ return ctx
246+ }
247+ logrus .Infof ("rollout %q was promoted to finish canary deployment" , resourcesMap [ROLLOUT_KEY ].GetName ())
248+ // Wait for rollout to reach a healthy finished state
249+ logrus .Infof ("waiting for rollout %q to complete and reach healthy status" , resourcesMap [ROLLOUT_KEY ].GetName ())
250+ err = wait .For (
251+ waitCondition .ResourceMatch (
252+ resourcesMap [ROLLOUT_KEY ],
253+ getRolloutHealthyFetcher (t ),
254+ ),
255+ wait .WithTimeout (LONG_PERIOD ),
256+ wait .WithInterval (SHORT_PERIOD ),
257+ )
258+ if err != nil {
259+ logrus .Errorf ("rollout %q completion was failed: %s" , resourcesMap [ROLLOUT_KEY ].GetName (), err )
260+ t .Error ()
261+ return ctx
262+ }
263+ logrus .Infof ("rollout %q completed successfully" , resourcesMap [ROLLOUT_KEY ].GetName ())
203264 logrus .Infof ("waiting for grpcRoute %q to clean up header-based routing and reset canary weight to %d" , resourcesMap [GRPC_ROUTE_KEY ].GetName (), FIRST_CANARY_ROUTE_WEIGHT )
204265 err = wait .For (
205266 waitCondition .ResourceMatch (
@@ -282,3 +343,24 @@ func getMatchHeaderBasedGRPCRouteFetcher(t *testing.T, targetWeight int32, targe
282343func isHeaderBasedGRPCRouteValuesEqual (first , second gatewayv1.GRPCHeaderMatch ) bool {
283344 return first .Name == second .Name && * first .Type == * second .Type && first .Value == second .Value
284345}
346+
347+ func getRolloutHealthyFetcher (t * testing.T ) func (k8s.Object ) bool {
348+ return func (obj k8s.Object ) bool {
349+ var rollout v1alpha1.Rollout
350+ unstructuredRollout , ok := obj .(* unstructured.Unstructured )
351+ if ! ok {
352+ logrus .Error ("k8s rollout object type assertion was failed" )
353+ t .Error ()
354+ return false
355+ }
356+ err := runtime .DefaultUnstructuredConverter .FromUnstructured (unstructuredRollout .Object , & rollout )
357+ if err != nil {
358+ logrus .Errorf ("conversation from unstructured rollout %q to the typed rollout was failed" , unstructuredRollout .GetName ())
359+ t .Error ()
360+ return false
361+ }
362+ // Check if rollout is healthy (completed successfully)
363+ // A rollout is considered finished when its phase is "Healthy"
364+ return rollout .Status .Phase == "Healthy"
365+ }
366+ }
0 commit comments