Skip to content

Commit 97ef37b

Browse files
committed
add stats collection test to apptest
1 parent 59d69ac commit 97ef37b

File tree

6 files changed

+66
-5
lines changed

6 files changed

+66
-5
lines changed

coderd/coderd.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ type Options struct {
162162

163163
UpdateAgentMetrics func(ctx context.Context, username, workspaceName, agentName string, metrics []agentsdk.AgentMetric)
164164
StatsBatcher *batchstats.Batcher
165+
166+
WorkspaceAppsStatsCollector *workspaceapps.StatsCollector
165167
}
166168

167169
// @title Coder API
@@ -416,8 +418,13 @@ func New(options *Options) *API {
416418
Cache: wsconncache.New(api._dialWorkspaceAgentTailnet, 0),
417419
}
418420
}
419-
420421
workspaceAppsLogger := options.Logger.Named("workspaceapps")
422+
if options.WorkspaceAppsStatsCollector == nil {
423+
options.WorkspaceAppsStatsCollector = workspaceapps.NewStatsCollector(workspaceapps.StatsCollectorOptions{
424+
Logger: workspaceAppsLogger.Named("stats_collector"),
425+
Reporter: workspaceapps.NewStatsDBReporter(options.Database, workspaceapps.DefaultStatsDBReporterBatchSize),
426+
})
427+
}
421428
api.workspaceAppServer = &workspaceapps.Server{
422429
Logger: workspaceAppsLogger,
423430

@@ -430,10 +437,7 @@ func New(options *Options) *API {
430437
SignedTokenProvider: api.WorkspaceAppsProvider,
431438
AgentProvider: api.agentProvider,
432439
AppSecurityKey: options.AppSecurityKey,
433-
StatsCollector: workspaceapps.NewStatsCollector(workspaceapps.StatsCollectorOptions{
434-
Logger: workspaceAppsLogger.Named("stats_collector"),
435-
Reporter: workspaceapps.NewStatsDBReporter(options.Database, workspaceapps.DefaultStatsDBReporterBatchSize),
436-
}),
440+
StatsCollector: options.WorkspaceAppsStatsCollector,
437441

438442
DisablePathApps: options.DeploymentValues.DisablePathApps.Value(),
439443
SecureAuthCookie: options.DeploymentValues.SecureAuthCookie.Value(),

coderd/coderdtest/coderdtest.go

+3
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ type Options struct {
144144
// as part of your test.
145145
Logger *slog.Logger
146146
StatsBatcher *batchstats.Batcher
147+
148+
WorkspaceAppsStatsCollector *workspaceapps.StatsCollector
147149
}
148150

149151
// New constructs a codersdk client connected to an in-memory API instance.
@@ -425,6 +427,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
425427
HealthcheckTimeout: options.HealthcheckTimeout,
426428
HealthcheckRefresh: options.HealthcheckRefresh,
427429
StatsBatcher: options.StatsBatcher,
430+
WorkspaceAppsStatsCollector: options.WorkspaceAppsStatsCollector,
428431
}
429432
}
430433

coderd/workspaceapps/apptest/apptest.go

+48
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"runtime"
1616
"strconv"
1717
"strings"
18+
"sync"
1819
"testing"
1920
"time"
2021

@@ -1406,4 +1407,51 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
14061407
require.Equal(t, []string{"Origin", "X-Foobar"}, deduped)
14071408
require.Equal(t, []string{"baz"}, resp.Header.Values("X-Foobar"))
14081409
})
1410+
1411+
t.Run("ReportStats", func(t *testing.T) {
1412+
t.Parallel()
1413+
1414+
reporter := &fakeStatsReporter{}
1415+
collector := workspaceapps.NewStatsCollector(workspaceapps.StatsCollectorOptions{
1416+
Reporter: reporter,
1417+
ReportInterval: time.Second,
1418+
RollupWindow: time.Minute,
1419+
})
1420+
appDetails := setupProxyTest(t, &DeploymentOptions{
1421+
StatsCollector: collector,
1422+
})
1423+
1424+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
1425+
defer cancel()
1426+
1427+
u := appDetails.PathAppURL(appDetails.Apps.Owner)
1428+
resp, err := requestWithRetries(ctx, t, appDetails.AppClient(t), http.MethodGet, u.String(), nil)
1429+
require.NoError(t, err)
1430+
defer resp.Body.Close()
1431+
_, err = io.Copy(io.Discard, resp.Body)
1432+
require.NoError(t, err)
1433+
require.Equal(t, http.StatusOK, resp.StatusCode)
1434+
1435+
require.Eventually(t, func() bool {
1436+
return len(reporter.stats()) > 0
1437+
}, testutil.WaitLong, testutil.IntervalMedium, "stats not reported")
1438+
})
1439+
}
1440+
1441+
type fakeStatsReporter struct {
1442+
mu sync.Mutex
1443+
s []workspaceapps.StatsReport
1444+
}
1445+
1446+
func (r *fakeStatsReporter) stats() []workspaceapps.StatsReport {
1447+
r.mu.Lock()
1448+
defer r.mu.Unlock()
1449+
return r.s
1450+
}
1451+
1452+
func (r *fakeStatsReporter) Report(_ context.Context, stats []workspaceapps.StatsReport) error {
1453+
r.mu.Lock()
1454+
r.s = append(r.s, stats...)
1455+
r.mu.Unlock()
1456+
return nil
14091457
}

coderd/workspaceapps/apptest/setup.go

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"cdr.dev/slog/sloggers/slogtest"
2222
"github.com/coder/coder/agent"
2323
"github.com/coder/coder/coderd/coderdtest"
24+
"github.com/coder/coder/coderd/workspaceapps"
2425
"github.com/coder/coder/codersdk"
2526
"github.com/coder/coder/codersdk/agentsdk"
2627
"github.com/coder/coder/provisioner/echo"
@@ -51,6 +52,8 @@ type DeploymentOptions struct {
5152
DangerousAllowPathAppSiteOwnerAccess bool
5253
ServeHTTPS bool
5354

55+
StatsCollector *workspaceapps.StatsCollector
56+
5457
// The following fields are only used by setupProxyTestWithFactory.
5558
noWorkspace bool
5659
port uint16

coderd/workspaceapps_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ func TestWorkspaceApps(t *testing.T) {
275275
"CF-Connecting-IP",
276276
},
277277
},
278+
WorkspaceAppsStatsCollector: opts.StatsCollector,
278279
})
279280

280281
user := coderdtest.CreateFirstUser(t, client)

enterprise/wsproxy/wsproxy_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ func TestWorkspaceProxyWorkspaceApps_Wsconncache(t *testing.T) {
596596
"CF-Connecting-IP",
597597
},
598598
},
599+
WorkspaceAppsStatsCollector: opts.StatsCollector,
599600
},
600601
LicenseOptions: &coderdenttest.LicenseOptions{
601602
Features: license.Features{
@@ -654,6 +655,7 @@ func TestWorkspaceProxyWorkspaceApps_SingleTailnet(t *testing.T) {
654655
"CF-Connecting-IP",
655656
},
656657
},
658+
WorkspaceAppsStatsCollector: opts.StatsCollector,
657659
},
658660
LicenseOptions: &coderdenttest.LicenseOptions{
659661
Features: license.Features{

0 commit comments

Comments
 (0)