Skip to content

Commit 593776e

Browse files
authored
chore: compress cassettes and test that cassettes are compressed (#3388)
* chore: compress cassettes and test that cassettes are compressed * go mod tidy * golangci-lint fix * fix lint * Fix tfproviderlint * Add other state to the compress list
1 parent 600a290 commit 593776e

File tree

119 files changed

+13096
-218754
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+13096
-218754
lines changed

cmd/vcr-compressor/main.go

Lines changed: 4 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,23 @@
11
package main
22

33
import (
4-
"encoding/json"
54
"log"
65
"os"
76

8-
"github.com/scaleway/scaleway-sdk-go/api/k8s/v1"
9-
"github.com/scaleway/scaleway-sdk-go/api/rdb/v1"
10-
"gopkg.in/dnaeon/go-vcr.v3/cassette"
7+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
118
)
129

13-
var transientStates = map[string]bool{
14-
k8s.ClusterStatusCreating.String(): true,
15-
k8s.ClusterStatusDeleting.String(): true,
16-
k8s.ClusterStatusUpdating.String(): true,
17-
k8s.PoolStatusDeleting.String(): true,
18-
k8s.PoolStatusScaling.String(): true,
19-
k8s.PoolStatusUpgrading.String(): true,
20-
21-
rdb.DatabaseBackupStatusCreating.String(): true,
22-
rdb.DatabaseBackupStatusDeleting.String(): true,
23-
rdb.DatabaseBackupStatusExporting.String(): true,
24-
rdb.DatabaseBackupStatusRestoring.String(): true,
25-
rdb.InstanceStatusAutohealing.String(): true,
26-
rdb.InstanceStatusBackuping.String(): true,
27-
rdb.InstanceStatusConfiguring.String(): true,
28-
rdb.InstanceStatusDeleting.String(): true,
29-
rdb.InstanceStatusInitializing.String(): true,
30-
rdb.InstanceStatusProvisioning.String(): true,
31-
rdb.InstanceStatusRestarting.String(): true,
32-
rdb.InstanceStatusSnapshotting.String(): true,
33-
}
34-
3510
func main() {
3611
if len(os.Args) < 2 {
3712
log.Fatalf("Usage: %s <cassette_file_name_without_yaml>\n", os.Args[0])
3813
}
3914

4015
path := os.Args[1]
4116

42-
inputCassette, err := cassette.Load(path)
17+
report, err := acctest.CompressCassette(path)
4318
if err != nil {
44-
log.Fatalf("Error while reading file : %v\n", err)
19+
log.Fatalf("%s", err)
4520
}
4621

47-
outputCassette := cassette.New(path)
48-
transitioning := false
49-
50-
for i := range len(inputCassette.Interactions) {
51-
interaction := inputCassette.Interactions[i]
52-
responseBody := interaction.Response.Body
53-
requestMethod := interaction.Request.Method
54-
55-
if requestMethod != "GET" {
56-
transitioning = false
57-
58-
log.Printf("Interaction %d is not a GET request. Recording it\n", i)
59-
outputCassette.AddInteraction(interaction)
60-
61-
continue
62-
}
63-
64-
if responseBody == "" {
65-
log.Printf("Interaction %d got an empty response body. Recording it\n", i)
66-
outputCassette.AddInteraction(interaction)
67-
68-
continue
69-
}
70-
71-
var m map[string]any
72-
73-
err := json.Unmarshal([]byte(responseBody), &m)
74-
if err != nil {
75-
log.Printf("Interaction %d have an error with unmarshalling response body: %v. Recording it\n", i, err)
76-
outputCassette.AddInteraction(interaction)
77-
78-
continue
79-
}
80-
81-
if m["status"] == nil {
82-
log.Printf("Interaction %d does not contain a status field. Recording it\n", i)
83-
outputCassette.AddInteraction(interaction)
84-
85-
continue
86-
}
87-
88-
status := m["status"].(string)
89-
// We test if the state is transient
90-
if _, ok := transientStates[status]; ok {
91-
if transitioning {
92-
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)
93-
} else {
94-
log.Printf("Interaction %d is in a transient state: %s, Recording it\n", i, status)
95-
96-
transitioning = true
97-
98-
outputCassette.AddInteraction(interaction)
99-
}
100-
} else {
101-
if transitioning {
102-
log.Printf("Interaction %d is not in a transient state anymore: %s, Recording it\n", i, status)
103-
104-
outputCassette.AddInteraction(interaction)
105-
106-
transitioning = false
107-
} else {
108-
log.Printf("Interaction %d is not in a transient state: %s, Recording it\n", i, status)
109-
outputCassette.AddInteraction(interaction)
110-
}
111-
}
112-
}
113-
114-
err = outputCassette.Save()
115-
if err != nil {
116-
log.Fatalf("error while saving file: %v", err)
117-
}
22+
report.Print()
11823
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require (
3232
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35
3333
github.com/stretchr/testify v1.11.1
3434
golang.org/x/crypto v0.42.0
35+
golang.org/x/sync v0.17.0
3536
gopkg.in/dnaeon/go-vcr.v3 v3.2.0
3637
)
3738

@@ -161,7 +162,6 @@ require (
161162
golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect
162163
golang.org/x/mod v0.28.0 // indirect
163164
golang.org/x/net v0.44.0 // indirect
164-
golang.org/x/sync v0.17.0 // indirect
165165
golang.org/x/sys v0.36.0 // indirect
166166
golang.org/x/term v0.35.0 // indirect
167167
golang.org/x/text v0.29.0 // indirect
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package acctest_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
7+
"github.com/stretchr/testify/require"
8+
"golang.org/x/sync/errgroup"
9+
)
10+
11+
func TestAccCassettes_Compressed(t *testing.T) {
12+
paths, err := getTestFiles(false)
13+
require.NoError(t, err)
14+
15+
var g errgroup.Group
16+
17+
for path := range paths {
18+
g.Go(func() error {
19+
report, errCompression := acctest.CompressCassette(path)
20+
require.NoError(t, errCompression)
21+
require.Zero(t, report.SkippedInteraction, "Issue with cassette: %s", report.Path)
22+
23+
return nil
24+
})
25+
}
26+
27+
if err := g.Wait(); err != nil {
28+
t.Errorf("error: %s", err)
29+
}
30+
}

internal/acctest/vcr_compress.go

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
package acctest
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"log"
7+
8+
applesilicon "github.com/scaleway/scaleway-sdk-go/api/applesilicon/v1alpha1"
9+
"github.com/scaleway/scaleway-sdk-go/api/baremetal/v1"
10+
block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
11+
container "github.com/scaleway/scaleway-sdk-go/api/container/v1beta1"
12+
domain "github.com/scaleway/scaleway-sdk-go/api/domain/v2beta1"
13+
file "github.com/scaleway/scaleway-sdk-go/api/file/v1alpha1"
14+
function "github.com/scaleway/scaleway-sdk-go/api/function/v1beta1"
15+
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
16+
"github.com/scaleway/scaleway-sdk-go/api/k8s/v1"
17+
"github.com/scaleway/scaleway-sdk-go/api/mongodb/v1"
18+
"github.com/scaleway/scaleway-sdk-go/api/rdb/v1"
19+
"github.com/scaleway/scaleway-sdk-go/api/redis/v1"
20+
tem "github.com/scaleway/scaleway-sdk-go/api/tem/v1alpha1"
21+
"gopkg.in/dnaeon/go-vcr.v3/cassette"
22+
)
23+
24+
var transientStates = map[string]bool{
25+
applesilicon.ServerStatusStarting.String(): true,
26+
applesilicon.ServerStatusRebooting.String(): true,
27+
applesilicon.ServerStatusReinstalling.String(): true,
28+
29+
baremetal.ServerStatusDeleting.String(): true,
30+
baremetal.ServerStatusStarting.String(): true,
31+
baremetal.ServerStatusDelivering.String(): true,
32+
baremetal.ServerStatusStarting.String(): true,
33+
baremetal.ServerStatusMigrating.String(): true,
34+
baremetal.ServerInstallStatusInstalling.String(): true,
35+
36+
block.VolumeStatusCreating.String(): true,
37+
block.VolumeStatusUpdating.String(): true,
38+
block.VolumeStatusDeleting.String(): true,
39+
block.VolumeStatusResizing.String(): true,
40+
block.VolumeStatusSnapshotting.String(): true,
41+
42+
container.ContainerStatusCreating.String(): true,
43+
container.ContainerStatusDeleting.String(): true,
44+
container.ContainerStatusPending.String(): true,
45+
46+
domain.DNSZoneStatusPending.String(): true,
47+
48+
file.FileSystemStatusCreating.String(): true,
49+
50+
function.FunctionStatusCreating.String(): true,
51+
function.FunctionStatusDeleting.String(): true,
52+
function.FunctionStatusPending.String(): true,
53+
54+
instance.ServerStateStarting.String(): true,
55+
instance.ServerStateStopping.String(): true,
56+
57+
k8s.ClusterStatusCreating.String(): true,
58+
k8s.ClusterStatusDeleting.String(): true,
59+
k8s.ClusterStatusUpdating.String(): true,
60+
k8s.PoolStatusDeleting.String(): true,
61+
k8s.PoolStatusScaling.String(): true,
62+
k8s.PoolStatusUpgrading.String(): true,
63+
64+
mongodb.InstanceStatusDeleting.String(): true,
65+
mongodb.InstanceStatusSnapshotting.String(): true,
66+
mongodb.InstanceStatusConfiguring.String(): true,
67+
mongodb.InstanceStatusInitializing.String(): true,
68+
mongodb.InstanceStatusProvisioning.String(): true,
69+
70+
rdb.DatabaseBackupStatusCreating.String(): true,
71+
rdb.DatabaseBackupStatusDeleting.String(): true,
72+
rdb.DatabaseBackupStatusExporting.String(): true,
73+
rdb.DatabaseBackupStatusRestoring.String(): true,
74+
rdb.InstanceStatusAutohealing.String(): true,
75+
rdb.InstanceStatusBackuping.String(): true,
76+
rdb.InstanceStatusConfiguring.String(): true,
77+
rdb.InstanceStatusDeleting.String(): true,
78+
rdb.InstanceStatusInitializing.String(): true,
79+
rdb.InstanceStatusProvisioning.String(): true,
80+
rdb.InstanceStatusRestarting.String(): true,
81+
rdb.InstanceStatusSnapshotting.String(): true,
82+
83+
redis.ClusterStatusAutohealing.String(): true,
84+
redis.ClusterStatusConfiguring.String(): true,
85+
redis.ClusterStatusProvisioning.String(): true,
86+
redis.ClusterStatusDeleting.String(): true,
87+
redis.ClusterStatusInitializing.String(): true,
88+
89+
tem.DomainStatusPending.String(): true,
90+
}
91+
92+
type CompressReport struct {
93+
Path string
94+
Logs []string
95+
ErrorLogs []string
96+
SkippedInteraction int
97+
}
98+
99+
func (report *CompressReport) AddLog(log string) {
100+
report.Logs = append(report.Logs, log)
101+
}
102+
103+
func (report *CompressReport) AddErrorLog(log string) {
104+
report.ErrorLogs = append(report.ErrorLogs, log)
105+
}
106+
107+
func (report *CompressReport) Print() {
108+
log.Printf("On cassette: %s\n", report.Path)
109+
log.Printf("%d skipped interactions\n", report.SkippedInteraction)
110+
111+
for _, msg := range report.ErrorLogs {
112+
log.Println(msg)
113+
}
114+
}
115+
116+
func CompressCassette(path string) (CompressReport, error) {
117+
inputCassette, err := cassette.Load(path)
118+
if err != nil {
119+
log.Fatalf("Error while reading file : %v\n", err)
120+
}
121+
122+
outputCassette := cassette.New(path)
123+
transitioning := false
124+
125+
report := CompressReport{
126+
SkippedInteraction: 0,
127+
Path: path,
128+
ErrorLogs: []string{},
129+
Logs: []string{},
130+
}
131+
132+
for i := range len(inputCassette.Interactions) {
133+
interaction := inputCassette.Interactions[i]
134+
responseBody := interaction.Response.Body
135+
requestMethod := interaction.Request.Method
136+
137+
if requestMethod != "GET" {
138+
transitioning = false
139+
140+
report.AddLog(fmt.Sprintf("Interaction %d in test %s is not a GET request. Recording it\n", i, path))
141+
outputCassette.AddInteraction(interaction)
142+
143+
continue
144+
}
145+
146+
if responseBody == "" {
147+
report.AddLog(fmt.Sprintf("Interaction %d in test %s got an empty response body. Recording it\n", i, path))
148+
outputCassette.AddInteraction(interaction)
149+
150+
continue
151+
}
152+
153+
var m map[string]any
154+
155+
err := json.Unmarshal([]byte(responseBody), &m)
156+
if err != nil {
157+
report.AddErrorLog(fmt.Sprintf("Interaction %d in test %s have an error with unmarshalling response body: %v. Recording it\n", i, path, err))
158+
outputCassette.AddInteraction(interaction)
159+
160+
continue
161+
}
162+
163+
if m["status"] == nil {
164+
report.AddLog(fmt.Sprintf("Interaction %d in test %s does not contain a status field. Recording it\n", i, path))
165+
outputCassette.AddInteraction(interaction)
166+
167+
continue
168+
}
169+
170+
status := m["status"].(string)
171+
// We test if the state is transient
172+
if _, ok := transientStates[status]; ok {
173+
if transitioning {
174+
report.AddLog(fmt.Sprintf("Interaction %d in test %s is in a transient state while we are already in transitient state. No need to record it: %s\n", i, path, status))
175+
report.SkippedInteraction++
176+
} else {
177+
report.AddLog(fmt.Sprintf("Interaction %d in test %s is in a transient state: %s, Recording it\n", i, path, status))
178+
179+
transitioning = true
180+
181+
outputCassette.AddInteraction(interaction)
182+
}
183+
} else {
184+
if transitioning {
185+
report.AddLog(fmt.Sprintf("Interaction %d in test %s is not in a transient state anymore: %s, Recording it\n", i, path, status))
186+
outputCassette.AddInteraction(interaction)
187+
188+
transitioning = false
189+
} else {
190+
report.AddLog(fmt.Sprintf("Interaction %d in test %s is not in a transient state: %s, Recording it\n", i, path, status))
191+
outputCassette.AddInteraction(interaction)
192+
}
193+
}
194+
}
195+
196+
err = outputCassette.Save()
197+
if err != nil {
198+
return report, fmt.Errorf("error while saving file: %w", err)
199+
}
200+
201+
return report, nil
202+
}

0 commit comments

Comments
 (0)