@@ -38,6 +38,7 @@ import (
38
38
"github.com/coder/coder/v2/tailnet"
39
39
"github.com/coder/coder/v2/tailnet/tailnettest"
40
40
"github.com/coder/coder/v2/testutil"
41
+ "github.com/coder/quartz"
41
42
)
42
43
43
44
func TestActiveUsers (t * testing.T ) {
@@ -98,7 +99,7 @@ func TestActiveUsers(t *testing.T) {
98
99
t .Run (tc .Name , func (t * testing.T ) {
99
100
t .Parallel ()
100
101
registry := prometheus .NewRegistry ()
101
- closeFunc , err := prometheusmetrics .ActiveUsers (context .Background (), registry , tc .Database (t ), time .Millisecond )
102
+ closeFunc , err := prometheusmetrics .ActiveUsers (context .Background (), slogtest . Make ( t , nil ), registry , tc .Database (t ), time .Millisecond )
102
103
require .NoError (t , err )
103
104
t .Cleanup (closeFunc )
104
105
@@ -112,6 +113,100 @@ func TestActiveUsers(t *testing.T) {
112
113
}
113
114
}
114
115
116
+ func TestUsers (t * testing.T ) {
117
+ t .Parallel ()
118
+
119
+ for _ , tc := range []struct {
120
+ Name string
121
+ Database func (t * testing.T ) database.Store
122
+ Count map [database.UserStatus ]int
123
+ }{{
124
+ Name : "None" ,
125
+ Database : func (t * testing.T ) database.Store {
126
+ return dbmem .New ()
127
+ },
128
+ Count : map [database.UserStatus ]int {},
129
+ }, {
130
+ Name : "One" ,
131
+ Database : func (t * testing.T ) database.Store {
132
+ db := dbmem .New ()
133
+ dbgen .User (t , db , database.User {Status : database .UserStatusActive })
134
+ return db
135
+ },
136
+ Count : map [database.UserStatus ]int {database .UserStatusActive : 1 },
137
+ }, {
138
+ Name : "MultipleStatuses" ,
139
+ Database : func (t * testing.T ) database.Store {
140
+ db := dbmem .New ()
141
+
142
+ dbgen .User (t , db , database.User {Status : database .UserStatusActive })
143
+ dbgen .User (t , db , database.User {Status : database .UserStatusDormant })
144
+
145
+ return db
146
+ },
147
+ Count : map [database.UserStatus ]int {database .UserStatusActive : 1 , database .UserStatusDormant : 1 },
148
+ }, {
149
+ Name : "MultipleActive" ,
150
+ Database : func (t * testing.T ) database.Store {
151
+ db := dbmem .New ()
152
+ dbgen .User (t , db , database.User {Status : database .UserStatusActive })
153
+ dbgen .User (t , db , database.User {Status : database .UserStatusActive })
154
+ dbgen .User (t , db , database.User {Status : database .UserStatusActive })
155
+ return db
156
+ },
157
+ Count : map [database.UserStatus ]int {database .UserStatusActive : 3 },
158
+ }} {
159
+ tc := tc
160
+ t .Run (tc .Name , func (t * testing.T ) {
161
+ t .Parallel ()
162
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitShort )
163
+ defer cancel ()
164
+
165
+ registry := prometheus .NewRegistry ()
166
+ mClock := quartz .NewMock (t )
167
+ db := tc .Database (t )
168
+ closeFunc , err := prometheusmetrics .Users (context .Background (), slogtest .Make (t , nil ), mClock , registry , db , time .Millisecond )
169
+ require .NoError (t , err )
170
+ t .Cleanup (closeFunc )
171
+
172
+ _ , w := mClock .AdvanceNext ()
173
+ w .MustWait (ctx )
174
+
175
+ checkFn := func () bool {
176
+ metrics , err := registry .Gather ()
177
+ if err != nil {
178
+ return false
179
+ }
180
+
181
+ // If we get no metrics and we know none should exist, bail
182
+ // early. If we get no metrics but we expect some, retry.
183
+ if len (metrics ) == 0 {
184
+ return len (tc .Count ) == 0
185
+ }
186
+
187
+ for _ , metric := range metrics [0 ].Metric {
188
+ if tc .Count [database .UserStatus (* metric .Label [0 ].Value )] != int (metric .Gauge .GetValue ()) {
189
+ return false
190
+ }
191
+ }
192
+
193
+ return true
194
+ }
195
+
196
+ require .Eventually (t , checkFn , testutil .WaitShort , testutil .IntervalFast )
197
+
198
+ // Add another dormant user and ensure it updates
199
+ dbgen .User (t , db , database.User {Status : database .UserStatusDormant })
200
+ tc .Count [database .UserStatusDormant ]++
201
+
202
+ _ , w = mClock .AdvanceNext ()
203
+ w .MustWait (ctx )
204
+
205
+ require .Eventually (t , checkFn , testutil .WaitShort , testutil .IntervalFast )
206
+ })
207
+ }
208
+ }
209
+
115
210
func TestWorkspaceLatestBuildTotals (t * testing.T ) {
116
211
t .Parallel ()
117
212
0 commit comments