github.com/webdestroya/awsmocker@v0.2.6/mocker_test.go (about) 1 package awsmocker_test 2 3 import ( 4 "context" 5 "crypto/tls" 6 "fmt" 7 "net/http" 8 "testing" 9 10 "github.com/aws/aws-sdk-go-v2/aws" 11 "github.com/aws/aws-sdk-go-v2/config" 12 "github.com/aws/aws-sdk-go-v2/credentials" 13 "github.com/aws/aws-sdk-go-v2/service/ecs" 14 "github.com/aws/aws-sdk-go-v2/service/eventbridge" 15 "github.com/aws/aws-sdk-go-v2/service/sts" 16 "github.com/jmespath/go-jmespath" 17 "github.com/stretchr/testify/require" 18 "github.com/webdestroya/awsmocker" 19 "github.com/webdestroya/awsmocker/internal/testutil" 20 ) 21 22 func TestEcsDescribeServices(t *testing.T) { 23 awsmocker.Start(t, &awsmocker.MockerOptions{ 24 SkipDefaultMocks: true, 25 Mocks: []*awsmocker.MockedEndpoint{ 26 { 27 Request: &awsmocker.MockedRequest{ 28 Service: "ecs", 29 Action: "DescribeServices", 30 }, 31 Response: &awsmocker.MockedResponse{ 32 Body: map[string]interface{}{ 33 "services": []map[string]interface{}{ 34 { 35 "serviceName": "someservice", 36 }, 37 }, 38 }, 39 }, 40 }, 41 }, 42 }) 43 44 client := ecs.NewFromConfig(testutil.GetAwsConfig()) 45 46 resp, err := client.DescribeServices(context.TODO(), &ecs.DescribeServicesInput{ 47 Services: []string{"someservice"}, 48 Cluster: aws.String("testcluster"), 49 }) 50 require.NoError(t, err) 51 require.Equalf(t, "someservice", *resp.Services[0].ServiceName, "Service name was wrong") 52 } 53 54 func TestStsGetCallerIdentity_WithObj(t *testing.T) { 55 awsmocker.Start(t, &awsmocker.MockerOptions{ 56 SkipDefaultMocks: true, 57 Mocks: []*awsmocker.MockedEndpoint{ 58 { 59 Request: &awsmocker.MockedRequest{ 60 Service: "sts", 61 Action: "GetCallerIdentity", 62 }, 63 Response: &awsmocker.MockedResponse{ 64 Body: sts.GetCallerIdentityOutput{ 65 Account: aws.String(awsmocker.DefaultAccountId), 66 Arn: aws.String(fmt.Sprintf("arn:aws:iam::%s:user/fakeuser", awsmocker.DefaultAccountId)), 67 UserId: aws.String("AKIAI44QH8DHBEXAMPLE"), 68 }, 69 }, 70 }, 71 }, 72 }) 73 74 stsClient := sts.NewFromConfig(testutil.GetAwsConfig()) 75 76 resp, err := stsClient.GetCallerIdentity(context.TODO(), nil) 77 require.NoError(t, err) 78 require.Equalf(t, awsmocker.DefaultAccountId, *resp.Account, "AccountID Mismatch") 79 } 80 81 func TestStsGetCallerIdentity_WithMap(t *testing.T) { 82 awsmocker.Start(t, &awsmocker.MockerOptions{ 83 SkipDefaultMocks: true, 84 Mocks: []*awsmocker.MockedEndpoint{ 85 { 86 Request: &awsmocker.MockedRequest{ 87 Service: "sts", 88 Action: "GetCallerIdentity", 89 }, 90 Response: &awsmocker.MockedResponse{ 91 Body: map[string]interface{}{ 92 "Account": awsmocker.DefaultAccountId, 93 "Arn": fmt.Sprintf("arn:aws:iam::%s:user/fakeuser", awsmocker.DefaultAccountId), 94 "UserId": "AKIAI44QH8DHBEXAMPLE", 95 }, 96 }, 97 }, 98 }, 99 }) 100 stsClient := sts.NewFromConfig(testutil.GetAwsConfig()) 101 102 resp, err := stsClient.GetCallerIdentity(context.TODO(), nil) 103 require.NoError(t, err) 104 require.EqualValuesf(t, awsmocker.DefaultAccountId, *resp.Account, "account id mismatch") 105 } 106 107 func TestDynamicMocker(t *testing.T) { 108 awsmocker.Start(t, &awsmocker.MockerOptions{ 109 Mocks: []*awsmocker.MockedEndpoint{ 110 { 111 Request: &awsmocker.MockedRequest{ 112 Service: "events", 113 Action: "PutRule", 114 MaxMatchCount: 1, 115 }, 116 Response: &awsmocker.MockedResponse{ 117 Body: func(rr *awsmocker.ReceivedRequest) string { 118 name, _ := jmespath.Search("Name", rr.JsonPayload) 119 return awsmocker.EncodeAsJson(map[string]interface{}{ 120 "RuleArn": fmt.Sprintf("arn:aws:events:%s:%s:rule/%s", rr.Region, awsmocker.DefaultAccountId, name.(string)), 121 }) 122 }, 123 }, 124 }, 125 { 126 Request: &awsmocker.MockedRequest{ 127 Service: "events", 128 Action: "PutRule", 129 MaxMatchCount: 1, 130 }, 131 Response: &awsmocker.MockedResponse{ 132 Body: func(rr *awsmocker.ReceivedRequest) (string, int) { 133 name, _ := jmespath.Search("Name", rr.JsonPayload) 134 return awsmocker.EncodeAsJson(map[string]interface{}{ 135 "RuleArn": fmt.Sprintf("arn:aws:events:%s:%s:rule/x%s", rr.Region, awsmocker.DefaultAccountId, name.(string)), 136 }), 200 137 }, 138 }, 139 }, 140 { 141 Request: &awsmocker.MockedRequest{ 142 Service: "events", 143 Action: "PutRule", 144 MaxMatchCount: 1, 145 }, 146 Response: &awsmocker.MockedResponse{ 147 Body: func(rr *awsmocker.ReceivedRequest) (string, int, string) { 148 name, _ := jmespath.Search("Name", rr.JsonPayload) 149 return awsmocker.EncodeAsJson(map[string]interface{}{ 150 "RuleArn": fmt.Sprintf("arn:aws:events:%s:%s:rule/y%s", rr.Region, awsmocker.DefaultAccountId, name.(string)), 151 }), 200, awsmocker.ContentTypeJSON 152 }, 153 }, 154 }, 155 { 156 Request: &awsmocker.MockedRequest{ 157 Service: "events", 158 Action: "PutRule", 159 MaxMatchCount: 1, 160 }, 161 Response: &awsmocker.MockedResponse{ 162 Body: func(rr *awsmocker.ReceivedRequest) (string, int, string, string) { 163 name, _ := jmespath.Search("Name", rr.JsonPayload) 164 return awsmocker.EncodeAsJson(map[string]interface{}{ 165 "RuleArn": fmt.Sprintf("arn:aws:events:%s:%s:rule/y%s", rr.Region, awsmocker.DefaultAccountId, name.(string)), 166 }), 200, awsmocker.ContentTypeJSON, "wut" 167 }, 168 }, 169 }, 170 }, 171 }) 172 173 client := eventbridge.NewFromConfig(testutil.GetAwsConfig()) 174 175 tables := []struct { 176 name string 177 expectedArn string 178 errorContains interface{} 179 }{ 180 {"testrule", "arn:aws:events:us-east-1:555555555555:rule/testrule", nil}, 181 {"testrule", "arn:aws:events:us-east-1:555555555555:rule/xtestrule", nil}, 182 {"testrule", "arn:aws:events:us-east-1:555555555555:rule/ytestrule", nil}, 183 {"testrule", "arn:aws:events:us-east-1:555555555555:rule/ztestrule", "InvalidBodyFunc"}, 184 } 185 186 for _, table := range tables { 187 resp, err := client.PutRule(context.TODO(), &eventbridge.PutRuleInput{ 188 Name: aws.String(table.name), 189 }) 190 191 if table.errorContains == nil { 192 require.NoError(t, err) 193 require.Equal(t, table.expectedArn, *resp.RuleArn) 194 } else { 195 require.ErrorContains(t, err, table.errorContains.(string)) 196 } 197 } 198 } 199 200 func TestStartMockServerForTest(t *testing.T) { 201 // THIS PART REALLY TALKS TO AWS 202 precfg, err := config.LoadDefaultConfig(context.TODO(), 203 config.WithDefaultRegion("us-east-1"), 204 config.WithRetryer(func() aws.Retryer { 205 return aws.NopRetryer{} 206 }), 207 // MAKE SURE YOU USE BAD CREDS 208 config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider("AKID", "SECRET_KEY", "TOKEN")), 209 ) 210 require.NoError(t, err) 211 _, err = sts.NewFromConfig(precfg).GetCallerIdentity(context.TODO(), nil) 212 require.Error(t, err) 213 require.ErrorContains(t, err, "InvalidClientTokenId") 214 // END REALLY TALKING TO AWS 215 216 // start the test mocker server 217 awsmocker.Start(t, &awsmocker.MockerOptions{}) 218 219 stsClient := sts.NewFromConfig(testutil.GetAwsConfig()) 220 221 resp, err := stsClient.GetCallerIdentity(context.TODO(), nil) 222 require.NoError(t, err) 223 require.EqualValuesf(t, awsmocker.DefaultAccountId, *resp.Account, "account id mismatch") 224 } 225 226 func TestDefaultMocks(t *testing.T) { 227 awsmocker.Start(t, nil) 228 229 stsClient := sts.NewFromConfig(testutil.GetAwsConfig()) 230 231 resp, err := stsClient.GetCallerIdentity(context.TODO(), nil) 232 require.NoError(t, err) 233 require.EqualValuesf(t, awsmocker.DefaultAccountId, *resp.Account, "account id mismatch") 234 } 235 236 func TestBypass(t *testing.T) { 237 awsmocker.Start(t, &awsmocker.MockerOptions{ 238 DoNotProxy: "example.com", 239 }) 240 241 httpresp, err := http.Head("http://example.com/") 242 require.NoError(t, err) 243 require.Equal(t, http.StatusOK, httpresp.StatusCode) 244 245 stsClient := sts.NewFromConfig(testutil.GetAwsConfig()) 246 247 resp, err := stsClient.GetCallerIdentity(context.TODO(), nil) 248 require.NoError(t, err) 249 require.EqualValuesf(t, awsmocker.DefaultAccountId, *resp.Account, "account id mismatch") 250 251 } 252 253 func TestBypassReject(t *testing.T) { 254 awsmocker.Start(t, &awsmocker.MockerOptions{ 255 DoNotProxy: "example.com", 256 DoNotFailUnhandledRequests: true, 257 }) 258 259 client := &http.Client{ 260 Transport: &http.Transport{ 261 Proxy: http.ProxyFromEnvironment, 262 TLSClientConfig: &tls.Config{ 263 InsecureSkipVerify: true, 264 }, 265 }, 266 } 267 268 resp, err := client.Head("https://example.org/") 269 require.NoError(t, err) 270 require.Equal(t, "webdestroya", resp.TLS.PeerCertificates[0].Subject.Organization[0]) 271 require.Equal(t, http.StatusNotImplemented, resp.StatusCode) 272 // require.ErrorContains(t, err, "Not Implemented") 273 274 resp = nil 275 276 resp, err = http.Get("http://example.org/") 277 require.NoError(t, err) 278 defer resp.Body.Close() 279 require.Equal(t, http.StatusNotImplemented, resp.StatusCode) 280 } 281 282 func TestSendingRegularRequestToProxy(t *testing.T) { 283 info := awsmocker.Start(t, nil) 284 285 resp, err := http.Get(info.ProxyURL + "/testing") 286 require.NoError(t, err) 287 defer resp.Body.Close() 288 require.Equal(t, http.StatusNotImplemented, resp.StatusCode) 289 }