Skip to content

Commit f0e5896

Browse files
VCR body comparison fixes (#3461) (#2047)
* Remove body comparison during VCR matching if content type is multipart * Fix other tests for vcr-style * Fix ssl cert test, IDP tests for VCR * Add json comparison * Sorts! Deterministic ordering of IAM bindings and compute metadata for VCR testing * Introduce sort to stringSliceFromGolangSet * Sort string list after set conversion * Tabs v spaces Signed-off-by: Modular Magician <[email protected]>
1 parent 3c02e54 commit f0e5896

20 files changed

+115
-65
lines changed

.changelog/3461.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:none
2+
3+
```

google-beta/config.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,12 @@ type Config struct {
7070
// It controls the interval at which we poll for successful operations
7171
PollInterval time.Duration
7272

73-
client *http.Client
74-
wrappedPubsubClient *http.Client
75-
context context.Context
76-
terraformVersion string
77-
userAgent string
73+
client *http.Client
74+
wrappedBigQueryClient *http.Client
75+
wrappedPubsubClient *http.Client
76+
context context.Context
77+
terraformVersion string
78+
userAgent string
7879

7980
tokenSource oauth2.TokenSource
8081

@@ -524,6 +525,7 @@ func (c *Config) LoadAndValidate(ctx context.Context) error {
524525
bigQueryClientBasePath := c.BigQueryBasePath
525526
log.Printf("[INFO] Instantiating Google Cloud BigQuery client for path %s", bigQueryClientBasePath)
526527
wrappedBigQueryClient := ClientWithAdditionalRetries(client, retryTransport, iamMemberMissing)
528+
c.wrappedBigQueryClient = wrappedBigQueryClient
527529
c.clientBigQuery, err = bigquery.NewService(ctx, option.WithHTTPClient(wrappedBigQueryClient))
528530
if err != nil {
529531
return err

google-beta/iam.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"log"
88
"reflect"
9+
"sort"
910
"strings"
1011
"time"
1112

@@ -265,7 +266,17 @@ func createIamBindingsMap(bindings []*cloudresourcemanager.Binding) map[iamBindi
265266
// Return list of Bindings for a map of role to member sets
266267
func listFromIamBindingMap(bm map[iamBindingKey]map[string]struct{}) []*cloudresourcemanager.Binding {
267268
rb := make([]*cloudresourcemanager.Binding, 0, len(bm))
268-
for key, members := range bm {
269+
var keys []iamBindingKey
270+
for k := range bm {
271+
keys = append(keys, k)
272+
}
273+
sort.Slice(keys, func(i, j int) bool {
274+
keyI := keys[i]
275+
keyJ := keys[j]
276+
return fmt.Sprintf("%s%s", keyI.Role, keyI.Condition.String()) < fmt.Sprintf("%s%s", keyJ.Role, keyJ.Condition.String())
277+
})
278+
for _, key := range keys {
279+
members := bm[key]
269280
if len(members) == 0 {
270281
continue
271282
}

google-beta/metadata.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"log"
7+
"sort"
78

89
computeBeta "google.golang.org/api/compute/v0.beta"
910
"google.golang.org/api/compute/v1"
@@ -144,10 +145,15 @@ func resourceInstanceMetadata(d TerraformResourceData) (*computeBeta.Metadata, e
144145
}
145146
if len(mdMap) > 0 {
146147
m.Items = make([]*computeBeta.MetadataItems, 0, len(mdMap))
147-
for key, val := range mdMap {
148-
v := val.(string)
148+
var keys []string
149+
for k := range mdMap {
150+
keys = append(keys, k)
151+
}
152+
sort.Strings(keys)
153+
for _, k := range keys {
154+
v := mdMap[k].(string)
149155
m.Items = append(m.Items, &computeBeta.MetadataItems{
150-
Key: key,
156+
Key: k,
151157
Value: &v,
152158
})
153159
}

google-beta/provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
895895
"google_dns_record_set": resourceDnsRecordSet(),
896896
"google_endpoints_service": resourceEndpointsService(),
897897
"google_folder": resourceGoogleFolder(),
898-
"google_folder_iam_binding": ResourceIamBinding(IamFolderSchema, NewFolderIamUpdater, FolderIdParseFunc),
898+
"google_folder_iam_binding": ResourceIamBindingWithBatching(IamFolderSchema, NewFolderIamUpdater, FolderIdParseFunc, IamBatchingEnabled),
899899
"google_folder_iam_member": ResourceIamMember(IamFolderSchema, NewFolderIamUpdater, FolderIdParseFunc),
900900
"google_folder_iam_policy": ResourceIamPolicy(IamFolderSchema, NewFolderIamUpdater, FolderIdParseFunc),
901901
"google_folder_organization_policy": resourceGoogleFolderOrganizationPolicy(),

google-beta/provider_test.go

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package google
22

33
import (
44
"bytes"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"io/ioutil"
@@ -10,6 +11,7 @@ import (
1011
"net/http"
1112
"os"
1213
"path/filepath"
14+
"reflect"
1315
"regexp"
1416
"strconv"
1517
"strings"
@@ -143,21 +145,48 @@ func getCachedConfig(d *schema.ResourceData, configureFunc func(d *schema.Resour
143145
// Defines how VCR will match requests to responses.
144146
rec.SetMatcher(func(r *http.Request, i cassette.Request) bool {
145147
// Default matcher compares method and URL only
146-
defaultMatch := cassette.DefaultMatcher(r, i)
148+
if !cassette.DefaultMatcher(r, i) {
149+
return false
150+
}
147151
if r.Body == nil {
148-
return defaultMatch
152+
return true
149153
}
154+
contentType := r.Header.Get("Content-Type")
155+
// If body contains media, don't try to compare
156+
if strings.Contains(contentType, "multipart/related") {
157+
return true
158+
}
159+
150160
var b bytes.Buffer
151161
if _, err := b.ReadFrom(r.Body); err != nil {
152162
log.Printf("[DEBUG] Failed to read request body from cassette: %v", err)
153163
return false
154164
}
155165
r.Body = ioutil.NopCloser(&b)
156-
// body must match recorded body
157-
return defaultMatch && b.String() == i.Body
166+
reqBody := b.String()
167+
// If body matches identically, we are done
168+
if reqBody == i.Body {
169+
return true
170+
}
171+
172+
// JSON might be the same, but reordered. Try parsing json and comparing
173+
if strings.Contains(contentType, "application/json") {
174+
var reqJson, cassetteJson interface{}
175+
if err := json.Unmarshal([]byte(reqBody), &reqJson); err != nil {
176+
log.Printf("[DEBUG] Failed to unmarshall request json: %v", err)
177+
return false
178+
}
179+
if err := json.Unmarshal([]byte(i.Body), &cassetteJson); err != nil {
180+
log.Printf("[DEBUG] Failed to unmarshall cassette json: %v", err)
181+
return false
182+
}
183+
return reflect.DeepEqual(reqJson, cassetteJson)
184+
}
185+
return false
158186
})
159187
config.client.Transport = rec
160188
config.wrappedPubsubClient.Transport = rec
189+
config.wrappedBigQueryClient.Transport = rec
161190
configs[testName] = config
162191
return config, err
163192
}

google-beta/resource_google_folder_iam_binding_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestAccFolderIamBinding_basic(t *testing.T) {
2626
{
2727
Config: testAccFolderIamBasic(org, fname),
2828
Check: resource.ComposeTestCheckFunc(
29-
testAccFolderExistingPolicy(org, fname),
29+
testAccFolderExistingPolicy(t, org, fname),
3030
),
3131
},
3232
// Apply an IAM binding
@@ -57,7 +57,7 @@ func TestAccFolderIamBinding_multiple(t *testing.T) {
5757
{
5858
Config: testAccFolderIamBasic(org, fname),
5959
Check: resource.ComposeTestCheckFunc(
60-
testAccFolderExistingPolicy(org, fname),
60+
testAccFolderExistingPolicy(t, org, fname),
6161
),
6262
},
6363
// Apply an IAM binding
@@ -102,7 +102,7 @@ func TestAccFolderIamBinding_multipleAtOnce(t *testing.T) {
102102
{
103103
Config: testAccFolderIamBasic(org, fname),
104104
Check: resource.ComposeTestCheckFunc(
105-
testAccFolderExistingPolicy(org, fname),
105+
testAccFolderExistingPolicy(t, org, fname),
106106
),
107107
},
108108
// Apply an IAM binding
@@ -137,7 +137,7 @@ func TestAccFolderIamBinding_update(t *testing.T) {
137137
{
138138
Config: testAccFolderIamBasic(org, fname),
139139
Check: resource.ComposeTestCheckFunc(
140-
testAccFolderExistingPolicy(org, fname),
140+
testAccFolderExistingPolicy(t, org, fname),
141141
),
142142
},
143143
// Apply an IAM binding
@@ -188,7 +188,7 @@ func TestAccFolderIamBinding_remove(t *testing.T) {
188188
{
189189
Config: testAccFolderIamBasic(org, fname),
190190
Check: resource.ComposeTestCheckFunc(
191-
testAccFolderExistingPolicy(org, fname),
191+
testAccFolderExistingPolicy(t, org, fname),
192192
),
193193
},
194194
// Apply multiple IAM bindings
@@ -209,7 +209,7 @@ func TestAccFolderIamBinding_remove(t *testing.T) {
209209
{
210210
Config: testAccFolderIamBasic(org, fname),
211211
Check: resource.ComposeTestCheckFunc(
212-
testAccFolderExistingPolicy(org, fname),
212+
testAccFolderExistingPolicy(t, org, fname),
213213
),
214214
},
215215
},

google-beta/resource_google_folder_iam_member_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func TestAccFolderIamMember_basic(t *testing.T) {
2222
{
2323
Config: testAccFolderIamBasic(org, fname),
2424
Check: resource.ComposeTestCheckFunc(
25-
testAccFolderExistingPolicy(org, fname),
25+
testAccFolderExistingPolicy(t, org, fname),
2626
),
2727
},
2828
// Apply an IAM binding
@@ -53,7 +53,7 @@ func TestAccFolderIamMember_multiple(t *testing.T) {
5353
{
5454
Config: testAccFolderIamBasic(org, fname),
5555
Check: resource.ComposeTestCheckFunc(
56-
testAccFolderExistingPolicy(org, fname),
56+
testAccFolderExistingPolicy(t, org, fname),
5757
),
5858
},
5959
// Apply an IAM binding
@@ -94,7 +94,7 @@ func TestAccFolderIamMember_remove(t *testing.T) {
9494
{
9595
Config: testAccFolderIamBasic(org, fname),
9696
Check: resource.ComposeTestCheckFunc(
97-
testAccFolderExistingPolicy(org, fname),
97+
testAccFolderExistingPolicy(t, org, fname),
9898
),
9999
},
100100
// Apply multiple IAM bindings
@@ -111,7 +111,7 @@ func TestAccFolderIamMember_remove(t *testing.T) {
111111
{
112112
Config: testAccFolderIamBasic(org, fname),
113113
Check: resource.ComposeTestCheckFunc(
114-
testAccFolderExistingPolicy(org, fname),
114+
testAccFolderExistingPolicy(t, org, fname),
115115
),
116116
},
117117
},

google-beta/resource_google_folder_iam_policy_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ func testAccCheckGoogleFolderIamPolicyDestroyProducer(t *testing.T) func(s *terr
8686
}
8787

8888
// Confirm that a folder has an IAM policy with at least 1 binding
89-
func testAccFolderExistingPolicy(org, fname string) resource.TestCheckFunc {
89+
func testAccFolderExistingPolicy(t *testing.T, org, fname string) resource.TestCheckFunc {
9090
return func(s *terraform.State) error {
91-
c := testAccProvider.Meta().(*Config)
91+
c := googleProviderConfig(t)
9292
var err error
9393
originalPolicy, err = getFolderIamPolicyByParentAndDisplayName("organizations/"+org, fname, c)
9494
if err != nil {

google-beta/resource_google_project_iam_audit_config_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestAccProjectIamAuditConfig_basic(t *testing.T) {
3232
{
3333
Config: testAccProject_create(pid, pname, org),
3434
Check: resource.ComposeTestCheckFunc(
35-
testAccProjectExistingPolicy(pid),
35+
testAccProjectExistingPolicy(t, pid),
3636
),
3737
},
3838
// Apply an IAM audit config
@@ -61,7 +61,7 @@ func TestAccProjectIamAuditConfig_multiple(t *testing.T) {
6161
{
6262
Config: testAccProject_create(pid, pname, org),
6363
Check: resource.ComposeTestCheckFunc(
64-
testAccProjectExistingPolicy(pid),
64+
testAccProjectExistingPolicy(t, pid),
6565
),
6666
},
6767
// Apply an IAM audit config
@@ -95,7 +95,7 @@ func TestAccProjectIamAuditConfig_multipleAtOnce(t *testing.T) {
9595
{
9696
Config: testAccProject_create(pid, pname, org),
9797
Check: resource.ComposeTestCheckFunc(
98-
testAccProjectExistingPolicy(pid),
98+
testAccProjectExistingPolicy(t, pid),
9999
),
100100
},
101101
// Apply an IAM audit config
@@ -124,7 +124,7 @@ func TestAccProjectIamAuditConfig_update(t *testing.T) {
124124
{
125125
Config: testAccProject_create(pid, pname, org),
126126
Check: resource.ComposeTestCheckFunc(
127-
testAccProjectExistingPolicy(pid),
127+
testAccProjectExistingPolicy(t, pid),
128128
),
129129
},
130130
// Apply an IAM audit config
@@ -165,7 +165,7 @@ func TestAccProjectIamAuditConfig_remove(t *testing.T) {
165165
{
166166
Config: testAccProject_create(pid, pname, org),
167167
Check: resource.ComposeTestCheckFunc(
168-
testAccProjectExistingPolicy(pid),
168+
testAccProjectExistingPolicy(t, pid),
169169
),
170170
},
171171
// Apply multiple IAM audit configs
@@ -179,7 +179,7 @@ func TestAccProjectIamAuditConfig_remove(t *testing.T) {
179179
{
180180
Config: testAccProject_create(pid, pname, org),
181181
Check: resource.ComposeTestCheckFunc(
182-
testAccProjectExistingPolicy(pid),
182+
testAccProjectExistingPolicy(t, pid),
183183
),
184184
},
185185
},
@@ -204,7 +204,7 @@ func TestAccProjectIamAuditConfig_addFirstExemptMember(t *testing.T) {
204204
{
205205
Config: testAccProject_create(pid, pname, org),
206206
Check: resource.ComposeTestCheckFunc(
207-
testAccProjectExistingPolicy(pid),
207+
testAccProjectExistingPolicy(t, pid),
208208
),
209209
},
210210
// Apply IAM audit config with no members
@@ -240,7 +240,7 @@ func TestAccProjectIamAuditConfig_removeLastExemptMember(t *testing.T) {
240240
{
241241
Config: testAccProject_create(pid, pname, org),
242242
Check: resource.ComposeTestCheckFunc(
243-
testAccProjectExistingPolicy(pid),
243+
testAccProjectExistingPolicy(t, pid),
244244
),
245245
},
246246
// Apply IAM audit config with member
@@ -276,7 +276,7 @@ func TestAccProjectIamAuditConfig_updateNoExemptMembers(t *testing.T) {
276276
{
277277
Config: testAccProject_create(pid, pname, org),
278278
Check: resource.ComposeTestCheckFunc(
279-
testAccProjectExistingPolicy(pid),
279+
testAccProjectExistingPolicy(t, pid),
280280
),
281281
},
282282
// Apply IAM audit config with DATA_READ

0 commit comments

Comments
 (0)