diff --git a/config/tests/samples/create/harness.go b/config/tests/samples/create/harness.go index 350c29e8f5..ff2e4154bf 100644 --- a/config/tests/samples/create/harness.go +++ b/config/tests/samples/create/harness.go @@ -315,9 +315,9 @@ func NewHarness(ctx context.Context, t *testing.T) *Harness { // Initialize VCR for TF requests input := os.Getenv("VCR_MODE") var VCRMode recorder.Mode - if input == "recording" { + if input == "record" { VCRMode = recorder.ModeRecordOnly - } else if input == "replaying" { + } else if input == "replay" { VCRMode = recorder.ModeReplayOnly } else { t.Fatalf("[VCR] Input mode is not supported.") diff --git a/pkg/test/resourcefixture/testdata/vcr/cassette/TestAllInSeries_fixtures_computenodetemplate.seed b/pkg/test/resourcefixture/testdata/vcr/cassette/TestAllInSeries_fixtures_computenodetemplate.seed index ca1f23815c..b22033829b 100644 --- a/pkg/test/resourcefixture/testdata/vcr/cassette/TestAllInSeries_fixtures_computenodetemplate.seed +++ b/pkg/test/resourcefixture/testdata/vcr/cassette/TestAllInSeries_fixtures_computenodetemplate.seed @@ -1 +1 @@ -3838530829430228066 \ No newline at end of file +7566824334709531536 \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/vcr/cassette/TestAllInSeries_fixtures_computenodetemplate.yaml b/pkg/test/resourcefixture/testdata/vcr/cassette/TestAllInSeries_fixtures_computenodetemplate.yaml index 23fb4e0cc6..bcb9b05544 100644 --- a/pkg/test/resourcefixture/testdata/vcr/cassette/TestAllInSeries_fixtures_computenodetemplate.yaml +++ b/pkg/test/resourcefixture/testdata/vcr/cassette/TestAllInSeries_fixtures_computenodetemplate.yaml @@ -1,17 +1,3 @@ -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - --- version: 2 interactions: @@ -20,61 +6,14 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 0 - transfer_encoding: [] - trailer: {} - host: compute.googleapis.com - remote_addr: "" - request_uri: "" - body: "" - form: {} - headers: - Content-Type: - - application/json - url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc?alt=json - method: GET - response: - proto: HTTP/2.0 - proto_major: 2 - proto_minor: 0 - transfer_encoding: [] - trailer: {} - content_length: -1 - uncompressed: true - body: | - { - "error": { - "code": 404, - "message": "The resource 'projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc' was not found", - "errors": [ - { - "message": "The resource 'projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc' was not found", - "domain": "global", - "reason": "notFound", - "debugInfo": "fake debug info" - } - ] - } - } - headers: - Content-Type: - - application/json; charset=UTF-8 - status: 404 Not Found - code: 404 - duration: 193.443983ms - - id: 1 - request: - proto: HTTP/1.1 - proto_major: 1 - proto_minor: 1 - content_length: 409 + content_length: 410 transfer_encoding: [] trailer: {} host: compute.googleapis.com remote_addr: "" request_uri: "" body: | - {"cpuOvercommitType":"NONE","description":"Node template for sole tenant nodes running in us-central1, with 96vCPUs and any amount of memory on any machine type.","name":"computenodetemplate-eh8yabhagpgc","nodeAffinityLabels":{"cnrm-test":"true","managed-by-cnrm":"true","memory_guarantee":"false"},"nodeTypeFlexibility":{"cpus":"96","memory":"any"},"region":"projects/cnrm-user/global/regions/us-central1"} + {"cpuOvercommitType":"NONE","description":"Node template for sole tenant nodes running in us-central1, with 96vCPUs and any amount of memory on any machine type.","name":"computenodetemplate-33a4ihmeg1u4l","nodeAffinityLabels":{"cnrm-test":"true","managed-by-cnrm":"true","memory_guarantee":"false"},"nodeTypeFlexibility":{"cpus":"96","memory":"any"},"region":"projects/cnrm-user/global/regions/us-central1"} form: {} headers: Content-Type: @@ -92,26 +31,26 @@ interactions: body: | { "kind": "compute#operation", - "id": "5449225809889107670", - "name": "operation-1710825528762-613fc9bea1fe3-55490b87-cb1b4ec4", + "id": "2450955058046816700", + "name": "operation-1711173459145-6144d9e2e71fa-a2bdc85e-7750565b", "operationType": "compute.nodeTemplates.insert", - "targetLink": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc", - "targetId": "2755123117236199126", + "targetLink": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l", + "targetId": "3102467589298966972", "status": "RUNNING", "user": "user@google.com", "progress": 0, - "insertTime": "2024-03-18T22:18:49.005-07:00", - "startTime": "2024-03-18T22:18:49.037-07:00", - "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/operations/operation-1710825528762-613fc9bea1fe3-55490b87-cb1b4ec4", - "region": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1" + "insertTime": "2024-03-22T22:57:39.419-07:00", + "startTime": "2024-03-22T22:57:39.454-07:00", + "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/operations/operation-1711173459145-6144d9e2e71fa-a2bdc85e-7750565b", + "region": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1" } headers: Content-Type: - application/json; charset=UTF-8 status: 200 OK code: 200 - duration: 400.705161ms - - id: 2 + duration: 405.258794ms + - id: 1 request: proto: HTTP/1.1 proto_major: 1 @@ -127,7 +66,7 @@ interactions: headers: X-Goog-Api-Client: - gl-go/1.21.5 gdcl/0.160.0 - url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/operations/operation-1710825528762-613fc9bea1fe3-55490b87-cb1b4ec4?alt=json&prettyPrint=false + url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/operations/operation-1711173459145-6144d9e2e71fa-a2bdc85e-7750565b?alt=json&prettyPrint=false method: GET response: proto: HTTP/2.0 @@ -137,14 +76,14 @@ interactions: trailer: {} content_length: -1 uncompressed: true - body: '{"kind":"compute#operation","id":"5449225809889107670","name":"operation-1710825528762-613fc9bea1fe3-55490b87-cb1b4ec4","operationType":"compute.nodeTemplates.insert","targetLink":"https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc","targetId":"2755123117236199126","status":"DONE","user":"user@google.com","progress":100,"insertTime":"2024-03-18T22:18:49.005-07:00","startTime":"2024-03-18T22:18:49.037-07:00","endTime":"2024-03-18T22:18:49.286-07:00","selfLink":"https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/operations/operation-1710825528762-613fc9bea1fe3-55490b87-cb1b4ec4","region":"https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1"}' + body: '{"kind":"compute#operation","id":"2450955058046816700","name":"operation-1711173459145-6144d9e2e71fa-a2bdc85e-7750565b","operationType":"compute.nodeTemplates.insert","targetLink":"https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l","targetId":"3102467589298966972","status":"DONE","user":"user@google.com","progress":100,"insertTime":"2024-03-22T22:57:39.419-07:00","startTime":"2024-03-22T22:57:39.454-07:00","endTime":"2024-03-22T22:57:39.734-07:00","selfLink":"https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/operations/operation-1711173459145-6144d9e2e71fa-a2bdc85e-7750565b","region":"https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1"}' headers: Content-Type: - application/json; charset=UTF-8 status: 200 OK code: 200 - duration: 140.878279ms - - id: 3 + duration: 408.074853ms + - id: 2 request: proto: HTTP/1.1 proto_major: 1 @@ -160,7 +99,7 @@ interactions: headers: Content-Type: - application/json - url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc?alt=json + url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l?alt=json method: GET response: proto: HTTP/2.0 @@ -173,9 +112,9 @@ interactions: body: | { "kind": "compute#nodeTemplate", - "id": "2755123117236199126", - "creationTimestamp": "2024-03-18T22:18:49.012-07:00", - "name": "computenodetemplate-eh8yabhagpgc", + "id": "3102467589298966972", + "creationTimestamp": "2024-03-22T22:57:39.429-07:00", + "name": "computenodetemplate-33a4ihmeg1u4l", "description": "Node template for sole tenant nodes running in us-central1, with 96vCPUs and any amount of memory on any machine type.", "nodeAffinityLabels": { "memory_guarantee": "false", @@ -183,8 +122,8 @@ interactions: "managed-by-cnrm": "true" }, "status": "READY", - "region": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1", - "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc", + "region": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l", "nodeTypeFlexibility": { "cpus": "96", "memory": "any" @@ -199,8 +138,8 @@ interactions: - application/json; charset=UTF-8 status: 200 OK code: 200 - duration: 150.587478ms - - id: 4 + duration: 301.137398ms + - id: 3 request: proto: HTTP/1.1 proto_major: 1 @@ -216,7 +155,7 @@ interactions: headers: Content-Type: - application/json - url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc?alt=json + url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l?alt=json method: GET response: proto: HTTP/2.0 @@ -229,9 +168,9 @@ interactions: body: | { "kind": "compute#nodeTemplate", - "id": "2755123117236199126", - "creationTimestamp": "2024-03-18T22:18:49.012-07:00", - "name": "computenodetemplate-eh8yabhagpgc", + "id": "3102467589298966972", + "creationTimestamp": "2024-03-22T22:57:39.429-07:00", + "name": "computenodetemplate-33a4ihmeg1u4l", "description": "Node template for sole tenant nodes running in us-central1, with 96vCPUs and any amount of memory on any machine type.", "nodeAffinityLabels": { "memory_guarantee": "false", @@ -239,8 +178,8 @@ interactions: "managed-by-cnrm": "true" }, "status": "READY", - "region": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1", - "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc", + "region": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l", "nodeTypeFlexibility": { "cpus": "96", "memory": "any" @@ -255,8 +194,8 @@ interactions: - application/json; charset=UTF-8 status: 200 OK code: 200 - duration: 151.268778ms - - id: 5 + duration: 317.983635ms + - id: 4 request: proto: HTTP/1.1 proto_major: 1 @@ -272,7 +211,7 @@ interactions: headers: Content-Type: - application/json - url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc?alt=json + url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l?alt=json method: GET response: proto: HTTP/2.0 @@ -285,18 +224,18 @@ interactions: body: | { "kind": "compute#nodeTemplate", - "id": "2755123117236199126", - "creationTimestamp": "2024-03-18T22:18:49.012-07:00", - "name": "computenodetemplate-eh8yabhagpgc", + "id": "3102467589298966972", + "creationTimestamp": "2024-03-22T22:57:39.429-07:00", + "name": "computenodetemplate-33a4ihmeg1u4l", "description": "Node template for sole tenant nodes running in us-central1, with 96vCPUs and any amount of memory on any machine type.", "nodeAffinityLabels": { - "memory_guarantee": "false", "cnrm-test": "true", - "managed-by-cnrm": "true" + "managed-by-cnrm": "true", + "memory_guarantee": "false" }, "status": "READY", - "region": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1", - "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc", + "region": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l", "nodeTypeFlexibility": { "cpus": "96", "memory": "any" @@ -311,8 +250,8 @@ interactions: - application/json; charset=UTF-8 status: 200 OK code: 200 - duration: 123.055182ms - - id: 6 + duration: 217.899519ms + - id: 5 request: proto: HTTP/1.1 proto_major: 1 @@ -328,7 +267,7 @@ interactions: headers: Content-Type: - application/json - url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc?alt=json + url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l?alt=json method: DELETE response: proto: HTTP/2.0 @@ -341,26 +280,26 @@ interactions: body: | { "kind": "compute#operation", - "id": "3629097340760268500", - "name": "operation-1710825530847-613fc9c09ef32-c8cf95aa-6131eb7f", + "id": "243844507925467576", + "name": "operation-1711173463206-6144d9e6c69d7-83d25262-47f7ce48", "operationType": "compute.nodeTemplates.delete", - "targetLink": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc", - "targetId": "2755123117236199126", + "targetLink": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l", + "targetId": "3102467589298966972", "status": "RUNNING", "user": "user@google.com", "progress": 0, - "insertTime": "2024-03-18T22:18:51.095-07:00", - "startTime": "2024-03-18T22:18:51.117-07:00", - "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/operations/operation-1710825530847-613fc9c09ef32-c8cf95aa-6131eb7f", - "region": "https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1" + "insertTime": "2024-03-22T22:57:43.441-07:00", + "startTime": "2024-03-22T22:57:43.460-07:00", + "selfLink": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/operations/operation-1711173463206-6144d9e6c69d7-83d25262-47f7ce48", + "region": "https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1" } headers: Content-Type: - application/json; charset=UTF-8 status: 200 OK code: 200 - duration: 402.865302ms - - id: 7 + duration: 372.731313ms + - id: 6 request: proto: HTTP/1.1 proto_major: 1 @@ -376,7 +315,7 @@ interactions: headers: X-Goog-Api-Client: - gl-go/1.21.5 gdcl/0.160.0 - url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/operations/operation-1710825530847-613fc9c09ef32-c8cf95aa-6131eb7f?alt=json&prettyPrint=false + url: https://compute.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/operations/operation-1711173463206-6144d9e6c69d7-83d25262-47f7ce48?alt=json&prettyPrint=false method: GET response: proto: HTTP/2.0 @@ -386,10 +325,10 @@ interactions: trailer: {} content_length: -1 uncompressed: true - body: '{"kind":"compute#operation","id":"3629097340760268500","name":"operation-1710825530847-613fc9c09ef32-c8cf95aa-6131eb7f","operationType":"compute.nodeTemplates.delete","targetLink":"https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/nodeTemplates/computenodetemplate-eh8yabhagpgc","targetId":"2755123117236199126","status":"DONE","user":"user@google.com","progress":100,"insertTime":"2024-03-18T22:18:51.095-07:00","startTime":"2024-03-18T22:18:51.117-07:00","endTime":"2024-03-18T22:18:51.451-07:00","selfLink":"https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1/operations/operation-1710825530847-613fc9c09ef32-c8cf95aa-6131eb7f","region":"https://www.googleapis.com/compute/beta/projects/cnrm-user/regions/us-central1"}' + body: '{"kind":"compute#operation","id":"243844507925467576","name":"operation-1711173463206-6144d9e6c69d7-83d25262-47f7ce48","operationType":"compute.nodeTemplates.delete","targetLink":"https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/nodeTemplates/computenodetemplate-33a4ihmeg1u4l","targetId":"3102467589298966972","status":"DONE","user":"user@google.com","progress":100,"insertTime":"2024-03-22T22:57:43.441-07:00","startTime":"2024-03-22T22:57:43.460-07:00","endTime":"2024-03-22T22:57:43.787-07:00","selfLink":"https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1/operations/operation-1711173463206-6144d9e6c69d7-83d25262-47f7ce48","region":"https://www.googleapis.com/compute/beta/projects/cnrm-yuhou/regions/us-central1"}' headers: Content-Type: - application/json; charset=UTF-8 status: 200 OK code: 200 - duration: 129.001311ms + duration: 150.689745ms diff --git a/tests/e2e/unified_test.go b/tests/e2e/unified_test.go index 22509a659a..94d83cdcc0 100644 --- a/tests/e2e/unified_test.go +++ b/tests/e2e/unified_test.go @@ -29,6 +29,7 @@ import ( "net/http" "os" "path/filepath" + "sort" "strconv" "strings" "testing" @@ -204,7 +205,27 @@ func testFixturesInSeries(ctx context.Context, t *testing.T, testName string, te return result } + unique := make(map[string]bool) + hook := func(i *cassette.Interaction) error { + // Discard failed interactions + resCode := i.Response.Code + if resCode == 404 || resCode == 400 || resCode == 403 { + i.DiscardOnSave = true + } + // Discard repeated operation retry interactions + reqURL := i.Request.URL + resBody := i.Response.Body + + if strings.Contains(reqURL, "operations") { + sorted, _ := sortJSON(resBody) + if _, exists := unique[sorted]; !exists { + unique[sorted] = true // Mark as seen + } else { + i.DiscardOnSave = true + } + } + var requestHeadersToRemove = []string{ "Authorization", "User-Agent", @@ -231,31 +252,16 @@ func testFixturesInSeries(ctx context.Context, t *testing.T, testName string, te i.Response.Body = replaceFunc(i.Response.Body) i.Request.URL = replaceFunc(i.Request.URL) - s := i.Response.Body obj := make(map[string]any) - if err := json.Unmarshal([]byte(s), &obj); err != nil { - klog.Fatalf("error from json.Unmarshal(%q): %v", s, err) + if err := json.Unmarshal([]byte(resBody), &obj); err != nil { + klog.Fatalf("error from json.Unmarshal(%q): %v", resBody, err) } toReplace, _, _ := unstructured.NestedString(obj, "user") if len(toReplace) != 0 { - s = strings.Replace(s, toReplace, "user@google.com", -1) + resBody = strings.Replace(resBody, toReplace, "user@google.com", -1) } - // A very hacky way to replace actual debug info from log. - if strings.Contains(s, "error") && strings.Contains(s, "debugInfo") { - keyword := "\"debugInfo\": \"" - // Find index of the start of debugInfo string - startIndex := strings.Index(s, keyword) - // Find index of the end of debugInfo string, by searching for the end quote character - subString := s[startIndex+len(keyword):] - endIndex := strings.Index(subString, "\"") - // Use both indexes to get the string contains the message we need to remove - temp := s[startIndex+len(keyword) : startIndex+len(keyword)+endIndex] - // Replace - s = strings.Replace(s, temp, "fake debug info", -1) - } - - i.Response.Body = s + i.Response.Body = resBody return nil } h.VCRRecorder.AddHook(hook, recorder.BeforeSaveHook) @@ -578,3 +584,33 @@ func readSeed(fileName string) (int64, error) { seed := string(data) return tpgresource.StringToFixed64(seed) } + +type KeyValue struct { + Key string `json:"key"` + Value interface{} `json:"value"` +} + +type KeyValueSlice []KeyValue + +func (kv KeyValueSlice) Len() int { return len(kv) } +func (kv KeyValueSlice) Less(i, j int) bool { return kv[i].Key < kv[j].Key } +func (kv KeyValueSlice) Swap(i, j int) { kv[i], kv[j] = kv[j], kv[i] } + +func sortJSON(s string) (string, error) { + var data map[string]interface{} + if err := json.Unmarshal([]byte(s), &data); err != nil { + return "", err + } + keyValueSlice := make(KeyValueSlice, len(data)) + for k, v := range data { + keyValueSlice = append(keyValueSlice, KeyValue{k, v}) + } + + sort.Sort(keyValueSlice) + + sortedJSON, err := json.Marshal(keyValueSlice) + if err != nil { + return "", err + } + return string(sortedJSON), nil +}