From 56c1b01a2fc4c30cee25fb7fe7f77646ae508fcb Mon Sep 17 00:00:00 2001 From: Milan Pavlik Date: Wed, 31 Aug 2022 09:55:26 +0000 Subject: [PATCH] [usage] Fix report to JSON conversion --- .../pkg/contentservice/usage_report_test.go | 63 +++++++++++++++++++ components/usage/pkg/db/types.go | 33 ++++++++-- 2 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 components/usage/pkg/contentservice/usage_report_test.go diff --git a/components/usage/pkg/contentservice/usage_report_test.go b/components/usage/pkg/contentservice/usage_report_test.go new file mode 100644 index 00000000000000..acad6bed4ee2ce --- /dev/null +++ b/components/usage/pkg/contentservice/usage_report_test.go @@ -0,0 +1,63 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License-AGPL.txt in the project root for license information. + +package contentservice + +import ( + "database/sql" + "encoding/json" + "fmt" + "github.com/gitpod-io/gitpod/usage/pkg/db" + "github.com/gitpod-io/gitpod/usage/pkg/db/dbtest" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +func TestUsageReport_ToJSON(t *testing.T) { + report := UsageReport{ + GenerationTime: time.Now().UTC(), + From: time.Now().UTC(), + To: time.Now().UTC(), + RawSessions: []db.WorkspaceInstanceForUsage{ + { + ID: uuid.New(), + WorkspaceID: dbtest.GenerateWorkspaceID(), + OwnerID: uuid.New(), + ProjectID: sql.NullString{ + String: "project-id", + Valid: true, + }, + WorkspaceClass: "workspace-class", + Type: "regular", + UsageAttributionID: db.NewTeamAttributionID(uuid.New().String()), + CreationTime: db.NewVarcharTime(time.Now()), + StartedTime: db.NewVarcharTime(time.Now()), + StoppingTime: db.NewVarcharTime(time.Now()), + StoppedTime: db.NewVarcharTime(time.Now()), + }, + }, + InvalidSessions: []InvalidSession{ + { + Reason: "some-reason", + Session: db.WorkspaceInstanceForUsage{}, + }, + }, + UsageRecords: []db.WorkspaceInstanceUsage{ + dbtest.NewWorkspaceInstanceUsage(t, db.WorkspaceInstanceUsage{}), + }, + } + + b, err := json.Marshal(report) + require.NoError(t, err) + + var actual UsageReport + err = json.Unmarshal(b, &actual) + require.NoError(t, err) + + fmt.Println(report, actual) + require.EqualValues(t, report, actual) + +} diff --git a/components/usage/pkg/db/types.go b/components/usage/pkg/db/types.go index 58c14df4e327fa..fbb8ddd62e8b21 100644 --- a/components/usage/pkg/db/types.go +++ b/components/usage/pkg/db/types.go @@ -13,7 +13,7 @@ import ( func NewVarcharTime(t time.Time) VarcharTime { return VarcharTime{ - t: t, + t: t.UTC(), valid: true, } } @@ -92,12 +92,35 @@ func (n VarcharTime) String() string { return "" } -func (u VarcharTime) MarshalJSON() ([]byte, error) { - if !u.IsSet() { - return []byte(""), nil +var null = "null" + +func (n VarcharTime) MarshalJSON() ([]byte, error) { + if !n.IsSet() { + return []byte(null), nil + } + + return n.Time().UTC().MarshalJSON() +} + +func (n *VarcharTime) UnmarshalJSON(data []byte) error { + if string(data) == null { + n.valid = false + return nil } - return u.Time().MarshalJSON() + t := time.Time{} + if err := t.UnmarshalJSON(data); err != nil { + return fmt.Errorf("failed to unmarshal VarcharTime %s: %w", string(data), err) + } + + if t.IsZero() { + return nil + } + + n.valid = true + n.t = t.UTC() + + return nil } const ISO8601Format = "2006-01-02T15:04:05.000Z"