From 3849c1a42abf250394c3031f1c1623cd273bd52c Mon Sep 17 00:00:00 2001 From: Michael Traver Date: Tue, 10 Nov 2020 16:51:39 -0800 Subject: [PATCH] fix: compare legacy event timestamps by value instead of format (#50) Legacy event timestamp validation was done by string comparison, but this requires each language to format the timestamp in the same way. In Go, sub-second precision isn't always included [1]; in the test events the seconds field is 0 but is written with sub-second precision. It's not feasible to change the marshalling of timestamps in the Go test function, so instead we'll compare timestamps by their value. They're parsed as RFC3339 timestamps, so validation will still fail if the format is totally wrong, but this affords some leniency in the formatting. [1] From https://golang.org/pkg/time/#Time.MarshalJSON: "The time is a quoted string in RFC 3339 format, with sub-second precision added if present." --- events/validators.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/events/validators.go b/events/validators.go index fb5f4ca..21a5523 100644 --- a/events/validators.go +++ b/events/validators.go @@ -18,6 +18,7 @@ import ( "encoding/json" "fmt" "reflect" + "time" cloudevents "github.com/cloudevents/sdk-go/v2" "github.com/google/go-cmp/cmp" @@ -94,13 +95,13 @@ func validateLegacyEvent(name string, gotBytes, wantBytes []byte) *ValidationInf got := make(map[string]interface{}) err := json.Unmarshal(gotBytes, &got) if err != nil { - vi.Errs = append(vi.Errs, fmt.Errorf("unmarshalling function-received version of legacy event %q: %v", name, err)) + vi.Errs = append(vi.Errs, fmt.Errorf("unmarshalling received legacy event %q: %v", name, err)) } want := make(map[string]interface{}) err = json.Unmarshal(wantBytes, &want) if err != nil { - vi.Errs = append(vi.Errs, fmt.Errorf("unmarshalling expected contents of legacy event %q: %v", name, err)) + vi.Errs = append(vi.Errs, fmt.Errorf("unmarshalling expected legacy event %q: %v", name, err)) } // If there were issues extracting the data, bail early. @@ -117,6 +118,16 @@ func validateLegacyEvent(name string, gotBytes, wantBytes []byte) *ValidationInf gotValue interface{} wantValue interface{} } + gotTimestamp, err := time.Parse(time.RFC3339, gotContext["timestamp"].(string)) + if err != nil { + vi.Errs = append(vi.Errs, fmt.Errorf("parsing timestamp of received legacy event: %v", err)) + return vi + } + wantTimestamp, err := time.Parse(time.RFC3339, wantContext["timestamp"].(string)) + if err != nil { + vi.Errs = append(vi.Errs, fmt.Errorf("parsing timestamp of expected legacy event: %v", err)) + return vi + } fields := []eventFields{ { name: "ID", @@ -130,8 +141,8 @@ func validateLegacyEvent(name string, gotBytes, wantBytes []byte) *ValidationInf }, { name: "timestamp", - gotValue: gotContext["timestamp"], - wantValue: wantContext["timestamp"], + gotValue: gotTimestamp, + wantValue: wantTimestamp, }, { name: "resource",