fix: implement fake DeleteOldWorkspaceAgentLogs (#11042)

This commit is contained in:
Marcin Tojek
2023-12-06 14:31:43 +01:00
committed by GitHub
parent 088fd0b904
commit f6891bc465
2 changed files with 141 additions and 5 deletions
+23 -2
View File
@@ -1154,8 +1154,29 @@ func (q *FakeQuerier) DeleteOldProvisionerDaemons(_ context.Context) error {
return nil
}
func (*FakeQuerier) DeleteOldWorkspaceAgentLogs(_ context.Context) error {
// no-op
func (q *FakeQuerier) DeleteOldWorkspaceAgentLogs(_ context.Context) error {
q.mutex.Lock()
defer q.mutex.Unlock()
now := dbtime.Now()
weekInterval := 7 * 24 * time.Hour
weekAgo := now.Add(-weekInterval)
var validLogs []database.WorkspaceAgentLog
for _, log := range q.workspaceAgentLogs {
var toBeDeleted bool
for _, agent := range q.workspaceAgents {
if agent.ID == log.AgentID && agent.LastConnectedAt.Valid && agent.LastConnectedAt.Time.Before(weekAgo) {
toBeDeleted = true
break
}
}
if !toBeDeleted {
validLogs = append(validLogs, log)
}
}
q.workspaceAgentLogs = validLogs
return nil
}
+118 -3
View File
@@ -14,6 +14,7 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbpurge"
"github.com/coder/coder/v2/coderd/database/dbtestutil"
@@ -33,6 +34,118 @@ func TestPurge(t *testing.T) {
require.NoError(t, err)
}
func TestDeleteOldWorkspaceAgentLogs(t *testing.T) {
t.Parallel()
db, _ := dbtestutil.NewDB(t)
org := dbgen.Organization(t, db, database.Organization{})
user := dbgen.User(t, db, database.User{})
_ = dbgen.OrganizationMember(t, db, database.OrganizationMember{UserID: user.ID, OrganizationID: org.ID})
tv := dbgen.TemplateVersion(t, db, database.TemplateVersion{OrganizationID: org.ID, CreatedBy: user.ID})
tmpl := dbgen.Template(t, db, database.Template{OrganizationID: org.ID, ActiveVersionID: tv.ID, CreatedBy: user.ID})
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true})
now := dbtime.Now()
t.Run("AgentHasNotConnectedSinceWeek_LogsExpired", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()
// given
agent := mustCreateAgentWithLogs(ctx, t, db, user, org, tmpl, tv, now.Add(-8*24*time.Hour), t.Name())
// when
closer := dbpurge.New(ctx, logger, db)
defer closer.Close()
// then
require.Eventually(t, func() bool {
agentLogs, err := db.GetWorkspaceAgentLogsAfter(ctx, database.GetWorkspaceAgentLogsAfterParams{
AgentID: agent,
})
if err != nil {
return false
}
return !containsAgentLog(agentLogs, t.Name())
}, testutil.WaitShort, testutil.IntervalFast)
})
t.Run("AgentConnectedSixDaysAgo_LogsValid", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()
// given
agent := mustCreateAgentWithLogs(ctx, t, db, user, org, tmpl, tv, now.Add(-6*24*time.Hour), t.Name())
// when
closer := dbpurge.New(ctx, logger, db)
defer closer.Close()
// then
require.Eventually(t, func() bool {
agentLogs, err := db.GetWorkspaceAgentLogsAfter(ctx, database.GetWorkspaceAgentLogsAfterParams{
AgentID: agent,
})
if err != nil {
return false
}
return containsAgentLog(agentLogs, t.Name())
}, testutil.WaitShort, testutil.IntervalFast)
})
}
func mustCreateAgentWithLogs(ctx context.Context, t *testing.T, db database.Store, user database.User, org database.Organization, tmpl database.Template, tv database.TemplateVersion, agentLastConnectedAt time.Time, output string) uuid.UUID {
agent := mustCreateAgent(t, db, user, org, tmpl, tv)
err := db.UpdateWorkspaceAgentConnectionByID(ctx, database.UpdateWorkspaceAgentConnectionByIDParams{
ID: agent.ID,
LastConnectedAt: sql.NullTime{Time: agentLastConnectedAt, Valid: true},
})
require.NoError(t, err)
_, err = db.InsertWorkspaceAgentLogs(ctx, database.InsertWorkspaceAgentLogsParams{
AgentID: agent.ID,
CreatedAt: agentLastConnectedAt,
Output: []string{output},
Level: []database.LogLevel{database.LogLevelDebug},
})
require.NoError(t, err)
return agent.ID
}
func mustCreateAgent(t *testing.T, db database.Store, user database.User, org database.Organization, tmpl database.Template, tv database.TemplateVersion) database.WorkspaceAgent {
workspace := dbgen.Workspace(t, db, database.Workspace{OwnerID: user.ID, OrganizationID: org.ID, TemplateID: tmpl.ID})
job := dbgen.ProvisionerJob(t, db, nil, database.ProvisionerJob{
OrganizationID: org.ID,
Type: database.ProvisionerJobTypeWorkspaceBuild,
Provisioner: database.ProvisionerTypeEcho,
StorageMethod: database.ProvisionerStorageMethodFile,
})
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
WorkspaceID: workspace.ID,
JobID: job.ID,
TemplateVersionID: tv.ID,
Transition: database.WorkspaceTransitionStart,
Reason: database.BuildReasonInitiator,
})
resource := dbgen.WorkspaceResource(t, db, database.WorkspaceResource{
JobID: job.ID,
Transition: database.WorkspaceTransitionStart,
})
return dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{
ResourceID: resource.ID,
})
}
func containsAgentLog(daemons []database.WorkspaceAgentLog, output string) bool {
return slices.ContainsFunc(daemons, func(d database.WorkspaceAgentLog) bool {
return d.Output == output
})
}
func TestDeleteOldProvisionerDaemons(t *testing.T) {
t.Parallel()
@@ -91,12 +204,14 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
if err != nil {
return false
}
return contains(daemons, "external-0") &&
contains(daemons, "external-3")
return containsProvisionerDaemon(daemons, "external-0") &&
!containsProvisionerDaemon(daemons, "external-1") &&
!containsProvisionerDaemon(daemons, "external-2") &&
containsProvisionerDaemon(daemons, "external-3")
}, testutil.WaitShort, testutil.IntervalFast)
}
func contains(daemons []database.ProvisionerDaemon, name string) bool {
func containsProvisionerDaemon(daemons []database.ProvisionerDaemon, name string) bool {
return slices.ContainsFunc(daemons, func(d database.ProvisionerDaemon) bool {
return d.Name == name
})