Skip to content

Commit

Permalink
Pre-Request manipulations (#131)
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre Fenoll <[email protected]>
  • Loading branch information
fenollp authored Nov 9, 2024
1 parent 2c74cea commit cd0cf87
Show file tree
Hide file tree
Showing 34 changed files with 1,528 additions and 890 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,9 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: actions/[email protected]
with:
go-version: '>=1.17.0'
- run: go install github.com/incu6us/goimports-reviser/[email protected]
- run: go install github.com/incu6us/goimports-reviser/[email protected]
- run: which goimports-reviser
- run: find . -type f -iname '*.go' ! -iname '*.pb.go' -exec goimports-reviser -file-path {} \;
- run: find . -type f -iname '*.go' ! -iname '*.pb.go' -exec goimports-reviser {} \;
- run: git --no-pager diff --exit-code

check-nillness:
Expand Down
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# syntax=docker.io/docker/dockerfile:1@sha256:9ba7531bd80fb0a858632727cf7a112fbfd19b17e94c4e84ced81e24ef1a0dbc
# syntax=docker.io/docker/dockerfile:1@sha256:865e5dd094beca432e8c0a1d5e1c465db5f998dca4e439981029b3b81fb39ed5

# Use --build-arg PREBUILT=1 with default target to fetch binaries from GitHub releases
ARG PREBUILT

# Fetched 2022/04/04
FROM --platform=$BUILDPLATFORM docker.io/library/alpine@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a AS alpine
FROM --platform=$BUILDPLATFORM docker.io/library/alpine@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d AS alpine
FROM --platform=$BUILDPLATFORM docker.io/nilslice/protolock@sha256:baf9bca8b7a28b945c557f36d562a34cf7ca85a63f6ba8cdadbe333e12ccea51 AS protolock
FROM --platform=$BUILDPLATFORM docker.io/library/golang@sha256:5f5d61dcb58900bc57b230431b6367c900f9982b583adcabf9fa93fd0aa5544a AS golang
FROM --platform=$BUILDPLATFORM docker.io/goreleaser/goreleaser@sha256:e8a4e0a0c9ccd1fcf456e5258b743bb63a3c68f50e03ae4fdfad7681761713e6 AS goreleaser
FROM --platform=$BUILDPLATFORM docker.io/library/golang@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 AS golang
FROM --platform=$BUILDPLATFORM docker.io/goreleaser/goreleaser@sha256:1f5ae36e41ede8b994a93c66e5c1fb1b1111de2ce88f25b6378e341771ed963e AS goreleaser
# On this image:
# go env GOCACHE => /root/.cache/go-build
# go env GOMODCACHE => /go/pkg/mod
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
.PHONY: all update debug lint test ape

SHELL = /bin/bash -o pipefail -eu

EXE ?= monkey

all: pkg/internal/fm/fuzzymonkey.pb.go make_README.sh README.md lint
CGO_ENABLED=0 go build -o $(EXE) $(if $(wildcard $(EXE)),|| (rm $(EXE) && false))
cat .gitignore >.dockerignore && echo /.git >>.dockerignore
./$(EXE) fmt -w && ./make_README.sh

update: SHELL := /bin/bash
update:
go get -u -a -v ./...
go mod tidy
Expand All @@ -19,8 +20,8 @@ latest:
$(bindir)/$(EXE) --version

devdeps:
go install -i github.com/wadey/gocovmerge
go install -i github.com/kyoh86/richgo
go install github.com/wadey/gocovmerge@latest
go install github.com/kyoh86/richgo@latest

pkg/internal/fm/fuzzymonkey.pb.go: pkg/internal/fm/fuzzymonkey.proto
docker buildx bake ci-check--protolock ci-check--protoc #ci-check--protolock-force
Expand All @@ -34,7 +35,7 @@ lint:

debug: all
./$(EXE) lint
./$(EXE) fuzz --exclude-tags=failing #--progress=bar
./$(EXE) fuzz --exclude-tags=failing --progress=ci #dots #=ci #=bar

distclean: clean
$(if $(wildcard dist/),rm -r dist/)
Expand All @@ -44,7 +45,6 @@ clean:
$(if $(wildcard *.cov),rm *.cov)
$(if $(wildcard cov.out),rm cov.out)

test: SHELL = /bin/bash -o pipefail
test: all
echo 42 | ./$(EXE) schema --validate-against=#/components/schemas/PostId
! ./$(EXE) exec repl <<<'assert that("malformed" != 42)'
Expand Down
43 changes: 39 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![asciicast](https://asciinema.org/a/171571.png)](https://asciinema.org/a/171571?autoplay=1)

```
monkey M.m.p go1.18.3 linux amd64
monkey M.m.p go1.23.2 linux amd64
Usage:
monkey [-vvv] env [VAR ...]
Expand Down Expand Up @@ -114,7 +114,6 @@ monkey.openapi3(
# Note: references to schemas in `file` are resolved relative to file's location.
file = SPEC,
host = "https://jsonplaceholder.typicode.com",
# header_authorization = "Bearer {}".format(monkey.env("DEV_API_TOKEN")),
)

# Note: exec commands are executed in shells sharing the same environment variables,
Expand All @@ -135,28 +134,64 @@ monkey.shell(
reset = """
echo ${BLA:-42}
BLA=$(( ${BLA:-42} + 1 ))
echo Resetting state...
echo Resetting System Under Test...
""",
)

## Add headers to some of the requests

MY_HEADER = "X-Special"

def add_special_headers(ctx):
"""Shows how to modify an HTTP request before it is sent"""

req = ctx.request
if type(req) != "http_request":
print("`ctx.request` isn't an HTTP request! It's a {}", type(req))
return

assert that(MY_HEADER.title()).is_equal_to(MY_HEADER)
assert that(dict(req.headers)).does_not_contain_key(MY_HEADER)
req.headers.add(MY_HEADER, "value!")
print("Added an extra header:", MY_HEADER)

# Let's also set a bearer token:
token = monkey.env("DEV_API_TOKEN", "dev token is unset!")
req.headers.set("authorization".title(), "Bearer " + token)

monkey.check(
name = "adds_special_headers",
before_request = add_special_headers,
tags = ["special_headers"],
)

monkey.check(
name = "checks_special_headers",
after_response = lambda ctx: assert that(dict(ctx.request.headers)).contains_key(MY_HEADER),
tags = ["special_headers"],
)

## Ensure some general property

def ensure_lowish_response_time(ms):
def responds_in_a_timely_manner(ctx):
assert that(ctx.response).is_of_type("http_response")
assert that(ctx.response.elapsed_ms).is_at_most(ms)

return responds_in_a_timely_manner

monkey.check(
name = "responds_in_a_timely_manner",
after_response = ensure_lowish_response_time(500),
after_response = ensure_lowish_response_time(1000),
tags = ["timings"],
)

## Express stateful properties

def stateful_model_of_posts(ctx):
"""Properties on posts. State collects posts returned by API."""
if type(ctx.request) != "http_request":
return

# NOTE: response has already been decoded & validated for us.

Expand Down
2 changes: 1 addition & 1 deletion Tagfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.49.0
0.50.0
41 changes: 38 additions & 3 deletions fuzzymonkey.star
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ monkey.openapi3(
# Note: references to schemas in `file` are resolved relative to file's location.
file = SPEC,
host = "https://jsonplaceholder.typicode.com",
# header_authorization = "Bearer {}".format(monkey.env("DEV_API_TOKEN")),
)

# Note: exec commands are executed in shells sharing the same environment variables,
Expand All @@ -30,28 +29,64 @@ monkey.shell(
reset = """
echo ${BLA:-42}
BLA=$(( ${BLA:-42} + 1 ))
echo Resetting state...
echo Resetting System Under Test...
""",
)

## Add headers to some of the requests

MY_HEADER = "X-Special"

def add_special_headers(ctx):
"""Shows how to modify an HTTP request before it is sent"""

req = ctx.request
if type(req) != "http_request":
print("`ctx.request` isn't an HTTP request! It's a {}", type(req))
return

assert that(MY_HEADER.title()).is_equal_to(MY_HEADER)
assert that(dict(req.headers)).does_not_contain_key(MY_HEADER)
req.headers.add(MY_HEADER, "value!")
print("Added an extra header:", MY_HEADER)

# Let's also set a bearer token:
token = monkey.env("DEV_API_TOKEN", "dev token is unset!")
req.headers.set("authorization".title(), "Bearer " + token)

monkey.check(
name = "adds_special_headers",
before_request = add_special_headers,
tags = ["special_headers"],
)

monkey.check(
name = "checks_special_headers",
after_response = lambda ctx: assert that(dict(ctx.request.headers)).contains_key(MY_HEADER),
tags = ["special_headers"],
)

## Ensure some general property

def ensure_lowish_response_time(ms):
def responds_in_a_timely_manner(ctx):
assert that(ctx.response).is_of_type("http_response")
assert that(ctx.response.elapsed_ms).is_at_most(ms)

return responds_in_a_timely_manner

monkey.check(
name = "responds_in_a_timely_manner",
after_response = ensure_lowish_response_time(500),
after_response = ensure_lowish_response_time(1000),
tags = ["timings"],
)

## Express stateful properties

def stateful_model_of_posts(ctx):
"""Properties on posts. State collects posts returned by API."""
if type(ctx.request) != "http_request":
return

# NOTE: response has already been decoded & validated for us.

Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ module github.com/FuzzyMonkeyCo/monkey

go 1.21

toolchain go1.23.2

require (
github.com/alecthomas/chroma/v2 v2.14.0
github.com/bazelbuild/buildtools v0.0.0-20240918101019-be1c24cc9a44
Expand Down
Loading

0 comments on commit cd0cf87

Please sign in to comment.