Repository navigation
start tune-up of the project #189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a2a11ab
6e11f75
6dc4282
3964a75
67918a7
651f2c4
4b99d36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| name: Test & Build | ||
|
|
||
| on: | ||
| pull_request: | ||
| push: | ||
| branches: | ||
| - main | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| go: [ '1.27' ] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| - name: Set up Go | ||
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | ||
| with: | ||
| go-version: ${{ matrix.go }} | ||
| - name: Run unit tests | ||
| run: go test -race ./... | ||
| - name: Run static checks | ||
| run: go vet ./... | ||
| - name: Run acceptance tests | ||
| run: make acceptance | ||
| - name: Check for vulnerabilities | ||
| run: | | ||
| go run golang.org/x/vuln/cmd/govulncheck@v1.9.0 ./... | ||
| go run golang.org/x/vuln/cmd/govulncheck@v1.9.0 -tags=acceptance ./... | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,13 +10,13 @@ jobs: | |
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Set up Go | ||
| uses: actions/setup-go@v5 | ||
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | ||
| with: | ||
| go-version: '1.21' | ||
| go-version: '1.27' | ||
| - name: Run GoReleaser | ||
| uses: goreleaser/goreleaser-action@v4 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice to see the actions being pinned to SHAs here. It could be worth pinning the ones this PR does not touch as well, for consistency: Not a blocker for this PR, it can be a follow-up.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My idea is improve all related with the release on other PR that will depends from this one, that will be ok for you? |
||
| if: startsWith(github.ref, 'refs/tags/') | ||
|
|
@@ -32,7 +32,7 @@ jobs: | |
| name: Deploy to DockerHub | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
|
|
||
| - name: Set up QEMU | ||
| uses: docker/setup-qemu-action@v3 | ||
|
|
@@ -61,4 +61,4 @@ jobs: | |
| context: . | ||
| platforms: linux/amd64,linux/arm64 | ||
| push: true | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Repository Guidelines | ||
|
|
||
| ## Project Structure & Module Organization | ||
|
|
||
| Killgrave is a Go HTTP mock server. `cmd/killgrave/main.go` is the executable entry point; `internal/app/` wires the application together, and `internal/app/cmd/` defines the Cobra CLI. Configuration and file watching live in `internal/`; HTTP routing, imposters, proxying, and response handling live in `internal/server/http/`. | ||
|
|
||
| Unit tests sit beside source files as `*_test.go`. Fixtures live in `internal/test/testdata/` and `internal/server/http/test/testdata/`. Process-level acceptance tests and `.txtar` fixtures live in `acceptance/`. Consult `README.md` for configuration and imposter examples. | ||
|
|
||
| ## Build, Test, and Development Commands | ||
|
|
||
| Use Go 1.27, matching `go.mod` and CI. | ||
|
|
||
| - `make build`: produce `bin/killgrave` with branch and commit version metadata. | ||
| - `./bin/killgrave --imposters ./internal/server/http/test/testdata/imposters`: run locally with existing fixtures on localhost:3000. | ||
| - `go test ./...`: run the default unit test suite. | ||
| - `go test -v -vet=off -race ./...`: reproduce the CI unit test command with race detection. | ||
| - `make acceptance`: build the executable, then run acceptance tests with the `acceptance` build tag. | ||
| - `gofmt -w path/to/changed.go`: format changed Go files; use `go vet ./...` for static checks. | ||
|
|
||
| ## Coding Style & Naming Conventions | ||
|
|
||
| Follow existing Go conventions: use `gofmt` formatting and tab indentation, short lowercase package names, exported `CamelCase` identifiers, and unexported `camelCase` identifiers. Keep related behavior in the existing packages. Group standard-library, external, and repository imports consistently with nearby code. Name imposter fixtures with `.imp.json`, `.imp.yml`, or `.imp.yaml` extensions. | ||
|
|
||
| ## Testing Guidelines | ||
|
|
||
| Use Go's `testing` package with Testify assertions. Name tests `Test<Behavior>` and use descriptive table-driven subtests for input variations. Add regression coverage for behavior changes, including error cases. Each acceptance scenario is one `acceptance/tests/<scenario>.txtar` archive containing setup files, optional `scenario.json`, and named `http/<step>/req.http` and `res.http` entries. See `acceptance/README.md` for the format. Run unit and acceptance suites before submitting. No numeric coverage threshold is configured. | ||
|
|
||
| ## Commit & Pull Request Guidelines | ||
|
|
||
| Recent commits use concise action-oriented subjects, such as `Fix imposters search` and `Replace spf13/afero with io/fs`; merged subjects often include a PR number. Follow that style. | ||
|
|
||
| Follow `CONTRIBUTING.md`: ask to take an issue, confirm its milestone, and base work on the milestone branch. PR descriptions should explain the change, link the issue, and list validation performed. For bugs, include reproduction steps, expected versus actual behavior, and relevant configuration or imposters. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # Acceptance tests | ||
|
|
||
| Run `make acceptance` from the repository root. It builds Killgrave and runs each | ||
| `tests/<scenario>.txtar` against a separate process with an isolated working | ||
| directory and port. No external services are needed. | ||
|
|
||
| Keep each scenario in one archive containing its setup and named HTTP steps: | ||
|
|
||
| ```text | ||
| -- imposters/routes.imp.json -- | ||
| [{"request":{"method":"GET","endpoint":"/example"},"response":{"status":200,"headers":{"Content-Type":"text/plain"},"body":"example\n"}}] | ||
| -- http/matched/req.http -- | ||
| GET /example HTTP/1.1 | ||
|
|
||
| -- http/matched/res.http -- | ||
| HTTP/1.1 200 OK | ||
| Content-Length: 8 | ||
| Content-Type: text/plain | ||
|
|
||
|
|
||
| example | ||
| ``` | ||
|
|
||
| Each `http/<step>/` group is a named subtest containing `req.http` and `res.http`. | ||
| Steps run in archive order, so response sequences are visible together without | ||
| numbering separate files. Scenarios run concurrently. Expected responses include | ||
| all headers except `Date`; redirects are checked directly. | ||
|
|
||
| All entries outside `http/`, except `scenario.json`, are extracted as setup files. | ||
| By default Killgrave uses the extracted `imposters` directory and an allocated | ||
| port. An optional `scenario.json` entry can replace startup arguments: | ||
|
|
||
| ```text | ||
| -- scenario.json -- | ||
| {"args":["--config","settings/config.yml"]} | ||
| -- settings/config.yml -- | ||
| host: localhost | ||
| port: ${PORT} | ||
| imposters_path: imposters | ||
| ``` | ||
|
|
||
| Arguments and setup files support `${PORT}` and `${UPSTREAM}` substitution. | ||
| Arguments run directly without a shell. Config-file imposter paths resolve | ||
| relative to the config file; `config_precedence.txtar` records precedence over | ||
| host, port, and imposter flags. | ||
|
|
||
| Optional `scenario.json` settings: | ||
|
|
||
| | Setting | Meaning | | ||
| | --- | --- | | ||
| | `args` | Replace the default startup arguments. | | ||
| | `error` | Require an unsuccessful exit and this diagnostic substring. No HTTP steps are needed. | | ||
| | `occupyPort` | Hold the allocated port open to exercise bind failure. | | ||
| | `upstreamCalls` | Start a local upstream and assert this exact request count, including zero. | | ||
| | `upstreamDown` | Close that upstream before startup to exercise a connection failure. | | ||
| | `https` | Send fixture requests over HTTPS. Startup arguments or configuration must also enable secure mode. | | ||
|
|
||
| The upstream returns status 202, `X-Upstream: yes`, and a body echoing the method, | ||
| request URI, `X-Test` header, and body. TCP readiness does not call the upstream | ||
| or advance response sequences. | ||
|
|
||
| Watcher steps can include `http/<step>/write/<relative-path>` entries to atomically | ||
| create or replace files before the request. An `http/<step>/eventually` entry | ||
| containing `true` retries the response check for up to five seconds. Writes happen | ||
| once. Use retries only for stateless GET requests without bodies; sequence tests | ||
| must check every response without retries. See `watcher_flag.txtar` for an example. | ||
|
|
||
| Delay steps may include `http/<step>/timing.json`, for example | ||
| `{"min":"180ms","max":"2s"}`. The harness measures the complete response, with a | ||
| lower bound to detect missing delays and a generous upper allowance for CI load. | ||
| Fixed and ranged delays are covered in both JSON and YAML. Timing checks cannot | ||
| use retries. | ||
|
|
||
| HTTPS clients accept Killgrave's bundled dummy certificate only within the test | ||
| transport. HTTPS proxy fixtures still connect to Killgrave before reaching the | ||
| local upstream; the unit suite separately checks a trusted local TLS upstream. | ||
|
|
||
| `TestGracefulShutdown` is a Go table test for SIGINT and SIGTERM. It uses channels | ||
| to hold an upstream request open, checks that new connections are refused during | ||
| shutdown, then releases the response and verifies clean exit. This coordination | ||
| stays in Go rather than adding concurrency commands to the archive format. | ||
|
|
||
| HTTP requests time out after three seconds; readiness and startup-error commands | ||
| have five-second limits. Cleanup allows three seconds for an interrupt before | ||
| killing and reaping the process, and verifies that the listening port can be bound | ||
| again. Failed scenarios include server logs. |
Uh oh!
There was an error while loading. Please reload this page.