Skip to content

Commit e145b74

Browse files
committed
Write unit test for job
1 parent f9ae3c9 commit e145b74

File tree

2 files changed

+93
-4
lines changed

2 files changed

+93
-4
lines changed

coderd/dormancy/dormantusersjob.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@ import (
1313
)
1414

1515
const (
16-
checkDuration = 5 * time.Minute
17-
dormancyPeriod = 90 * 24 * time.Hour
16+
jobInterval = 5 * time.Minute
17+
accountDormancyPeriod = 90 * 24 * time.Hour
1818
)
1919

2020
func CheckInactiveUsers(ctx context.Context, logger slog.Logger, db database.Store) func() {
21+
return CheckInactiveUsersWithOptions(ctx, logger, db, jobInterval, accountDormancyPeriod)
22+
}
23+
24+
func CheckInactiveUsersWithOptions(ctx context.Context, logger slog.Logger, db database.Store, checkInterval, dormancyPeriod time.Duration) func() {
2125
logger = logger.Named("dormancy")
2226

2327
ctx, cancelFunc := context.WithCancel(ctx)
2428
done := make(chan struct{})
25-
ticker := time.NewTicker(checkDuration)
29+
ticker := time.NewTicker(checkInterval)
2630
go func() {
2731
defer close(done)
2832
defer ticker.Stop()
Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,92 @@
11
package dormancy_test
22

3-
import "testing"
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/google/uuid"
9+
"github.com/moby/moby/pkg/namesgenerator"
10+
"github.com/stretchr/testify/require"
11+
12+
"cdr.dev/slog/sloggers/slogtest"
13+
14+
"github.com/coder/coder/coderd/database"
15+
"github.com/coder/coder/coderd/database/dbfake"
16+
"github.com/coder/coder/coderd/dormancy"
17+
"github.com/coder/coder/testutil"
18+
)
419

520
func TestCheckInactiveUsers(t *testing.T) {
21+
t.Parallel()
22+
23+
// Predefine job settings
24+
interval := time.Millisecond
25+
dormancyPeriod := 90 * 24 * time.Hour
26+
27+
// Add some dormant accounts
28+
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true})
29+
db := dbfake.New()
30+
31+
ctx, cancelFunc := context.WithCancel(context.Background())
32+
t.Cleanup(cancelFunc)
33+
34+
inactiveUser1 := setupUser(ctx, t, db, "dormant-user-1@coder.com", time.Now().Add(-dormancyPeriod).Add(-time.Minute))
35+
inactiveUser2 := setupUser(ctx, t, db, "dormant-user-2@coder.com", time.Now().Add(-dormancyPeriod).Add(-time.Hour))
36+
inactiveUser3 := setupUser(ctx, t, db, "dormant-user-3@coder.com", time.Now().Add(-dormancyPeriod).Add(-6*time.Hour))
37+
38+
activeUser1 := setupUser(ctx, t, db, "active-user-1@coder.com", time.Now().Add(-dormancyPeriod).Add(time.Minute))
39+
activeUser2 := setupUser(ctx, t, db, "active-user-2@coder.com", time.Now().Add(-dormancyPeriod).Add(time.Hour))
40+
activeUser3 := setupUser(ctx, t, db, "active-user-3@coder.com", time.Now().Add(-dormancyPeriod).Add(6*time.Hour))
41+
42+
// Run the periodic job
43+
closeFunc := dormancy.CheckInactiveUsersWithOptions(ctx, logger, db, interval, dormancyPeriod)
44+
t.Cleanup(closeFunc)
45+
46+
var rows []database.GetUsersRow
47+
var err error
48+
require.Eventually(t, func() bool {
49+
rows, err = db.GetUsers(ctx, database.GetUsersParams{})
50+
if err != nil {
51+
return false
52+
}
53+
54+
var c int
55+
for _, row := range rows {
56+
if row.Status == database.UserStatusDormant {
57+
c++
58+
}
59+
}
60+
// 6 users in total, 3 dormant
61+
return len(rows) == 6 && c == 3
62+
}, testutil.WaitShort, testutil.IntervalMedium)
63+
64+
allUsers := database.ConvertUserRows(rows)
65+
66+
// Verify user status
67+
expectedUsers := []database.User{
68+
asDormant(inactiveUser1),
69+
asDormant(inactiveUser2),
70+
asDormant(inactiveUser3),
71+
activeUser1,
72+
activeUser2,
73+
activeUser3,
74+
}
75+
require.ElementsMatch(t, allUsers, expectedUsers)
76+
}
77+
78+
func setupUser(ctx context.Context, t *testing.T, db database.Store, email string, lastSeenAt time.Time) database.User {
79+
user, err := db.InsertUser(ctx, database.InsertUserParams{ID: uuid.New(), LoginType: database.LoginTypePassword, Username: namesgenerator.GetRandomName(8), Email: email})
80+
require.NoError(t, err)
81+
// At the beginning of the test all users are marked as active
82+
user, err = db.UpdateUserStatus(ctx, database.UpdateUserStatusParams{ID: user.ID, Status: database.UserStatusActive})
83+
require.NoError(t, err)
84+
user, err = db.UpdateUserLastSeenAt(ctx, database.UpdateUserLastSeenAtParams{ID: user.ID, LastSeenAt: lastSeenAt})
85+
require.NoError(t, err)
86+
return user
87+
}
688

89+
func asDormant(user database.User) database.User {
90+
user.Status = database.UserStatusDormant
91+
return user
792
}

0 commit comments

Comments
 (0)