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,77 @@ 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+ return nil
57+ }
58+
59+ if i .Request .Body != "" && i .Request .Headers .Get ("Content-Type" ) == "application/octet-stream" {
60+ requestBody := []byte (i .Request .Body )
61+ if ! json .Valid (requestBody ) {
62+ err := xml .Unmarshal (requestBody , new (any ))
63+ if err != nil {
64+ i .Request .Body = base64 .StdEncoding .EncodeToString (requestBody )
65+ }
66+ }
67+ }
68+
69+ if i .Response .Body != "" && i .Response .Headers .Get ("Content-Type" ) == "binary/octet-stream" {
70+ responseBody := []byte (i .Response .Body )
71+ if ! json .Valid (responseBody ) {
72+ err := xml .Unmarshal (responseBody , new (any ))
73+ if err != nil {
74+ i .Response .Body = base64 .StdEncoding .EncodeToString (responseBody )
75+ }
76+ }
77+ }
78+
79+ return nil
80+ }
81+
82+ func NewRecordedClient (t * testing.T , pkgFolder string , update bool ) (client * http.Client , cleanup func (), err error ) {
83+ t .Helper ()
84+
85+ s3EncoderHook := vcr.AdditionalHook {
86+ HookFunc : s3Encoder ,
87+ Kind : recorder .AfterCaptureHook ,
88+ }
89+
90+ r , err := vcr .NewHTTPRecorder (t , pkgFolder , update , nil , s3EncoderHook )
91+ if err != nil {
92+ return nil , nil , err
93+ }
94+
95+ retryOptions := transport.RetryableTransportOptions {}
96+ if ! update {
97+ retryOptions .RetryWaitMax = scw .TimeDurationPtr (0 )
98+ }
99+
100+ return & http.Client {
101+ Transport : transport .NewRetryableTransportWithOptions (r , retryOptions ),
102+ }, func () {
103+ require .NoError (t , r .Stop ()) // Make sure recorder is stopped once done with it
104+ }, nil
105+ }
106+
28107func NewTestTools (t * testing.T ) * TestTools {
29108 t .Helper ()
30109
@@ -35,8 +114,18 @@ func NewTestTools(t *testing.T) *TestTools {
35114 t .Fatalf ("cannot detect working directory for testing" )
36115 }
37116
38- // Create a http client with recording capabilities
39- httpClient , cleanup , err := getHTTPRecoder (t , folder , * UpdateCassettes )
117+ // Create an HTTP client with recording capabilities
118+ var (
119+ httpClient * http.Client
120+ cleanup func ()
121+ )
122+
123+ if folderUsesVCRv4 (folder ) {
124+ httpClient , cleanup , err = NewRecordedClient (t , folder , * UpdateCassettes )
125+ } else {
126+ httpClient , cleanup , err = getHTTPRecoder (t , folder , * UpdateCassettes )
127+ }
128+
40129 require .NoError (t , err )
41130
42131 // Create meta that will be passed in the provider config
@@ -48,11 +137,11 @@ func NewTestTools(t *testing.T) *TestTools {
48137 require .NoError (t , err )
49138
50139 if ! * UpdateCassettes {
51- // If no recording is happening, the delay to retry to interactions should be 0
140+ // If no recording is happening, the delay to retry interactions should be 0
52141 tmp := 0 * time .Second
53142 transport .DefaultWaitRetryInterval = & tmp
54143 } 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
144+ // Overriding the delay interval is helpful to reduce the amount of requests performed while waiting for a resource to be available
56145 tmp , err := time .ParseDuration (os .Getenv (env .RetryDelay ))
57146 if err != nil {
58147 t .Fatal (err )
0 commit comments