Skip to content

Commit e1dd559

Browse files
committed
test: Consistent user ordering in dbfake
1 parent 96de7d3 commit e1dd559

File tree

3 files changed

+46
-26
lines changed

3 files changed

+46
-26
lines changed

cli/root_test.go

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"runtime"
1414
"strings"
1515
"testing"
16-
"time"
1716

1817
"github.com/spf13/cobra"
1918
"github.com/stretchr/testify/assert"
@@ -198,32 +197,13 @@ func prepareTestData(t *testing.T) (*codersdk.Client, map[string]string) {
198197
IncludeProvisionerDaemon: true,
199198
})
200199
firstUser := coderdtest.CreateFirstUser(t, rootClient)
201-
202-
firstUserData, err := rootClient.User(ctx, firstUser.UserID.String())
200+
secondUser, err := rootClient.CreateUser(ctx, codersdk.CreateUserRequest{
201+
Email: "testuser2@coder.com",
202+
Username: "testuser2",
203+
Password: coderdtest.FirstUserParams.Password,
204+
OrganizationID: firstUser.OrganizationID,
205+
})
203206
require.NoError(t, err)
204-
205-
var secondUser codersdk.User
206-
for {
207-
secondUser, err = rootClient.CreateUser(ctx, codersdk.CreateUserRequest{
208-
Email: "testuser2@coder.com",
209-
Username: "testuser2",
210-
Password: coderdtest.FirstUserParams.Password,
211-
OrganizationID: firstUser.OrganizationID,
212-
})
213-
require.NoError(t, err)
214-
215-
// If the second user has the same timestamp as the first user, delete it and try again.
216-
// This is because user order is determined by creation time, and we want to ensure
217-
// second user is listed after first user.
218-
// Round to microsecond since that is the precision of the database.
219-
if secondUser.CreatedAt.Round(time.Microsecond).Equal(firstUserData.CreatedAt.Round(time.Microsecond)) {
220-
err = rootClient.DeleteUser(ctx, secondUser.ID)
221-
require.NoError(t, err)
222-
continue
223-
}
224-
break
225-
}
226-
227207
version := coderdtest.CreateTemplateVersion(t, rootClient, firstUser.OrganizationID, nil)
228208
version = coderdtest.AwaitTemplateVersionJob(t, rootClient, version.ID)
229209
template := coderdtest.CreateTemplate(t, rootClient, firstUser.OrganizationID, version.ID, func(req *codersdk.CreateTemplateRequest) {

coderd/database/dbfake/databasefake.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,6 +2922,21 @@ func (q *fakeQuerier) InsertUser(_ context.Context, arg database.InsertUserParam
29222922
return database.User{}, err
29232923
}
29242924

2925+
// There is a common bug when using dbfake that 2 inserted users have the
2926+
// same created_at time. This causes user order to not be deterministic,
2927+
// which breaks some unit tests.
2928+
// To fix this, we make sure that the created_at time is always greater
2929+
// than the last user's created_at time.
2930+
allUsers, _ := q.GetUsers(context.Background(), database.GetUsersParams{})
2931+
if len(allUsers) > 0 {
2932+
lastUser := allUsers[len(allUsers)-1]
2933+
if arg.CreatedAt.Before(lastUser.CreatedAt) ||
2934+
arg.CreatedAt.Equal(lastUser.CreatedAt) {
2935+
// 1 ms is a good enough buffer.
2936+
arg.CreatedAt = lastUser.CreatedAt.Add(time.Millisecond)
2937+
}
2938+
}
2939+
29252940
q.mutex.Lock()
29262941
defer q.mutex.Unlock()
29272942

coderd/database/dbfake/databasefake_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import (
88
"testing"
99
"time"
1010

11+
"github.com/stretchr/testify/require"
12+
13+
"github.com/coder/coder/coderd/database/dbgen"
14+
1115
"github.com/stretchr/testify/assert"
1216

1317
"github.com/coder/coder/coderd/database"
@@ -105,6 +109,27 @@ func TestExactMethods(t *testing.T) {
105109
}
106110
}
107111

112+
// TestUserOrder ensures that the fake database returns users in the order they
113+
// were created.
114+
func TestUserOrder(t *testing.T) {
115+
db := dbfake.New()
116+
now := database.Now()
117+
count := 10
118+
for i := 0; i < count; i++ {
119+
dbgen.User(t, db, database.User{
120+
Username: fmt.Sprintf("user%d", i),
121+
CreatedAt: now,
122+
})
123+
}
124+
125+
users, err := db.GetUsers(context.Background(), database.GetUsersParams{})
126+
require.NoError(t, err)
127+
require.Lenf(t, users, count, "expected %d users", count)
128+
for i, user := range users {
129+
require.Equal(t, fmt.Sprintf("user%d", i), user.Username)
130+
}
131+
}
132+
108133
func methods(rt reflect.Type) map[string]bool {
109134
methods := make(map[string]bool)
110135
for i := 0; i < rt.NumMethod(); i++ {

0 commit comments

Comments
 (0)