Skip to content

Commit 055135a

Browse files
committed
Finish metricscache tests
1 parent c6b087a commit 055135a

File tree

4 files changed

+65
-30
lines changed

4 files changed

+65
-30
lines changed

.vscode/settings.json

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,10 @@
161161
// To reduce redundancy in tests, it's covered by other packages.
162162
// Since package coverage pairing can't be defined, all packages cover
163163
// all other packages.
164-
"go.testFlags": ["-short", "-coverpkg=./..."],
165-
"go.coverageDecorator": {
166-
"type": "gutter",
167-
"coveredHighlightColor": "rgba(64,128,128,0.5)",
168-
"uncoveredHighlightColor": "rgba(128,64,64,0.25)",
169-
"coveredBorderColor": "rgba(64,128,128,0.5)",
170-
"uncoveredBorderColor": "rgba(128,64,64,0.25)",
171-
"coveredGutterStyle": "blockgreen",
172-
"uncoveredGutterStyle": "blockred"
173-
},
164+
"go.testFlags": [
165+
"-short",
166+
"-coverpkg=./..."
167+
],
174168
// We often use a version of TypeScript that's ahead of the version shipped
175169
// with VS Code.
176170
"typescript.tsdk": "./site/node_modules/typescript/lib"

coderd/database/databasefake/databasefake.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func (q *fakeQuerier) GetTemplateDAUs(_ context.Context, templateID uuid.UUID) (
176176
if dateEntry == nil {
177177
dateEntry = make(map[uuid.UUID]struct{})
178178
}
179-
dateEntry[as.ID] = struct{}{}
179+
dateEntry[as.UserID] = struct{}{}
180180
seens[date] = dateEntry
181181
}
182182

coderd/metricscache/metricscache.go

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Cache struct {
2727
log slog.Logger
2828

2929
templateDAUResponses atomic.Pointer[map[uuid.UUID]codersdk.TemplateDAUsResponse]
30+
templateUniqueUsers atomic.Pointer[map[uuid.UUID]int]
3031

3132
doneCh chan struct{}
3233
cancel func()
@@ -107,6 +108,14 @@ func convertDAUResponse(rows []database.GetTemplateDAUsRow) codersdk.TemplateDAU
107108
return resp
108109
}
109110

111+
func countUniqueUsers(rows []database.GetTemplateDAUsRow) int {
112+
seen := make(map[uuid.UUID]struct{}, len(rows))
113+
for _, row := range rows {
114+
seen[row.UserID] = struct{}{}
115+
}
116+
return len(seen)
117+
}
118+
110119
func (c *Cache) refresh(ctx context.Context) error {
111120
err := c.database.DeleteOldAgentStats(ctx)
112121
if err != nil {
@@ -118,17 +127,21 @@ func (c *Cache) refresh(ctx context.Context) error {
118127
return err
119128
}
120129

121-
templateDAUs := make(map[uuid.UUID]codersdk.TemplateDAUsResponse, len(templates))
122-
130+
var (
131+
templateDAUs = make(map[uuid.UUID]codersdk.TemplateDAUsResponse, len(templates))
132+
templateUniqueUsers = make(map[uuid.UUID]int)
133+
)
123134
for _, template := range templates {
124135
rows, err := c.database.GetTemplateDAUs(ctx, template.ID)
125136
if err != nil {
126137
return err
127138
}
128139
templateDAUs[template.ID] = convertDAUResponse(rows)
140+
templateUniqueUsers[template.ID] = countUniqueUsers(rows)
129141
}
130-
131142
c.templateDAUResponses.Store(&templateDAUs)
143+
c.templateUniqueUsers.Store(&templateUniqueUsers)
144+
132145
return nil
133146
}
134147

@@ -190,3 +203,20 @@ func (c *Cache) TemplateDAUs(id uuid.UUID) codersdk.TemplateDAUsResponse {
190203
}
191204
return resp
192205
}
206+
207+
// TemplateUniqueUsers returns the total number of unique users for the template,
208+
// from all the Cache data.
209+
func (c *Cache) TemplateUniqueUsers(id uuid.UUID) (int, bool) {
210+
m := c.templateUniqueUsers.Load()
211+
if m == nil {
212+
// Data loading.
213+
return -1, false
214+
}
215+
216+
resp, ok := (*m)[id]
217+
if !ok {
218+
// Probably no data.
219+
return -1, false
220+
}
221+
return resp, true
222+
}

coderd/metricscache/metricscache_test.go

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package metricscache_test
22

33
import (
44
"context"
5-
"reflect"
65
"testing"
76
"time"
87

@@ -25,19 +24,23 @@ func TestCache(t *testing.T) {
2524
t.Parallel()
2625

2726
var (
28-
zebra = uuid.New()
29-
tiger = uuid.New()
27+
zebra = uuid.UUID{1}
28+
tiger = uuid.UUID{2}
3029
)
3130

3231
type args struct {
3332
rows []database.InsertAgentStatParams
3433
}
34+
type want struct {
35+
entries []codersdk.DAUEntry
36+
uniqueUsers int
37+
}
3538
tests := []struct {
3639
name string
3740
args args
38-
want []codersdk.DAUEntry
41+
want want
3942
}{
40-
{"empty", args{}, nil},
43+
{"empty", args{}, want{nil, 0}},
4144
{"one hole", args{
4245
rows: []database.InsertAgentStatParams{
4346
{
@@ -49,7 +52,7 @@ func TestCache(t *testing.T) {
4952
UserID: zebra,
5053
},
5154
},
52-
}, []codersdk.DAUEntry{
55+
}, want{[]codersdk.DAUEntry{
5356
{
5457
Date: date(2022, 8, 27),
5558
Amount: 1,
@@ -66,7 +69,8 @@ func TestCache(t *testing.T) {
6669
Date: date(2022, 8, 30),
6770
Amount: 1,
6871
},
69-
}},
72+
}, 1},
73+
},
7074
{"no holes", args{
7175
rows: []database.InsertAgentStatParams{
7276
{
@@ -82,7 +86,7 @@ func TestCache(t *testing.T) {
8286
UserID: zebra,
8387
},
8488
},
85-
}, []codersdk.DAUEntry{
89+
}, want{[]codersdk.DAUEntry{
8690
{
8791
Date: date(2022, 8, 27),
8892
Amount: 1,
@@ -95,7 +99,7 @@ func TestCache(t *testing.T) {
9599
Date: date(2022, 8, 29),
96100
Amount: 1,
97101
},
98-
}},
102+
}, 1}},
99103
{"holes", args{
100104
rows: []database.InsertAgentStatParams{
101105
{
@@ -119,7 +123,7 @@ func TestCache(t *testing.T) {
119123
UserID: tiger,
120124
},
121125
},
122-
}, []codersdk.DAUEntry{
126+
}, want{[]codersdk.DAUEntry{
123127
{
124128
Date: date(2022, 1, 1),
125129
Amount: 2,
@@ -148,7 +152,7 @@ func TestCache(t *testing.T) {
148152
Date: date(2022, 1, 7),
149153
Amount: 2,
150154
},
151-
}},
155+
}, 2}},
152156
}
153157

154158
for _, tt := range tests {
@@ -167,19 +171,26 @@ func TestCache(t *testing.T) {
167171
ID: templateID,
168172
})
169173

174+
gotUniqueUsers, ok := cache.TemplateUniqueUsers(templateID)
175+
require.False(t, ok, "template shouldn't have loaded yet")
176+
170177
for _, row := range tt.args.rows {
171178
row.TemplateID = templateID
172179
db.InsertAgentStat(context.Background(), row)
173180
}
174181

175-
var got codersdk.TemplateDAUsResponse
176-
177182
require.Eventuallyf(t, func() bool {
178-
got = cache.TemplateDAUs(templateID)
179-
return reflect.DeepEqual(got.Entries, tt.want)
183+
return len(cache.TemplateDAUs(templateID).Entries) > 0
180184
}, testutil.WaitShort, testutil.IntervalMedium,
181-
"GetDAUs() = %v, want %v", got, tt.want,
185+
"TemplateDAUs never populated",
182186
)
187+
188+
gotUniqueUsers, ok = cache.TemplateUniqueUsers(templateID)
189+
require.True(t, ok)
190+
191+
gotEntries := cache.TemplateDAUs(templateID)
192+
require.Equal(t, tt.want.entries, gotEntries.Entries)
193+
require.Equal(t, tt.want.uniqueUsers, gotUniqueUsers)
183194
})
184195
}
185196
}

0 commit comments

Comments
 (0)