Path: blob/main/components/gitpod-db/go/workspace_instance_test.go
2497 views
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package db_test56import (7"context"8"fmt"9"testing"10"time"1112db "github.com/gitpod-io/gitpod/components/gitpod-db/go"1314"github.com/gitpod-io/gitpod/components/gitpod-db/go/dbtest"15"github.com/google/uuid"16"github.com/stretchr/testify/require"17)1819var (20startOfMay = time.Date(2022, 05, 1, 0, 00, 00, 00, time.UTC)21startOfJune = time.Date(2022, 06, 1, 0, 00, 00, 00, time.UTC)22)2324func TestFindStoppedWorkspaceInstancesInRange(t *testing.T) {25conn := dbtest.ConnectForTests(t)2627workspace := dbtest.CreateWorkspaces(t, conn, dbtest.NewWorkspace(t, db.Workspace{}))[0]2829valid := []db.WorkspaceInstance{30// In the middle of May31dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{32WorkspaceID: workspace.ID,33StartedTime: db.NewVarCharTime(time.Date(2022, 05, 15, 12, 00, 00, 00, time.UTC)),34StoppingTime: db.NewVarCharTime(time.Date(2022, 05, 15, 13, 00, 00, 00, time.UTC)),35}),36// Start of May37dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{38ID: uuid.New(),39WorkspaceID: workspace.ID,40StartedTime: db.NewVarCharTime(time.Date(2022, 05, 1, 0, 00, 00, 00, time.UTC)),41StoppingTime: db.NewVarCharTime(time.Date(2022, 05, 1, 1, 00, 00, 00, time.UTC)),42}),43// End of May44dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{45ID: uuid.New(),46WorkspaceID: workspace.ID,47StartedTime: db.NewVarCharTime(time.Date(2022, 05, 31, 23, 00, 00, 00, time.UTC)),48StoppingTime: db.NewVarCharTime(time.Date(2022, 05, 31, 23, 59, 59, 999999, time.UTC)),49}),50// Started in April, but continued into May51dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{52ID: uuid.New(),53WorkspaceID: workspace.ID,54StartedTime: db.NewVarCharTime(time.Date(2022, 04, 30, 23, 00, 00, 00, time.UTC)),55StoppingTime: db.NewVarCharTime(time.Date(2022, 05, 1, 0, 0, 0, 0, time.UTC)),56}),57}58invalid := []db.WorkspaceInstance{59// Started in April, no stop time, still running60dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{61ID: uuid.New(),62WorkspaceID: workspace.ID,63StartedTime: db.NewVarCharTime(time.Date(2022, 04, 31, 23, 00, 00, 00, time.UTC)),64}),65// Started in May, but continued into June66dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{67ID: uuid.New(),68WorkspaceID: workspace.ID,69StartedTime: db.NewVarCharTime(time.Date(2022, 05, 31, 23, 00, 00, 00, time.UTC)),70StoppingTime: db.NewVarCharTime(time.Date(2022, 06, 1, 1, 0, 0, 0, time.UTC)),71}),72// Started in April, but continued into June (ran for all of May)73dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{74ID: uuid.New(),75WorkspaceID: workspace.ID,76StartedTime: db.NewVarCharTime(time.Date(2022, 04, 31, 23, 00, 00, 00, time.UTC)),77StoppingTime: db.NewVarCharTime(time.Date(2022, 06, 1, 1, 0, 0, 0, time.UTC)),78}),79// Start of June80dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{81ID: uuid.New(),82WorkspaceID: workspace.ID,83StartedTime: db.NewVarCharTime(time.Date(2022, 06, 1, 00, 00, 00, 00, time.UTC)),84StoppingTime: db.NewVarCharTime(time.Date(2022, 06, 1, 1, 0, 0, 0, time.UTC)),85}),86}8788var all []db.WorkspaceInstance89all = append(all, valid...)90all = append(all, invalid...)9192dbtest.CreateWorkspaceInstances(t, conn, all...)9394retrieved := dbtest.FindStoppedWorkspaceInstancesInRange(t, conn, startOfMay, startOfJune, workspace.ID)9596require.Len(t, retrieved, len(valid))97}9899func TestAttributionID_Values(t *testing.T) {100scenarios := []struct {101Input string102ExpectedEntity string103ExpectedID string104}{105{Input: "team:123", ExpectedEntity: "team", ExpectedID: "123"},106{Input: "user:123", ExpectedEntity: "", ExpectedID: ""},107{Input: "foo:123", ExpectedEntity: "", ExpectedID: ""},108{Input: "user:123:invalid", ExpectedEntity: "", ExpectedID: ""},109{Input: "invalid:123:", ExpectedEntity: "", ExpectedID: ""},110{Input: "", ExpectedEntity: "", ExpectedID: ""},111}112113for _, s := range scenarios {114t.Run(fmt.Sprintf("attribution in: %s, expecting: %s %s", s.Input, s.ExpectedEntity, s.ExpectedID), func(t *testing.T) {115entity, id := db.AttributionID(s.Input).Values()116require.Equal(t, s.ExpectedEntity, entity)117require.Equal(t, s.ExpectedID, id)118})119}120}121122func TestFindRunningWorkspace(t *testing.T) {123conn := dbtest.ConnectForTests(t)124125workspace := dbtest.CreateWorkspaces(t, conn, dbtest.NewWorkspace(t, db.Workspace{}))[0]126now := time.Now()127fiveMinAgo := now.Add(-5 * time.Minute)128tenMinAgo := now.Add(-10 * time.Minute)129moreThan10DaysAgo := now.Add(-11 * 24 * time.Hour)130131all := []db.WorkspaceInstance{132// one stopped instance133dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{134WorkspaceID: workspace.ID,135StartedTime: db.NewVarCharTime(tenMinAgo),136StoppingTime: db.NewVarCharTime(fiveMinAgo),137}),138// one unstopped before 10 days ago139dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{140WorkspaceID: workspace.ID,141StartedTime: db.NewVarCharTime(moreThan10DaysAgo),142PhasePersisted: "running",143}),144// Two running instances145dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{146ID: uuid.New(),147WorkspaceID: workspace.ID,148StartedTime: db.NewVarCharTime(tenMinAgo),149PhasePersisted: "running",150}),151dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{152ID: uuid.New(),153WorkspaceID: workspace.ID,154StartedTime: db.NewVarCharTime(tenMinAgo),155PhasePersisted: "running",156}),157}158159dbtest.CreateWorkspaceInstances(t, conn, all...)160161retrieved := dbtest.FindRunningWorkspaceInstances(t, conn, workspace.ID)162163require.Equal(t, 2, len(retrieved))164for _, ws := range retrieved {165require.False(t, ws.StoppingTime.IsSet())166}167168}169170func TestFindWorkspacesByInstanceId(t *testing.T) {171conn := dbtest.ConnectForTests(t)172173workspace := dbtest.CreateWorkspaces(t, conn, dbtest.NewWorkspace(t, db.Workspace{}))[0]174175all := []db.WorkspaceInstance{176// one stopped instance177dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{178WorkspaceID: workspace.ID,179StartedTime: db.NewVarCharTime(time.Date(2022, 05, 15, 12, 00, 00, 00, time.UTC)),180StoppingTime: db.NewVarCharTime(time.Date(2022, 05, 15, 13, 00, 00, 00, time.UTC)),181}),182// Two running instances183dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{184ID: uuid.New(),185WorkspaceID: workspace.ID,186StartedTime: db.NewVarCharTime(time.Date(2022, 05, 1, 0, 00, 00, 00, time.UTC)),187}),188dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{189ID: uuid.New(),190WorkspaceID: workspace.ID,191StartedTime: db.NewVarCharTime(time.Date(2022, 04, 30, 23, 00, 00, 00, time.UTC)),192}),193}194195twoIds := []uuid.UUID{all[0].ID, all[1].ID}196197dbtest.CreateWorkspaceInstances(t, conn, all...)198199retrieved, err := db.FindWorkspaceInstancesByIds(context.Background(), conn, twoIds)200require.NoError(t, err)201202require.Equal(t, 2, len(retrieved))203for _, ws := range retrieved {204require.NotEqual(t, all[2].ID, ws.ID)205}206207}208209func TestListWorkspaceInstanceIDsWithPhaseStoppedButNoStoppingTime(t *testing.T) {210dbconn := dbtest.ConnectForTests(t)211instances := dbtest.CreateWorkspaceInstances(t, dbconn,212// started but not stopped, should be ignored213dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{214StartedTime: db.NewVarCharTime(time.Now()),215}),216// stopped, but no stopping time, should be detected217dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{218StartedTime: db.NewVarCharTime(time.Now()),219PhasePersisted: "stopped",220}),221)222223dbtest.CreateUsageRecords(t, dbconn,224dbtest.NewUsage(t, db.Usage{225ID: instances[0].ID,226}),227dbtest.NewUsage(t, db.Usage{228ID: instances[1].ID,229}),230)231232detectedIDs, err := db.ListWorkspaceInstanceIDsWithPhaseStoppedButNoStoppingTime(context.Background(), dbconn)233require.NoError(t, err)234require.Equal(t, []uuid.UUID{instances[1].ID}, detectedIDs)235}236237238