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  }