github.com/SaurabhDubey-Groww/go-cloud@v0.0.0-20221124105541-b26c29285fd8/runtimevar/awsparamstore/awsparamstore_test.go (about) 1 // Copyright 2018 The Go Cloud Development Kit Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package awsparamstore 16 17 import ( 18 "context" 19 "errors" 20 "os" 21 "testing" 22 23 ssmv2 "github.com/aws/aws-sdk-go-v2/service/ssm" 24 "github.com/aws/aws-sdk-go/aws" 25 "github.com/aws/aws-sdk-go/aws/awserr" 26 "github.com/aws/aws-sdk-go/aws/client" 27 "github.com/aws/aws-sdk-go/aws/session" 28 "github.com/aws/aws-sdk-go/service/ssm" 29 "github.com/aws/smithy-go" 30 "gocloud.dev/internal/testing/setup" 31 "gocloud.dev/runtimevar" 32 "gocloud.dev/runtimevar/driver" 33 "gocloud.dev/runtimevar/drivertest" 34 ) 35 36 // This constant records the region used for the last --record. 37 // If you want to use --record mode, 38 // 1. Update this constant to your AWS region. 39 // TODO(issue #300): Use Terraform to get this. 40 const region = "us-east-2" 41 42 type harness struct { 43 useV2 bool 44 session client.ConfigProvider 45 clientV2 *ssmv2.Client 46 closer func() 47 } 48 49 func newHarness(t *testing.T) (drivertest.Harness, error) { 50 sess, _, done, _ := setup.NewAWSSession(context.Background(), t, region) 51 return &harness{useV2: false, session: sess, closer: done}, nil 52 } 53 54 func newHarnessV2(t *testing.T) (drivertest.Harness, error) { 55 cfg, _, done, _ := setup.NewAWSv2Config(context.Background(), t, region) 56 return &harness{useV2: true, clientV2: ssmv2.NewFromConfig(cfg), closer: done}, nil 57 } 58 59 func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { 60 return newWatcher(h.useV2, h.session, h.clientV2, name, decoder, nil), nil 61 } 62 63 func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { 64 if h.useV2 { 65 _, err := h.clientV2.PutParameter(ctx, &ssmv2.PutParameterInput{ 66 Name: aws.String(name), 67 Type: "String", 68 Value: aws.String(string(val)), 69 Overwrite: true, 70 }) 71 return err 72 } 73 svc := ssm.New(h.session) 74 _, err := svc.PutParameter(&ssm.PutParameterInput{ 75 Name: aws.String(name), 76 Type: aws.String("String"), 77 Value: aws.String(string(val)), 78 Overwrite: aws.Bool(true), 79 }) 80 return err 81 } 82 83 func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { 84 return h.CreateVariable(ctx, name, val) 85 } 86 87 func (h *harness) DeleteVariable(ctx context.Context, name string) error { 88 if h.useV2 { 89 _, err := h.clientV2.DeleteParameter(ctx, &ssmv2.DeleteParameterInput{Name: aws.String(name)}) 90 return err 91 } 92 svc := ssm.New(h.session) 93 _, err := svc.DeleteParameter(&ssm.DeleteParameterInput{Name: aws.String(name)}) 94 return err 95 } 96 97 func (h *harness) Close() { 98 h.closer() 99 } 100 101 func (h *harness) Mutable() bool { return true } 102 103 func TestConformance(t *testing.T) { 104 drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{useV2: false}}) 105 } 106 107 func TestConformanceV2(t *testing.T) { 108 drivertest.RunConformanceTests(t, newHarnessV2, []drivertest.AsTest{verifyAs{useV2: true}}) 109 } 110 111 type verifyAs struct { 112 useV2 bool 113 } 114 115 func (verifyAs) Name() string { 116 return "verify As" 117 } 118 119 func (v verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { 120 if v.useV2 { 121 var getParam *ssmv2.GetParameterOutput 122 if !s.As(&getParam) { 123 return errors.New("Snapshot.As failed for GetParameterOutput") 124 } 125 return nil 126 } 127 var getParam *ssm.GetParameterOutput 128 if !s.As(&getParam) { 129 return errors.New("Snapshot.As failed for GetParameterOutput") 130 } 131 return nil 132 } 133 134 func (va verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { 135 if va.useV2 { 136 var e smithy.APIError 137 if !v.ErrorAs(err, &e) { 138 return errors.New("Keeper.ErrorAs failed") 139 } 140 return nil 141 } 142 var e awserr.Error 143 if !v.ErrorAs(err, &e) { 144 return errors.New("runtimevar.ErrorAs failed") 145 } 146 return nil 147 } 148 149 // Paramstore-specific tests. 150 151 func TestEquivalentError(t *testing.T) { 152 tests := []struct { 153 Err1, Err2 error 154 Want bool 155 }{ 156 {Err1: errors.New("not aws"), Err2: errors.New("not aws"), Want: true}, 157 {Err1: errors.New("not aws"), Err2: errors.New("not aws but different")}, 158 {Err1: errors.New("not aws"), Err2: awserr.New("code1", "fail", nil)}, 159 {Err1: awserr.New("code1", "fail", nil), Err2: awserr.New("code2", "fail", nil)}, 160 {Err1: awserr.New("code1", "fail", nil), Err2: awserr.New("code1", "fail", nil), Want: true}, 161 } 162 163 for _, test := range tests { 164 got := equivalentError(test.Err1, test.Err2) 165 if got != test.Want { 166 t.Errorf("%v vs %v: got %v want %v", test.Err1, test.Err2, got, test.Want) 167 } 168 } 169 } 170 171 func TestNoConnectionError(t *testing.T) { 172 prevAccessKey := os.Getenv("AWS_ACCESS_KEY") 173 prevSecretKey := os.Getenv("AWS_SECRET_KEY") 174 prevRegion := os.Getenv("AWS_REGION") 175 os.Setenv("AWS_ACCESS_KEY", "myaccesskey") 176 os.Setenv("AWS_SECRET_KEY", "mysecretkey") 177 os.Setenv("AWS_REGION", "us-east-1") 178 defer func() { 179 os.Setenv("AWS_ACCESS_KEY", prevAccessKey) 180 os.Setenv("AWS_SECRET_KEY", prevSecretKey) 181 os.Setenv("AWS_REGION", prevRegion) 182 }() 183 sess, err := session.NewSession() 184 if err != nil { 185 t.Fatal(err) 186 } 187 188 v, err := OpenVariable(sess, "variable-name", nil, nil) 189 if err != nil { 190 t.Fatal(err) 191 } 192 defer v.Close() 193 _, err = v.Watch(context.Background()) 194 if err == nil { 195 t.Error("got nil want error") 196 } 197 } 198 199 func TestOpenVariable(t *testing.T) { 200 tests := []struct { 201 URL string 202 WantErr bool 203 }{ 204 // OK. 205 {"awsparamstore://myvar", false}, 206 // OK, setting region. 207 {"awsparamstore://myvar?region=us-west-1", false}, 208 // OK, setting decoder. 209 {"awsparamstore://myvar?decoder=string", false}, 210 // Invalid decoder. 211 {"awsparamstore://myvar?decoder=notadecoder", true}, 212 // OK, setting wait. 213 {"awsparamstore://myvar?wait=2m", false}, 214 // Invalid wait. 215 {"awsparamstore://myvar?wait=x", true}, 216 // Invalid parameter. 217 {"awsparamstore://myvar?param=value", true}, 218 // OK, using SDK V2. 219 {"awsparamstore://myvar?decoder=string&awssdk=v2", false}, 220 } 221 222 ctx := context.Background() 223 for _, test := range tests { 224 v, err := runtimevar.OpenVariable(ctx, test.URL) 225 if (err != nil) != test.WantErr { 226 t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) 227 } 228 if err == nil { 229 v.Close() 230 } 231 } 232 }