Skip to content

Commit fafe8e0

Browse files
committed
TestUserActivityInsights
1 parent 6a7d1ce commit fafe8e0

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

coderd/insights_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,102 @@ func TestDeploymentInsights(t *testing.T) {
118118
require.NoError(t, err)
119119
}
120120

121+
func TestUserActivityInsights(t *testing.T) {
122+
t.Parallel()
123+
124+
logger := slogtest.Make(t, nil)
125+
client := coderdtest.New(t, &coderdtest.Options{
126+
IncludeProvisionerDaemon: true,
127+
AgentStatsRefreshInterval: time.Millisecond * 100,
128+
})
129+
130+
// Create two users, one that will appear in the report and another that
131+
// won't (due to not having/using a workspace).
132+
user := coderdtest.CreateFirstUser(t, client)
133+
_, _ = coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
134+
authToken := uuid.NewString()
135+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
136+
Parse: echo.ParseComplete,
137+
ProvisionPlan: echo.PlanComplete,
138+
ProvisionApply: echo.ProvisionApplyWithAgent(authToken),
139+
})
140+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
141+
require.Empty(t, template.BuildTimeStats[codersdk.WorkspaceTransitionStart])
142+
143+
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
144+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
145+
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
146+
147+
// Start an agent so that we can generate stats.
148+
agentClient := agentsdk.New(client.URL)
149+
agentClient.SetSessionToken(authToken)
150+
agentCloser := agent.New(agent.Options{
151+
Logger: logger.Named("agent"),
152+
Client: agentClient,
153+
})
154+
defer func() {
155+
_ = agentCloser.Close()
156+
}()
157+
resources := coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
158+
159+
// Start must be at the beginning of the day, initialize it early in case
160+
// the day changes so that we get the relevant stats faster.
161+
y, m, d := time.Now().UTC().Date()
162+
today := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
163+
164+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
165+
defer cancel()
166+
167+
// Connect to the agent to generate usage/latency stats.
168+
conn, err := client.DialWorkspaceAgent(ctx, resources[0].Agents[0].ID, &codersdk.DialWorkspaceAgentOptions{
169+
Logger: logger.Named("client"),
170+
})
171+
require.NoError(t, err)
172+
defer conn.Close()
173+
174+
sshConn, err := conn.SSHClient(ctx)
175+
require.NoError(t, err)
176+
defer sshConn.Close()
177+
178+
sess, err := sshConn.NewSession()
179+
require.NoError(t, err)
180+
defer sess.Close()
181+
182+
r, w := io.Pipe()
183+
defer r.Close()
184+
defer w.Close()
185+
sess.Stdin = r
186+
sess.Stdout = io.Discard
187+
err = sess.Start("cat")
188+
require.NoError(t, err)
189+
190+
var userActivities codersdk.UserActivityInsightsResponse
191+
require.Eventuallyf(t, func() bool {
192+
// Keep connection active.
193+
_, err := w.Write([]byte("hello world\n"))
194+
if !assert.NoError(t, err) {
195+
return false
196+
}
197+
userActivities, err = client.UserActivityInsights(ctx, codersdk.UserActivityInsightsRequest{
198+
StartTime: today,
199+
EndTime: time.Now().UTC().Truncate(time.Hour).Add(time.Hour), // Round up to include the current hour.
200+
TemplateIDs: []uuid.UUID{template.ID},
201+
})
202+
if !assert.NoError(t, err) {
203+
return false
204+
}
205+
return len(userActivities.Report.Users) > 0 && userActivities.Report.Users[0].Seconds > 0
206+
}, testutil.WaitMedium, testutil.IntervalFast, "user activity is missing")
207+
208+
// We got our latency data, close the connection.
209+
_ = sess.Close()
210+
_ = sshConn.Close()
211+
212+
require.Len(t, userActivities.Report.Users, 1, "want only 1 user")
213+
require.Equal(t, userActivities.Report.Users[0].UserID, user.UserID, "want user id to match")
214+
assert.Greater(t, userActivities.Report.Users[0].Seconds, int64(0), "want usage in seconds to be greater than 0")
215+
}
216+
121217
func TestUserLatencyInsights(t *testing.T) {
122218
t.Parallel()
123219

0 commit comments

Comments
 (0)