Skip to content

Commit da53199

Browse files
committed
bring in gdt-1.8.0
Also improves the debug logging and simplifies the Eval() method substantially. Signed-off-by: Jay Pipes <[email protected]>
1 parent efdb1a1 commit da53199

File tree

10 files changed

+174
-223
lines changed

10 files changed

+174
-223
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ test-kind-simple:
4242
test-all: test kind-clear-clusters
4343
@go test -v ./fixtures/kind/kind_test.go
4444
@go test -v ./placement_test.go
45+
46+
test-placement: clear-test-cache kind-clear-clusters
47+
@go test -v ./placement_test.go

README.md

+80-116
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,27 @@ All `gdt` test specs have the same [base fields][base-spec-fields]:
112112
* `description`: (optional) string with longer description of the test unit.
113113
* `timeout`: (optional) an object containing [timeout information][timeout] for the test
114114
unit.
115-
* `timeout.after`: a string duration of time the test unit is expected to
115+
* `timeout`: (optional) a string duration of time the test unit is expected to
116116
complete within.
117-
* `timeout.expected`: a bool indicating that the test unit is expected to not
118-
complete before `timeout.after`. This is really only useful in unit testing.
117+
* `retry`: (optional) an object containing retry configurationu for the test
118+
unit. Some plugins will automatically attempt to retry the test action when
119+
an assertion fails. This field allows you to control this retry behaviour for
120+
each individual test.
121+
* `retry.interval`: (optional) a string duration of time that the test plugin
122+
will retry the test action in the event assertions fail. The default interval
123+
for retries is plugin-dependent.
124+
* `retry.attempts`: (optional) an integer indicating the number of times that a
125+
plugin will retry the test action in the event assertions fail. The default
126+
number of attempts for retries is plugin-dependent.
127+
* `retry.exponential`: (optional) a boolean indicating an exponential backoff
128+
should be applied to the retry interval. The default is is plugin-dependent.
119129
* `wait` (optional) an object containing [wait information][wait] for the test
120130
unit.
121131
* `wait.before`: a string duration of time that gdt should wait before
122132
executing the test unit's action.
123133
* `wait.after`: a string duration of time that gdt should wait after executing
124134
the test unit's action.
125135

126-
[timeout]: https://github.com/gdt-dev/gdt/blob/2791e11105fd3c36d1f11a7d111e089be7cdc84c/types/timeout.go#L11-L22
127136
[wait]: https://github.com/gdt-dev/gdt/blob/2791e11105fd3c36d1f11a7d111e089be7cdc84c/types/wait.go#L11-L25
128137

129138
`gdt-kube` test specs have some additional fields that allow you to take some
@@ -711,108 +720,6 @@ tests:
711720
delete: deployments/nginx
712721
```
713722

714-
### Timeouts and retrying `kube.get` assertions
715-
716-
When evaluating assertions for `kube.get`, `gdt` inspects the test's
717-
`timeout.after` value to determine how long to retry the `get` call and recheck
718-
the assertions.
719-
720-
If a test's `timeout.after` is empty, `gdt` inspects the scenario's
721-
`defaults.timeout.after` value. If both of those values are empty, `gdt` will
722-
use a **default timeout of 5 seconds**.
723-
724-
If you're interested in seeing the individual results of `gdt`'s
725-
assertion-checks for a single `get` call, you can use the `gdt.WithDebug()`
726-
function, like this test function demonstrates:
727-
728-
file: `testdata/matches.yaml`:
729-
730-
```yaml
731-
name: matches
732-
description: create a deployment and check the matches condition succeeds
733-
fixtures:
734-
- kind
735-
tests:
736-
- name: create-deployment
737-
kube:
738-
create: testdata/manifests/nginx-deployment.yaml
739-
- name: deployment-exists
740-
kube:
741-
get: deployments/nginx
742-
assert:
743-
matches:
744-
spec:
745-
replicas: 2
746-
template:
747-
metadata:
748-
labels:
749-
app: nginx
750-
status:
751-
readyReplicas: 2
752-
- name: delete-deployment
753-
kube:
754-
delete: deployments/nginx
755-
```
756-
757-
file: `matches_test.go`
758-
759-
```go
760-
import (
761-
"github.com/gdt-dev/gdt"
762-
_ "github.com/gdt-dev/kube"
763-
kindfix "github.com/gdt-dev/kube/fixture/kind"
764-
)
765-
766-
func TestMatches(t *testing.T) {
767-
fp := filepath.Join("testdata", "matches.yaml")
768-
769-
kfix := kindfix.New()
770-
771-
s, err := gdt.From(fp)
772-
773-
ctx := gdt.NewContext(gdt.WithDebug())
774-
ctx = gdt.RegisterFixture(ctx, "kind", kfix)
775-
s.Run(ctx, t)
776-
}
777-
```
778-
779-
Here's what running `go test -v matches_test.go` would look like:
780-
781-
```
782-
$ go test -v matches_test.go
783-
=== RUN TestMatches
784-
=== RUN TestMatches/matches
785-
=== RUN TestMatches/matches/create-deployment
786-
=== RUN TestMatches/matches/deployment-exists
787-
deployment-exists (try 1 after 1.303µs) ok: false, terminal: false
788-
deployment-exists (try 1 after 1.303µs) failure: assertion failed: match field not equal: $.status.readyReplicas not present in subject
789-
deployment-exists (try 2 after 595.62786ms) ok: false, terminal: false
790-
deployment-exists (try 2 after 595.62786ms) failure: assertion failed: match field not equal: $.status.readyReplicas not present in subject
791-
deployment-exists (try 3 after 1.020003807s) ok: false, terminal: false
792-
deployment-exists (try 3 after 1.020003807s) failure: assertion failed: match field not equal: $.status.readyReplicas not present in subject
793-
deployment-exists (try 4 after 1.760006109s) ok: false, terminal: false
794-
deployment-exists (try 4 after 1.760006109s) failure: assertion failed: match field not equal: $.status.readyReplicas had different values. expected 2 but found 1
795-
deployment-exists (try 5 after 2.772416449s) ok: true, terminal: false
796-
=== RUN TestMatches/matches/delete-deployment
797-
--- PASS: TestMatches (3.32s)
798-
--- PASS: TestMatches/matches (3.30s)
799-
--- PASS: TestMatches/matches/create-deployment (0.01s)
800-
--- PASS: TestMatches/matches/deployment-exists (2.78s)
801-
--- PASS: TestMatches/matches/delete-deployment (0.02s)
802-
PASS
803-
ok command-line-arguments 3.683s
804-
```
805-
806-
You can see from the debug output above that `gdt` created the Deployment and
807-
then did a `kube.get` for the `deployments/nginx` Deployment. Initially
808-
(attempt 1), the `assert.matches` assertion failed because the
809-
`status.readyReplicas` field was not present in the returned resource. `gdt`
810-
retried the `kube.get` call 4 more times (attempts 2-5), with attempts 2 and 3
811-
failed the existence check for the `status.readyReplicas` field and attempt 4
812-
failing the *value* check for the `status.readyReplicas` field being `1`
813-
instead of the expected `2`. Finally, when the Deployment was completely rolled
814-
out, attempt 5 succeeded in all the `assert.matches` assertions.
815-
816723
## Determining Kubernetes config, context and namespace values
817724

818725
When evaluating how to construct a Kubernetes client `gdt-kube` uses the following
@@ -881,12 +788,78 @@ tests:
881788
- kube.get: pods/nginx
882789
```
883790

791+
#### Retaining and deleting KinD clusters
792+
793+
The default behaviour of the `KindFixture` is to delete the KinD cluster when
794+
the Fixture's `Stop()` method is called, but **only if the KinD cluster did not
795+
previously exist before the Fixture's `Start()` method was called**.
796+
797+
If you want to *always* ensure that a KinD cluster is deleted when the
798+
`KindFixture` is stopped, use the `fixtures.kind.WithDeleteOnStop()` function:
799+
800+
```go
801+
import (
802+
"github.com/gdt-dev/gdt"
803+
gdtkube "github.com/gdt-dev/kube"
804+
gdtkind "github.com/gdt-dev/kube/fixtures/kind"
805+
)
806+
807+
func TestExample(t *testing.T) {
808+
s, err := gdt.From("path/to/test.yaml")
809+
if err != nil {
810+
t.Fatalf("failed to load tests: %s", err)
811+
}
812+
813+
ctx := context.Background()
814+
ctx = gdt.RegisterFixture(
815+
ctx, "kind", gdtkind.New(),
816+
gdtkind.WithDeleteOnStop(),
817+
)
818+
err = s.Run(ctx, t)
819+
if err != nil {
820+
t.Fatalf("failed to run tests: %s", err)
821+
}
822+
}
823+
```
824+
825+
Likewise, the default behaviour of the `KindFixture` is to retain the KinD
826+
cluster when the Fixture's `Stop()` method is called but **only if the KinD
827+
cluster previously existed before the Fixture's `Start()` method was called**.
828+
829+
If you want to *always* ensure a KinD cluster is retained, even if the
830+
KindFixture created the KinD cluster, use the
831+
`fixtures.kind.WithRetainOnStop()` function:
832+
833+
```go
834+
import (
835+
"github.com/gdt-dev/gdt"
836+
gdtkube "github.com/gdt-dev/kube"
837+
gdtkind "github.com/gdt-dev/kube/fixtures/kind"
838+
)
839+
840+
func TestExample(t *testing.T) {
841+
s, err := gdt.From("path/to/test.yaml")
842+
if err != nil {
843+
t.Fatalf("failed to load tests: %s", err)
844+
}
845+
846+
ctx := context.Background()
847+
ctx = gdt.RegisterFixture(
848+
ctx, "kind", gdtkind.New(),
849+
gdtkind.WithRetainOnStop(),
850+
)
851+
err = s.Run(ctx, t)
852+
if err != nil {
853+
t.Fatalf("failed to run tests: %s", err)
854+
}
855+
}
856+
```
857+
884858
#### Passing a KinD configuration
885859

886860
You may want to pass a custom KinD configuration resource by using the
887861
`fixtures.kind.WithConfigPath()` modifier:
888862

889-
890863
```go
891864
import (
892865
"github.com/gdt-dev/gdt"
@@ -914,15 +887,6 @@ func TestExample(t *testing.T) {
914887
}
915888
```
916889

917-
In your test file, you would list the "kind" fixture in the `fixtures` list:
918-
919-
```yaml
920-
name: example-using-kind
921-
fixtures:
922-
- kind
923-
tests:
924-
- kube.get: pods/nginx
925-
```
926890
## Contributing and acknowledgements
927891

928892
`gdt` was inspired by [Gabbi](https://github.com/cdent/gabbi), the excellent

0 commit comments

Comments
 (0)