Skip to content

Commit 7e3ff5b

Browse files
authored
chore: fix TestBatchStats flake (#8952)
1 parent 758c368 commit 7e3ff5b

File tree

3 files changed

+20
-19
lines changed

3 files changed

+20
-19
lines changed

coderd/batchstats/batcher.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ func New(ctx context.Context, opts ...Option) (*Batcher, func(), error) {
125125

126126
// Add adds a stat to the batcher for the given workspace and agent.
127127
func (b *Batcher) Add(
128+
now time.Time,
128129
agentID uuid.UUID,
129130
templateID uuid.UUID,
130131
userID uuid.UUID,
@@ -134,7 +135,7 @@ func (b *Batcher) Add(
134135
b.mu.Lock()
135136
defer b.mu.Unlock()
136137

137-
now := database.Now()
138+
now = database.Time(now)
138139

139140
b.buf.ID = append(b.buf.ID, uuid.New())
140141
b.buf.CreatedAt = append(b.buf.CreatedAt, now)
@@ -198,15 +199,6 @@ func (b *Batcher) flush(ctx context.Context, forced bool, reason string) {
198199
defer func() {
199200
b.flushForced.Store(false)
200201
b.mu.Unlock()
201-
// Notify that a flush has completed. This only happens in tests.
202-
if b.flushed != nil {
203-
select {
204-
case <-ctx.Done():
205-
close(b.flushed)
206-
default:
207-
b.flushed <- count
208-
}
209-
}
210202
if count > 0 {
211203
elapsed := time.Since(start)
212204
b.log.Debug(ctx, "flush complete",
@@ -216,6 +208,15 @@ func (b *Batcher) flush(ctx context.Context, forced bool, reason string) {
216208
slog.F("reason", reason),
217209
)
218210
}
211+
// Notify that a flush has completed. This only happens in tests.
212+
if b.flushed != nil {
213+
select {
214+
case <-ctx.Done():
215+
close(b.flushed)
216+
default:
217+
b.flushed <- count
218+
}
219+
}
219220
}()
220221

221222
if len(b.buf.ID) == 0 {

coderd/batchstats/batcher_internal_test.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestBatchStats(t *testing.T) {
4646

4747
// Given: no data points are added for workspace
4848
// When: it becomes time to report stats
49-
t1 := time.Now()
49+
t1 := database.Now()
5050
// Signal a tick and wait for a flush to complete.
5151
tick <- t1
5252
f := <-flushed
@@ -59,9 +59,9 @@ func TestBatchStats(t *testing.T) {
5959
require.Empty(t, stats, "should have no stats for workspace")
6060

6161
// Given: a single data point is added for workspace
62-
t2 := time.Now()
62+
t2 := t1.Add(time.Second)
6363
t.Logf("inserting 1 stat")
64-
require.NoError(t, b.Add(deps1.Agent.ID, deps1.User.ID, deps1.Template.ID, deps1.Workspace.ID, randAgentSDKStats(t)))
64+
require.NoError(t, b.Add(t2.Add(time.Millisecond), deps1.Agent.ID, deps1.User.ID, deps1.Template.ID, deps1.Workspace.ID, randAgentSDKStats(t)))
6565

6666
// When: it becomes time to report stats
6767
// Signal a tick and wait for a flush to complete.
@@ -77,17 +77,17 @@ func TestBatchStats(t *testing.T) {
7777

7878
// Given: a lot of data points are added for both workspaces
7979
// (equal to batch size)
80-
t3 := time.Now()
80+
t3 := t2.Add(time.Second)
8181
done := make(chan struct{})
8282

8383
go func() {
8484
defer close(done)
8585
t.Logf("inserting %d stats", defaultBufferSize)
8686
for i := 0; i < defaultBufferSize; i++ {
8787
if i%2 == 0 {
88-
require.NoError(t, b.Add(deps1.Agent.ID, deps1.User.ID, deps1.Template.ID, deps1.Workspace.ID, randAgentSDKStats(t)))
88+
require.NoError(t, b.Add(t3.Add(time.Millisecond), deps1.Agent.ID, deps1.User.ID, deps1.Template.ID, deps1.Workspace.ID, randAgentSDKStats(t)))
8989
} else {
90-
require.NoError(t, b.Add(deps2.Agent.ID, deps2.User.ID, deps2.Template.ID, deps2.Workspace.ID, randAgentSDKStats(t)))
90+
require.NoError(t, b.Add(t3.Add(time.Millisecond), deps2.Agent.ID, deps2.User.ID, deps2.Template.ID, deps2.Workspace.ID, randAgentSDKStats(t)))
9191
}
9292
}
9393
}()
@@ -105,15 +105,15 @@ func TestBatchStats(t *testing.T) {
105105
require.Len(t, stats, 2, "should have stats for both workspaces")
106106

107107
// Ensures that a subsequent flush pushes all the remaining data
108-
t4 := time.Now()
108+
t4 := t3.Add(time.Second)
109109
tick <- t4
110110
f2 := <-flushed
111111
t.Logf("flush 4 completed")
112112
expectedCount := defaultBufferSize - f
113113
require.Equal(t, expectedCount, f2, "did not flush expected remaining rows")
114114

115115
// Ensure that a subsequent flush does not push stale data.
116-
t5 := time.Now()
116+
t5 := t4.Add(time.Second)
117117
tick <- t5
118118
f = <-flushed
119119
require.Zero(t, f, "expected zero stats to have been flushed")

coderd/workspaceagents.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ func (api *API) workspaceAgentReportStats(rw http.ResponseWriter, r *http.Reques
14141414

14151415
var errGroup errgroup.Group
14161416
errGroup.Go(func() error {
1417-
if err := api.statsBatcher.Add(workspaceAgent.ID, workspace.TemplateID, workspace.OwnerID, workspace.ID, req); err != nil {
1417+
if err := api.statsBatcher.Add(time.Now(), workspaceAgent.ID, workspace.TemplateID, workspace.OwnerID, workspace.ID, req); err != nil {
14181418
api.Logger.Error(ctx, "failed to add stats to batcher", slog.Error(err))
14191419
return xerrors.Errorf("can't insert workspace agent stat: %w", err)
14201420
}

0 commit comments

Comments
 (0)