Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ jobs:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v5

- uses: actions/setup-go@v3
- uses: actions/setup-go@v6
with:
go-version-file: .go-version

- name: golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v9
with:
version: latest
version: v2.9.0
verify: false
args: --config .golangci.yml --timeout 5m --verbose
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ jobs:
needs: [create_release_tag]
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v5
with:
fetch-depth: 0
ref: ${{ github.event.inputs.version }}

- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v6
with:
go-version-file: .go-version

Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: [1.18, 1.19, 1.19.2]
# go: [1.19, 1.22, 1.23, 1.24, 1.25]
go: [1.23, 1.24, 1.25]
name: Go ${{ matrix.go }} tests
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v5

- name: Setup go
uses: actions/setup-go@v3
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go }}

Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/internal/thing
/dist
.DS_Store
/coverage/
/coverage/
.claude
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.19
1.25.5
102 changes: 52 additions & 50 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
version: "2"

linters:
disable-all: true
default: none
enable:
- errcheck
- gofmt
- goimports
- gosec
- gosimple
- govet
- ineffassign
- misspell
- prealloc
- staticcheck
- typecheck
- unconvert
- unused
- asciicheck
Expand All @@ -21,51 +19,55 @@ linters:
- makezero
- nonamedreturns
- predeclared
settings:
depguard:
rules:
main:
deny:
- pkg: github.com/aws/aws-sdk-go/aws
desc: 'use v2 sdk instead'
gocritic:
disabled-checks:
- newDeref # it's wrong on generics
govet:
enable:
- shadow
exclusions:
rules:
- text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*\\.Exit|.*Flush|os\\.Remove(All)?|.*printf?|fmt\\.Fprintln|os\\.(Un)?Setenv|io\\.WriteString|io\\.Copy). is not checked"
linters:
- errcheck
- text: 'declaration of "err"'
linters:
- govet
# it's all fake
- text: "G101" # G101: potential hard coded creds
linters:
- gosec
# yea, it's a test proxy. we're way beyond security
- text: "G402" # TLS InsecureSkipVerify set true
linters:
- gosec
# it's used for a serial number
- text: "G404" # G404: Use of weak random number generator (math/rand instead of crypto/rand)
linters:
- gosec
- text: "QF1001"
linters:
- staticcheck
- text: "QF1003"
linters:
- staticcheck
paths:
- scripts

issues:
exclude:
- "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*\\.Exit|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv|io\\.WriteString|io\\.Copy). is not checked"
- 'declaration of "err"'
exclude-rules:

# it's all fake
- text: "G101" # G101: potential hard coded creds
linters:
- gosec

# yea, it's a test proxy. we're way beyond security
- text: "G402" # TLS InsecureSkipVerify set true
linters:
- gosec

# it's used for a serial number
- text: "G404" # G404: Use of weak random number generator (math/rand instead of crypto/rand)
linters:
- gosec

formatters:
enable:
- gofmt
- goimports

# output configuration options
output:
format: 'colored-line-number'
print-issued-lines: true
print-linter-name: true

linters-settings:
depguard:
list-type: denylist
packages:
- github.com/aws/aws-sdk-go/aws
packages-with-error-message:
- github.com/aws/aws-sdk-go/aws: 'use v2 sdk instead'

gocritic:
disabled-checks:
- newDeref # it's wrong on generics

govet:
check-shadowing: true
# enable-all: true

run:
skip-dirs:
- scripts
formats:
text:
print-issued-lines: true
print-linter-name: true
29 changes: 29 additions & 0 deletions .revive.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 0
warningCode = 0

[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.dot-imports]
[rule.empty-block]
[rule.error-naming]
[rule.error-return]
[rule.error-strings]
[rule.errorf]
# [rule.exported]
[rule.increment-decrement]
[rule.indent-error-flow]
[rule.package-comments]
[rule.range]
# [rule.receiver-naming]
[rule.redefines-builtin-id]
[rule.superfluous-else]
[rule.time-naming]
[rule.unexported-return]
[rule.unreachable-code]
[rule.unused-parameter]
[rule.var-declaration]
# [rule.var-naming]
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"go.testEnvVars": {
"AWSMOCKER_DEBUG": "1",
}
}
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
generate:
go generate ./...


.PHONY: tidy
tidy:
go mod verify
Expand All @@ -15,7 +14,7 @@ tidy:
.PHONY: lint-install
lint-install:
@echo "Installing golangci-lint"
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.46.2
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v2.9.0

.PHONY: lint
lint:
Expand All @@ -25,6 +24,10 @@ lint:
}
@golangci-lint run && echo "All Good!"

.PHONY: outdated
outdated:
@go list -u -m -f '{{if not .Indirect}}{{if .Update}}{{.}}{{end}}{{end}}' all

.PHONY: test-release
test-release:
goreleaser release --skip-publish --rm-dist --snapshot
Expand Down
50 changes: 22 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ Easily create a proxy to allow easy testing of AWS API calls.

**:warning: This is considered alpha quality right now. It might not work for all of AWS's APIs.**

> [!IMPORTANT]
> Version 1.0.0 has **BREAKING CHANGES**:
> * You must use the AWS config from `Config()` function returned by `Start()`.
> * The `Start` function has been modified to accept variable arguments for options setting

If you find problems, please create an Issue or make a PR.

## Installation
Expand All @@ -16,37 +21,25 @@ go get -u github.com/webdestroya/awsmocker
```

## Configuration
The default configuration when passing `nil` will setup a few mocks for STS.
The default configuration will setup a few mocks for STS.
```go
awsmocker.Start(t, nil)
m := awsmocker.Start(t)
```

For advanced usage and adding other mocks, you can use the following options:

```go
awsmocker.Start(t, &awsmocker.MockerOptions{
// parameters
})
m := awsmocker.Start(t, ...OPTIONS)
```

| Option Key | Type | Description |
| ----------- | ---- | ------ |
| `Mocks` | `[]*MockedEndpoint` | A list of MockedEndpoints that will be matched against all incoming requests. |
| `Timeout` | `time.Duration` | If provided, then requests that run longer than this will be terminated. Generally you should not need to set this |
| `MockEc2Metadata` | `bool` | Set this to `true` and mocks for common EC2 IMDS endpoints will be added. These are not exhaustive, so if you have a special need you will have to add it. |
| `SkipDefaultMocks` | `bool` | Setting this to true will prevent mocks for STS being added. Note: any mocks you add will be evaluated before the default mocks, so this option is generally not necessary. |
| `ReturnAwsConfig` | `bool` | For many applications, the test suite will have the ability to pass a custom `aws.Config` value. If you have the ability to do this, you can bypass setting all the HTTP_PROXY environment variables. This makes your test cleaner. Setting this to true will add the `AwsConfig` value to the returned value of the Start call. |
| `DoNotProxy` | `string` | Optional list of hostname globs that will be added to the `NO_PROXY` environment variable. These hostnames will bypass the mocker. Use this if you are making actual HTTP requests elsewhere in your code that you want to allow through. |
| `DoNotFailUnhandledRequests` | `bool` | By default, if the mocker receives any request that does not have a matching mock, it will fail the test. This is usually desired as it prevents requests without error checking from allowing tests to pass. If you explicitly want a request to fail, you can define that. |
| `DoNotOverrideCreds` | `bool` | This will stop the test mocker from overriding the AWS environment variables with fake values. This means if you do not properly configure the mocker, you could end up making real requests to AWS. This is not recommended. |

## Defining Mocks

```go
&awsmocker.MockedEndpoint{
Request: &awsmocker.MockedRequest{},
Response: &awsmocker.MockedResponse{},
}

```

### Mocking Requests
Expand Down Expand Up @@ -92,9 +85,7 @@ awsmocker.Start(t, &awsmocker.MockerOptions{

```go
func TestSomethingThatCallsAws(t *testing.T) {
awsmocker.Start(t, &awsmocker.MockerOptions{
// List out the mocks
Mocks: []*awsmocker.MockedEndpoint{
m := awsmocker.Start(t, awsmocker.WithMocks(
// Simple construction of a response
awsmocker.NewSimpleMockedEndpoint("sts", "GetCallerIdentity", sts.GetCallerIdentityOutput{
Account: aws.String("123456789012"),
Expand All @@ -103,29 +94,27 @@ func TestSomethingThatCallsAws(t *testing.T) {
}),

// advanced construction
{
&awsmocker.MockedEndpoint{
Request: &awsmocker.MockedRequest{
// specify the service/action to respond to
Service: "ecs",
Action: "DescribeServices",
},
// provide the response to give
Response: &awsmocker.MockedResponse{
Body: map[string]interface{}{
"services": []map[string]interface{}{
Body: map[string]any{
"services": []map[string]any{
{
"serviceName": "someservice",
},
},
},
},
},
},
})
),
)

cfg, _ := config.LoadDefaultConfig(context.TODO())

stsClient := sts.NewFromConfig(cfg)
stsClient := sts.NewFromConfig(m.Config())

resp, err := stsClient.GetCallerIdentity(context.TODO(), nil)
if err != nil {
Expand Down Expand Up @@ -154,7 +143,7 @@ func Mock_Events_PutRule_Generic() *awsmocker.MockedEndpoint {

name, _ := jmespath.Search("Name", rr.JsonPayload)

return util.Must(util.Jsonify(map[string]interface{}{
return util.Must(util.Jsonify(map[string]any{
"RuleArn": fmt.Sprintf("arn:aws:events:%s:%s:rule/%s", rr.Region, awsmocker.DefaultAccountId, name.(string)),
}))
},
Expand All @@ -177,5 +166,10 @@ To see the request/response traffic, you can use either of the following:
* if you provide a response object, it will be encoded to JSON or XML based on the requesting content type. If you need a response in a special format, please provide the content type and a string for the body.
* There is very little "error handling". If something goes wrong, it just panics. This might be less than ideal, but the only usecase for this library is within a test, which would make the test fail. This is the goal.

## Possible Issues

**Receiving error: "not found, ResolveEndpointV2"**:
Upgrade aws modules: `go get -u github.com/aws/aws-sdk-go-v2/...`

## See Also
* Heavily influenced by [hashicorp's servicemocks](github.com/hashicorp/aws-sdk-go-base/v2/servicemocks)
Loading