Skip to content

Commit 13e1fd9

Browse files
authored
chore: add support for vcr compression and trim k8s cassettes (#3136)
* chore: add support for vcr compression and trim k8s cassettes * Fix * Fix linter * Fix i18n for error message * Apply review suggestions * Apply review suggestions * Fix lint * add documentation * Fix useless continue
1 parent 555a269 commit 13e1fd9

16 files changed

+7767
-102776
lines changed

TESTING.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,16 @@ Running a single test:
6262
```sh
6363
TF_UPDATE_CASSETTES=true TF_LOG=DEBUG SCW_DEBUG=1 TF_ACC=1 go test ./scaleway -v -run=TestAccScalewayDataSourceRDBInstance_Basic -timeout=120m -parallel=10
6464
```
65+
66+
## Compressing the cassettes
67+
68+
We record interactions with the Scaleway API in cassettes, which are stored in the `testdata` directory of each service.
69+
Each wait function used in the resources will perform several requests to the API for pulling a resource state, which can lead to large cassettes.
70+
We use a compressor to reduce the size of these cassettes once they are recorded.
71+
By doing so, tests can run faster and the cassettes are easier to read.
72+
73+
To use the compressor on a given cassette, run the following command:
74+
75+
```sh
76+
go run -v ./cmd/vcr-compressor internal/services/rdb/testdata/acl-basic.cassette
77+
```

cmd/vcr-compressor/main.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"log"
6+
"os"
7+
8+
"github.com/scaleway/scaleway-sdk-go/api/k8s/v1"
9+
"gopkg.in/dnaeon/go-vcr.v3/cassette"
10+
)
11+
12+
var transientStates = map[string]bool{
13+
k8s.ClusterStatusCreating.String(): true,
14+
k8s.ClusterStatusDeleting.String(): true,
15+
k8s.ClusterStatusUpdating.String(): true,
16+
k8s.PoolStatusDeleting.String(): true,
17+
k8s.PoolStatusScaling.String(): true,
18+
k8s.PoolStatusUpgrading.String(): true,
19+
}
20+
21+
func main() {
22+
if len(os.Args) < 2 {
23+
log.Fatalf("Usage: %s <cassette_file_name_without_yaml>\n", os.Args[0])
24+
}
25+
26+
path := os.Args[1]
27+
28+
inputCassette, err := cassette.Load(path)
29+
if err != nil {
30+
log.Fatalf("Error while reading file : %v\n", err)
31+
}
32+
33+
outputCassette := cassette.New(path)
34+
transitioning := false
35+
36+
for i := range len(inputCassette.Interactions) {
37+
interaction := inputCassette.Interactions[i]
38+
responseBody := interaction.Response.Body
39+
requestMethod := interaction.Request.Method
40+
41+
if requestMethod != "GET" {
42+
transitioning = false
43+
44+
log.Printf("Interaction %d is not a GET request. Recording it\n", i)
45+
outputCassette.AddInteraction(interaction)
46+
47+
continue
48+
}
49+
50+
if responseBody == "" {
51+
log.Printf("Interaction %d got an empty response body. Recording it\n", i)
52+
outputCassette.AddInteraction(interaction)
53+
54+
continue
55+
}
56+
57+
var m map[string]interface{}
58+
59+
err := json.Unmarshal([]byte(responseBody), &m)
60+
if err != nil {
61+
log.Printf("Interaction %d have an error with unmarshalling response body: %v. Recording it\n", i, err)
62+
outputCassette.AddInteraction(interaction)
63+
64+
continue
65+
}
66+
67+
if m["status"] == nil {
68+
log.Printf("Interaction %d does not contain a status field. Recording it\n", i)
69+
outputCassette.AddInteraction(interaction)
70+
71+
continue
72+
}
73+
74+
status := m["status"].(string)
75+
// We test if the state is transient
76+
if _, ok := transientStates[status]; ok {
77+
if transitioning {
78+
log.Printf("Interaction %d is in a transient state while we are already in transitient state. No need to record it: %s\n", i, status)
79+
} else {
80+
log.Printf("Interaction %d is in a transient state: %s, Recording it\n", i, status)
81+
82+
transitioning = true
83+
84+
outputCassette.AddInteraction(interaction)
85+
}
86+
} else {
87+
if transitioning {
88+
log.Printf("Interaction %d is not in a transient state anymore: %s, Recording it\n", i, status)
89+
90+
outputCassette.AddInteraction(interaction)
91+
92+
transitioning = false
93+
} else {
94+
log.Printf("Interaction %d is not in a transient state: %s, Recording it\n", i, status)
95+
outputCassette.AddInteraction(interaction)
96+
}
97+
}
98+
}
99+
100+
err = outputCassette.Save()
101+
if err != nil {
102+
log.Fatalf("error while saving file: %v", err)
103+
}
104+
}

cmd/vcr-viewer/main.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"log"
6+
"os"
7+
8+
"gopkg.in/dnaeon/go-vcr.v3/cassette"
9+
)
10+
11+
func main() {
12+
if len(os.Args) < 2 {
13+
log.Fatalf("Usage: %s <cassette_file_name_without_yaml>\n", os.Args[0])
14+
}
15+
16+
path := os.Args[1]
17+
18+
data, err := cassette.Load(path)
19+
if err != nil {
20+
log.Fatalf("Error while reading file: %v\n", err)
21+
}
22+
23+
for i := range len(data.Interactions) {
24+
interaction := data.Interactions[i]
25+
26+
log.Println("--------------")
27+
log.Printf("Interaction %d:\n", i+1)
28+
log.Printf(" Request:\n")
29+
log.Printf(" Method: %s\n", interaction.Request.Method)
30+
log.Printf(" URL: %s\n", interaction.Request.URL)
31+
32+
if interaction.Request.Body != "" {
33+
log.Printf(" Body: %s\n", interaction.Request.Body)
34+
}
35+
36+
log.Printf(" Response:\n")
37+
log.Printf(" Status: %s\n", interaction.Response.Status)
38+
log.Printf(" Body: %s\n", interaction.Response.Body)
39+
40+
var m map[string]interface{}
41+
42+
err := json.Unmarshal([]byte(interaction.Response.Body), &m)
43+
if err != nil {
44+
continue
45+
}
46+
47+
if m["status"] != nil {
48+
log.Println("++++++++++++++++")
49+
log.Printf("status: %s\n", m["status"])
50+
log.Println("++++++++++++++++")
51+
}
52+
53+
log.Println("--------------")
54+
}
55+
}

internal/services/k8s/testdata/cluster-multicloud.cassette.yaml

Lines changed: 165 additions & 6633 deletions
Large diffs are not rendered by default.

internal/services/k8s/testdata/cluster-pool-private-network.cassette.yaml

Lines changed: 2013 additions & 3506 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)