@@ -23,6 +23,8 @@ import (
2323 "github.com/aws/aws-sdk-go-v2/service/ecs/types"
2424 "github.com/stretchr/testify/assert"
2525 "github.com/stretchr/testify/require"
26+
27+ "github.com/pipe-cd/pipecd/pkg/app/pipedv1/plugin/ecs/provider"
2628)
2729
2830func TestRollBack (t * testing.T ) {
@@ -327,3 +329,152 @@ func TestRollBack(t *testing.T) {
327329 })
328330 }
329331}
332+
333+ func TestRestoreELBWeights (t * testing.T ) {
334+ t .Parallel ()
335+
336+ var (
337+ primaryARN = "arn:aws:elasticloadbalancing:us-east-1:123:targetgroup/primary/aaa"
338+ canaryARN = "arn:aws:elasticloadbalancing:us-east-1:123:targetgroup/canary/bbb"
339+ listenerARN1 = "arn:aws:elasticloadbalancing:us-east-1:123:listener/app/my-alb/aaa/bbb"
340+ listenerARN2 = "arn:aws:elasticloadbalancing:us-east-1:123:listener/app/my-alb/aaa/ccc"
341+ primaryLB = & types.LoadBalancer {TargetGroupArn : aws .String (primaryARN )}
342+ )
343+
344+ testcases := []struct {
345+ name string
346+ primary * types.LoadBalancer
347+ metadata * mockMetadataStore
348+ client * mockECSClient
349+ wantErr bool
350+ wantErrMsg string
351+ }{
352+ {
353+ name : "success: listener ARNs and canary ARN in metadata, weights restored to 100/0" ,
354+ primary : primaryLB ,
355+ metadata : func () * mockMetadataStore {
356+ m := happyMetadataStore ()
357+ m .GetFunc = func (_ context.Context , key string ) (string , bool , error ) {
358+ switch key {
359+ case currentListenersKey :
360+ return listenerARN1 + "," + listenerARN2 , true , nil
361+ case canaryTargetGroupArnKey :
362+ return canaryARN , true , nil
363+ }
364+ return "" , false , nil
365+ }
366+ return m
367+ }(),
368+ client : func () * mockECSClient {
369+ m := & mockECSClient {}
370+ m .ModifyListenersFunc = func (_ context.Context , listenerArns []string , cfg provider.RoutingTrafficConfig ) ([]string , error ) {
371+ assert .Equal (t , []string {listenerARN1 , listenerARN2 }, listenerArns )
372+ assert .Equal (t , provider.RoutingTrafficConfig {
373+ {TargetGroupArn : primaryARN , Weight : 100 },
374+ {TargetGroupArn : canaryARN , Weight : 0 },
375+ }, cfg )
376+ return []string {"rule-1" }, nil
377+ }
378+ return m
379+ }(),
380+ },
381+ {
382+ name : "success (no-op): no listener ARNs in metadata (traffic routing never ran)" ,
383+ primary : primaryLB ,
384+ metadata : happyMetadataStore (), // GetFunc returns (_, false, nil) for all keys
385+ client : & mockECSClient {},
386+ },
387+ {
388+ name : "success (no-op): listener ARNs found but no canary ARN in metadata" ,
389+ primary : primaryLB ,
390+ metadata : func () * mockMetadataStore {
391+ m := happyMetadataStore ()
392+ m .GetFunc = func (_ context.Context , key string ) (string , bool , error ) {
393+ if key == currentListenersKey {
394+ return listenerARN1 , true , nil
395+ }
396+ return "" , false , nil
397+ }
398+ return m
399+ }(),
400+ client : & mockECSClient {},
401+ },
402+ {
403+ name : "fail: GetDeploymentPluginMetadata error for listener ARNs" ,
404+ primary : primaryLB ,
405+ metadata : func () * mockMetadataStore {
406+ m := happyMetadataStore ()
407+ m .GetFunc = func (_ context.Context , key string ) (string , bool , error ) {
408+ if key == currentListenersKey {
409+ return "" , false , errors .New ("metadata error" )
410+ }
411+ return "" , false , nil
412+ }
413+ return m
414+ }(),
415+ client : & mockECSClient {},
416+ wantErr : true ,
417+ wantErrMsg : "failed to get listener ARNs from metadata" ,
418+ },
419+ {
420+ name : "fail: GetDeploymentPluginMetadata error for canary ARN" ,
421+ primary : primaryLB ,
422+ metadata : func () * mockMetadataStore {
423+ m := happyMetadataStore ()
424+ m .GetFunc = func (_ context.Context , key string ) (string , bool , error ) {
425+ switch key {
426+ case currentListenersKey :
427+ return listenerARN1 , true , nil
428+ case canaryTargetGroupArnKey :
429+ return "" , false , errors .New ("metadata error" )
430+ }
431+ return "" , false , nil
432+ }
433+ return m
434+ }(),
435+ client : & mockECSClient {},
436+ wantErr : true ,
437+ wantErrMsg : "failed to get canary target group ARN from metadata" ,
438+ },
439+ {
440+ name : "fail: ModifyListeners error" ,
441+ primary : primaryLB ,
442+ metadata : func () * mockMetadataStore {
443+ m := happyMetadataStore ()
444+ m .GetFunc = func (_ context.Context , key string ) (string , bool , error ) {
445+ switch key {
446+ case currentListenersKey :
447+ return listenerARN1 , true , nil
448+ case canaryTargetGroupArnKey :
449+ return canaryARN , true , nil
450+ }
451+ return "" , false , nil
452+ }
453+ return m
454+ }(),
455+ client : func () * mockECSClient {
456+ m := & mockECSClient {}
457+ m .ModifyListenersFunc = func (_ context.Context , _ []string , _ provider.RoutingTrafficConfig ) ([]string , error ) {
458+ return nil , errors .New ("modify listeners error" )
459+ }
460+ return m
461+ }(),
462+ wantErr : true ,
463+ wantErrMsg : "failed to restore ELB listener weights" ,
464+ },
465+ }
466+
467+ for _ , tc := range testcases {
468+ t .Run (tc .name , func (t * testing.T ) {
469+ t .Parallel ()
470+
471+ err := restoreELBWeights (context .Background (), & fakeLogPersister {}, tc .metadata , tc .client , tc .primary )
472+ if tc .wantErr {
473+ require .Error (t , err )
474+ assert .Contains (t , err .Error (), tc .wantErrMsg )
475+ return
476+ }
477+ require .NoError (t , err )
478+ })
479+ }
480+ }
0 commit comments