mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
fix(coderd): use insights for DAUs, simplify metricscache (#12775)
Fixes #12134 Fixes https://github.com/coder/customers/issues/384 Refs #12122
This commit is contained in:
committed by
GitHub
parent
5d82a78d4c
commit
421bf7e785
@ -19,241 +19,10 @@ import (
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
)
|
||||
|
||||
func dateH(year, month, day, hour int) time.Time {
|
||||
return time.Date(year, time.Month(month), day, hour, 0, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
func date(year, month, day int) time.Time {
|
||||
return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
func TestCache_TemplateUsers(t *testing.T) {
|
||||
t.Parallel()
|
||||
statRow := func(user uuid.UUID, date time.Time) database.InsertWorkspaceAgentStatParams {
|
||||
return database.InsertWorkspaceAgentStatParams{
|
||||
CreatedAt: date,
|
||||
UserID: user,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
zebra = uuid.UUID{1}
|
||||
tiger = uuid.UUID{2}
|
||||
)
|
||||
|
||||
type args struct {
|
||||
rows []database.InsertWorkspaceAgentStatParams
|
||||
}
|
||||
type want struct {
|
||||
entries []codersdk.DAUEntry
|
||||
uniqueUsers int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
tplWant want
|
||||
// dauWant is optional
|
||||
dauWant []codersdk.DAUEntry
|
||||
tzOffset int
|
||||
}{
|
||||
{name: "empty", args: args{}, tplWant: want{nil, 0}},
|
||||
{
|
||||
name: "one hole",
|
||||
args: args{
|
||||
rows: []database.InsertWorkspaceAgentStatParams{
|
||||
statRow(zebra, dateH(2022, 8, 27, 0)),
|
||||
statRow(zebra, dateH(2022, 8, 30, 0)),
|
||||
},
|
||||
},
|
||||
tplWant: want{[]codersdk.DAUEntry{
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 8, 27)),
|
||||
Amount: 1,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 8, 28)),
|
||||
Amount: 0,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 8, 29)),
|
||||
Amount: 0,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 8, 30)),
|
||||
Amount: 1,
|
||||
},
|
||||
}, 1},
|
||||
},
|
||||
{
|
||||
name: "no holes",
|
||||
args: args{
|
||||
rows: []database.InsertWorkspaceAgentStatParams{
|
||||
statRow(zebra, dateH(2022, 8, 27, 0)),
|
||||
statRow(zebra, dateH(2022, 8, 28, 0)),
|
||||
statRow(zebra, dateH(2022, 8, 29, 0)),
|
||||
},
|
||||
},
|
||||
tplWant: want{[]codersdk.DAUEntry{
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 8, 27)),
|
||||
Amount: 1,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 8, 28)),
|
||||
Amount: 1,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 8, 29)),
|
||||
Amount: 1,
|
||||
},
|
||||
}, 1},
|
||||
},
|
||||
{
|
||||
name: "holes",
|
||||
args: args{
|
||||
rows: []database.InsertWorkspaceAgentStatParams{
|
||||
statRow(zebra, dateH(2022, 1, 1, 0)),
|
||||
statRow(tiger, dateH(2022, 1, 1, 0)),
|
||||
statRow(zebra, dateH(2022, 1, 4, 0)),
|
||||
statRow(zebra, dateH(2022, 1, 7, 0)),
|
||||
statRow(tiger, dateH(2022, 1, 7, 0)),
|
||||
},
|
||||
},
|
||||
tplWant: want{[]codersdk.DAUEntry{
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 1)),
|
||||
Amount: 2,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 2)),
|
||||
Amount: 0,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 3)),
|
||||
Amount: 0,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 4)),
|
||||
Amount: 1,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 5)),
|
||||
Amount: 0,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 6)),
|
||||
Amount: 0,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 7)),
|
||||
Amount: 2,
|
||||
},
|
||||
}, 2},
|
||||
},
|
||||
{
|
||||
name: "tzOffset",
|
||||
tzOffset: 3,
|
||||
args: args{
|
||||
rows: []database.InsertWorkspaceAgentStatParams{
|
||||
statRow(zebra, dateH(2022, 1, 2, 3)),
|
||||
statRow(tiger, dateH(2022, 1, 2, 3)),
|
||||
// With offset these should be in the previous day
|
||||
statRow(zebra, dateH(2022, 1, 2, 0)),
|
||||
statRow(tiger, dateH(2022, 1, 2, 0)),
|
||||
},
|
||||
},
|
||||
tplWant: want{[]codersdk.DAUEntry{
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 2)),
|
||||
Amount: 2,
|
||||
},
|
||||
}, 2},
|
||||
dauWant: []codersdk.DAUEntry{
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 1)),
|
||||
Amount: 2,
|
||||
},
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 2)),
|
||||
Amount: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tzOffsetPreviousDay",
|
||||
tzOffset: 6,
|
||||
args: args{
|
||||
rows: []database.InsertWorkspaceAgentStatParams{
|
||||
statRow(zebra, dateH(2022, 1, 2, 1)),
|
||||
statRow(tiger, dateH(2022, 1, 2, 1)),
|
||||
statRow(zebra, dateH(2022, 1, 2, 0)),
|
||||
statRow(tiger, dateH(2022, 1, 2, 0)),
|
||||
},
|
||||
},
|
||||
dauWant: []codersdk.DAUEntry{
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 1)),
|
||||
Amount: 2,
|
||||
},
|
||||
},
|
||||
tplWant: want{[]codersdk.DAUEntry{
|
||||
{
|
||||
Date: metricscache.OnlyDate(date(2022, 1, 2)),
|
||||
Amount: 2,
|
||||
},
|
||||
}, 2},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
db = dbmem.New()
|
||||
cache = metricscache.New(db, slogtest.Make(t, nil), metricscache.Intervals{
|
||||
TemplateDAUs: testutil.IntervalFast,
|
||||
})
|
||||
)
|
||||
|
||||
defer cache.Close()
|
||||
|
||||
template := dbgen.Template(t, db, database.Template{
|
||||
Provisioner: database.ProvisionerTypeEcho,
|
||||
})
|
||||
|
||||
for _, row := range tt.args.rows {
|
||||
row.TemplateID = template.ID
|
||||
row.ConnectionCount = 1
|
||||
db.InsertWorkspaceAgentStat(context.Background(), row)
|
||||
}
|
||||
|
||||
require.Eventuallyf(t, func() bool {
|
||||
_, _, ok := cache.TemplateDAUs(template.ID, tt.tzOffset)
|
||||
return ok
|
||||
}, testutil.WaitShort, testutil.IntervalMedium,
|
||||
"TemplateDAUs never populated",
|
||||
)
|
||||
|
||||
gotUniqueUsers, ok := cache.TemplateUniqueUsers(template.ID)
|
||||
require.True(t, ok)
|
||||
|
||||
if tt.dauWant != nil {
|
||||
_, dauResponse, ok := cache.DeploymentDAUs(tt.tzOffset)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, tt.dauWant, dauResponse.Entries)
|
||||
}
|
||||
|
||||
offset, gotEntries, ok := cache.TemplateDAUs(template.ID, tt.tzOffset)
|
||||
require.True(t, ok)
|
||||
// Template only supports 0 offset.
|
||||
require.Equal(t, 0, offset)
|
||||
require.Equal(t, tt.tplWant.entries, gotEntries.Entries)
|
||||
require.Equal(t, tt.tplWant.uniqueUsers, gotUniqueUsers)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_TemplateWorkspaceOwners(t *testing.T) {
|
||||
t.Parallel()
|
||||
var ()
|
||||
@ -261,7 +30,7 @@ func TestCache_TemplateWorkspaceOwners(t *testing.T) {
|
||||
var (
|
||||
db = dbmem.New()
|
||||
cache = metricscache.New(db, slogtest.Make(t, nil), metricscache.Intervals{
|
||||
TemplateDAUs: testutil.IntervalFast,
|
||||
TemplateBuildTimes: testutil.IntervalFast,
|
||||
})
|
||||
)
|
||||
|
||||
@ -412,7 +181,7 @@ func TestCache_BuildTime(t *testing.T) {
|
||||
var (
|
||||
db = dbmem.New()
|
||||
cache = metricscache.New(db, slogtest.Make(t, nil), metricscache.Intervals{
|
||||
TemplateDAUs: testutil.IntervalFast,
|
||||
TemplateBuildTimes: testutil.IntervalFast,
|
||||
})
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user