-
Notifications
You must be signed in to change notification settings - Fork 120
/
acctest.go
152 lines (131 loc) · 4.33 KB
/
acctest.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package acctest
import (
"context"
"strconv"
"strings"
"testing"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/transport"
"github.com/scaleway/terraform-provider-scaleway/v2/scaleway"
"github.com/stretchr/testify/require"
)
func PreCheck(_ *testing.T) {}
type TestTools struct {
T *testing.T
Meta *meta.Meta
ProviderFactories map[string]func() (*schema.Provider, error)
Cleanup func()
}
func NewTestTools(t *testing.T) *TestTools {
t.Helper()
ctx := context.Background()
// Create a http client with recording capabilities
httpClient, cleanup, err := getHTTPRecoder(t, *UpdateCassettes)
require.NoError(t, err)
// Create meta that will be passed in the provider config
m, err := meta.NewMeta(ctx, &meta.Config{
ProviderSchema: nil,
TerraformVersion: "terraform-tests",
HTTPClient: httpClient,
})
require.NoError(t, err)
if !*UpdateCassettes {
tmp := 0 * time.Second
transport.DefaultWaitRetryInterval = &tmp
}
return &TestTools{
T: t,
Meta: m,
ProviderFactories: map[string]func() (*schema.Provider, error){
"scaleway": func() (*schema.Provider, error) {
return scaleway.Provider(&scaleway.ProviderConfig{Meta: m})(), nil
},
},
Cleanup: cleanup,
}
}
// Test Generated name has format: "{prefix}-{generated_number}
// example: test-acc-scaleway-project-3723338038624371236
func extractTestGeneratedNamePrefix(name string) string {
// {prefix}-{generated}
// ^
dashIndex := strings.LastIndex(name, "-")
generated := name[dashIndex+1:]
_, generatedToIntErr := strconv.ParseInt(generated, 10, 64)
if dashIndex == -1 || generatedToIntErr != nil {
// some are only {name}
return name
}
// {prefix}
return name[:dashIndex]
}
// Generated names have format: "tf-{prefix}-{generated1}-{generated2}"
// example: tf-sg-gifted-yonath
func extractGeneratedNamePrefix(name string) string {
if strings.Count(name, "-") < 3 {
return name
}
// tf-{prefix}-gifted-yonath
name = strings.TrimPrefix(name, "tf-")
// {prefix}-gifted-yonath
// ^
dashIndex := strings.LastIndex(name, "-")
name = name[:dashIndex]
// {prefix}-gifted
// ^
dashIndex = strings.LastIndex(name, "-")
name = name[:dashIndex]
return name
}
// compareJSONFieldsStrings compare two strings from request JSON bodies
// has special case when string are terraform generated names
func compareJSONFieldsStrings(expected, actual string) bool {
expectedHandled := expected
actualHandled := actual
// Remove s3 url suffix to allow comparison
if strings.HasSuffix(actual, ".s3-website.fr-par.scw.cloud") {
actual = strings.TrimSuffix(actual, ".s3-website.fr-par.scw.cloud")
expected = strings.TrimSuffix(expected, ".s3-website.fr-par.scw.cloud")
}
// Try to parse test generated name
if strings.Contains(actual, "-") {
expectedHandled = extractTestGeneratedNamePrefix(expected)
actualHandled = extractTestGeneratedNamePrefix(actual)
}
// Try provider generated name
if actualHandled == actual && strings.HasPrefix(actual, "tf-") {
expectedHandled = extractGeneratedNamePrefix(expected)
actualHandled = extractGeneratedNamePrefix(actual)
}
return expectedHandled == actualHandled
}
// compareJSONBodies compare two given maps that represent json bodies
// returns true if both json are equivalent
func compareJSONBodies(expected, actual map[string]interface{}) bool {
// Check for each key in actual requests
// Compare its value to cassette content if marshal-able to string
for key := range actual {
expectedValue, exists := expected[key]
if !exists {
// Actual request may contain a field that does not exist in cassette
// New fields can appear in requests with new api features
// We do not want to generate new cassettes for each new features
continue
}
if !compareJSONFields(expectedValue, actual[key]) {
return false
}
}
for key := range expected {
_, exists := actual[key]
if !exists && expected[key] != nil {
// Fails match if cassettes contains a field not in actual requests
// Fields should not disappear from requests unless a sdk breaking change
// We ignore if field is nil in cassette as it could be an old deprecated and unused field
return false
}
}
return true
}