11package acctest
22
33import (
4+ "encoding/base64"
5+ "encoding/json"
6+ "encoding/xml"
7+ "net/http"
48 "os"
59 "strconv"
610 "strings"
@@ -9,11 +13,15 @@ import (
913
1014 "github.com/hashicorp/terraform-plugin-go/tfprotov6"
1115 "github.com/hashicorp/terraform-plugin-mux/tf6muxserver"
16+ "github.com/scaleway/scaleway-sdk-go/scw"
17+ "github.com/scaleway/scaleway-sdk-go/vcr"
1218 "github.com/scaleway/terraform-provider-scaleway/v2/internal/env"
1319 "github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
1420 "github.com/scaleway/terraform-provider-scaleway/v2/internal/transport"
1521 "github.com/scaleway/terraform-provider-scaleway/v2/provider"
1622 "github.com/stretchr/testify/require"
23+ "gopkg.in/dnaeon/go-vcr.v4/pkg/cassette"
24+ "gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
1725)
1826
1927func PreCheck (_ * testing.T ) {}
@@ -25,6 +33,75 @@ type TestTools struct {
2533 Cleanup func ()
2634}
2735
36+ var foldersUsingVCRv4 = []string {
37+ "instance" ,
38+ }
39+
40+ func folderUsesVCRv4 (fullFolderPath string ) bool {
41+ fullPathSplit := strings .Split (fullFolderPath , "/" )
42+
43+ folder := fullPathSplit [len (fullPathSplit )- 1 ]
44+ for _ , migratedFolder := range foldersUsingVCRv4 {
45+ if migratedFolder == folder {
46+ return true
47+ }
48+ }
49+
50+ return false
51+ }
52+
53+ // s3Encoder encodes binary payloads as base64 because serialization changed on go-vcr.v4
54+ func s3Encoder (i * cassette.Interaction ) error {
55+ if strings .HasSuffix (i .Request .Host , "scw.cloud" ) {
56+ if i .Request .Body != "" && i .Request .Headers .Get ("Content-Type" ) == "application/octet-stream" {
57+ requestBody := []byte (i .Request .Body )
58+ if ! json .Valid (requestBody ) {
59+ err := xml .Unmarshal (requestBody , new (any ))
60+ if err != nil {
61+ i .Request .Body = base64 .StdEncoding .EncodeToString (requestBody )
62+ }
63+ }
64+ }
65+
66+ if i .Response .Body != "" && i .Response .Headers .Get ("Content-Type" ) == "binary/octet-stream" {
67+ responseBody := []byte (i .Response .Body )
68+ if ! json .Valid (responseBody ) {
69+ err := xml .Unmarshal (responseBody , new (any ))
70+ if err != nil {
71+ i .Response .Body = base64 .StdEncoding .EncodeToString (responseBody )
72+ }
73+ }
74+ }
75+ }
76+
77+ return nil
78+ }
79+
80+ func NewRecordedClient (t * testing.T , pkgFolder string , update bool ) (client * http.Client , cleanup func (), err error ) {
81+ t .Helper ()
82+
83+ s3EncoderHook := vcr.AdditionalHook {
84+ HookFunc : s3Encoder ,
85+ Kind : recorder .AfterCaptureHook ,
86+ }
87+
88+ r , err := vcr .NewHTTPRecorder (t , pkgFolder , update , nil , s3EncoderHook )
89+ if err != nil {
90+ return nil , nil , err
91+ }
92+
93+ retryOptions := transport.RetryableTransportOptions {}
94+ if ! update {
95+ retryOptions .RetryWaitMax = scw .TimeDurationPtr (0 )
96+ }
97+
98+ return & http.Client {
99+ Transport : transport .NewRetryableTransportWithOptions (r , retryOptions ),
100+ }, func () {
101+ require .NoError (t , r .Stop ()) // Make sure recorder is stopped once done with it
102+ }, nil
103+ }
104+
28105func NewTestTools (t * testing.T ) * TestTools {
29106 t .Helper ()
30107
@@ -35,8 +112,18 @@ func NewTestTools(t *testing.T) *TestTools {
35112 t .Fatalf ("cannot detect working directory for testing" )
36113 }
37114
38- // Create a http client with recording capabilities
39- httpClient , cleanup , err := getHTTPRecoder (t , folder , * UpdateCassettes )
115+ // Create an HTTP client with recording capabilities
116+ var (
117+ httpClient * http.Client
118+ cleanup func ()
119+ )
120+
121+ if folderUsesVCRv4 (folder ) {
122+ httpClient , cleanup , err = NewRecordedClient (t , folder , * UpdateCassettes )
123+ } else {
124+ httpClient , cleanup , err = getHTTPRecoder (t , folder , * UpdateCassettes )
125+ }
126+
40127 require .NoError (t , err )
41128
42129 // Create meta that will be passed in the provider config
@@ -48,11 +135,11 @@ func NewTestTools(t *testing.T) *TestTools {
48135 require .NoError (t , err )
49136
50137 if ! * UpdateCassettes {
51- // If no recording is happening, the delay to retry to interactions should be 0
138+ // If no recording is happening, the delay to retry interactions should be 0
52139 tmp := 0 * time .Second
53140 transport .DefaultWaitRetryInterval = & tmp
54141 } else if os .Getenv (env .RetryDelay ) != "" {
55- // Overriding the delay interval is helpful to reduce the amount of requests performed while waiting for a ressource to be available
142+ // Overriding the delay interval is helpful to reduce the amount of requests performed while waiting for a resource to be available
56143 tmp , err := time .ParseDuration (os .Getenv (env .RetryDelay ))
57144 if err != nil {
58145 t .Fatal (err )
0 commit comments