Skip to content

Commit 1113d8f

Browse files
committed
Move generate functions and no more generics
1 parent bc88e41 commit 1113d8f

File tree

3 files changed

+272
-0
lines changed

3 files changed

+272
-0
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
package fakegen
2+
3+
import (
4+
"context"
5+
"crypto/sha256"
6+
"database/sql"
7+
"encoding/hex"
8+
"testing"
9+
"time"
10+
11+
"github.com/coder/coder/cryptorand"
12+
"github.com/tabbed/pqtype"
13+
14+
"github.com/coder/coder/coderd/database"
15+
"github.com/google/uuid"
16+
"github.com/moby/moby/pkg/namesgenerator"
17+
"github.com/stretchr/testify/require"
18+
)
19+
20+
func Template(t *testing.T, db database.Store, seed database.Template) database.Template {
21+
template, err := db.InsertTemplate(context.Background(), database.InsertTemplateParams{
22+
ID: takeFirst(seed.ID, uuid.New()),
23+
CreatedAt: takeFirst(seed.CreatedAt, time.Now()),
24+
UpdatedAt: takeFirst(seed.UpdatedAt, time.Now()),
25+
OrganizationID: takeFirst(seed.OrganizationID, uuid.New()),
26+
Name: takeFirst(seed.Name, namesgenerator.GetRandomName(1)),
27+
Provisioner: takeFirst(seed.Provisioner, database.ProvisionerTypeEcho),
28+
ActiveVersionID: takeFirst(seed.ActiveVersionID, uuid.New()),
29+
Description: takeFirst(seed.Description, namesgenerator.GetRandomName(1)),
30+
DefaultTTL: takeFirst(seed.DefaultTTL, 3600),
31+
CreatedBy: takeFirst(seed.CreatedBy, uuid.New()),
32+
Icon: takeFirst(seed.Icon, namesgenerator.GetRandomName(1)),
33+
UserACL: seed.UserACL,
34+
GroupACL: seed.GroupACL,
35+
DisplayName: takeFirst(seed.DisplayName, namesgenerator.GetRandomName(1)),
36+
AllowUserCancelWorkspaceJobs: takeFirst(seed.AllowUserCancelWorkspaceJobs, true),
37+
})
38+
require.NoError(t, err, "insert template")
39+
return template
40+
}
41+
42+
func APIKey(t *testing.T, db database.Store, seed database.APIKey) (key database.APIKey, secret string) {
43+
id, _ := cryptorand.String(10)
44+
secret, _ = cryptorand.String(22)
45+
hashed := sha256.Sum256([]byte(secret))
46+
47+
key, err := db.InsertAPIKey(context.Background(), database.InsertAPIKeyParams{
48+
ID: takeFirst(seed.ID, id),
49+
// 0 defaults to 86400 at the db layer
50+
LifetimeSeconds: takeFirst(seed.LifetimeSeconds, 0),
51+
HashedSecret: takeFirstBytes(seed.HashedSecret, hashed[:]),
52+
IPAddress: pqtype.Inet{},
53+
UserID: takeFirst(seed.UserID, uuid.New()),
54+
LastUsed: takeFirst(seed.LastUsed, time.Now()),
55+
ExpiresAt: takeFirst(seed.ExpiresAt, time.Now().Add(time.Hour)),
56+
CreatedAt: takeFirst(seed.CreatedAt, time.Now()),
57+
UpdatedAt: takeFirst(seed.UpdatedAt, time.Now()),
58+
LoginType: takeFirst(seed.LoginType, database.LoginTypePassword),
59+
Scope: takeFirst(seed.Scope, database.APIKeyScopeAll),
60+
})
61+
require.NoError(t, err, "insert api key")
62+
return key, secret
63+
}
64+
65+
func Workspace(t *testing.T, db database.Store, orig database.Workspace) database.Workspace {
66+
workspace, err := db.InsertWorkspace(context.Background(), database.InsertWorkspaceParams{
67+
ID: takeFirst(orig.ID, uuid.New()),
68+
OwnerID: takeFirst(orig.OwnerID, uuid.New()),
69+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
70+
UpdatedAt: takeFirst(orig.UpdatedAt, time.Now()),
71+
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
72+
TemplateID: takeFirst(orig.TemplateID, uuid.New()),
73+
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
74+
AutostartSchedule: orig.AutostartSchedule,
75+
Ttl: orig.Ttl,
76+
})
77+
require.NoError(t, err, "insert workspace")
78+
return workspace
79+
}
80+
81+
func WorkspaceBuild(t *testing.T, db database.Store, orig database.WorkspaceBuild) database.WorkspaceBuild {
82+
build, err := db.InsertWorkspaceBuild(context.Background(), database.InsertWorkspaceBuildParams{
83+
ID: takeFirst(orig.ID, uuid.New()),
84+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
85+
UpdatedAt: takeFirst(orig.UpdatedAt, time.Now()),
86+
WorkspaceID: takeFirst(orig.WorkspaceID, uuid.New()),
87+
TemplateVersionID: takeFirst(orig.TemplateVersionID, uuid.New()),
88+
BuildNumber: takeFirst(orig.BuildNumber, 0),
89+
Transition: takeFirst(orig.Transition, database.WorkspaceTransitionStart),
90+
InitiatorID: takeFirst(orig.InitiatorID, uuid.New()),
91+
JobID: takeFirst(orig.JobID, uuid.New()),
92+
ProvisionerState: takeFirstBytes(orig.ProvisionerState, []byte{}),
93+
Deadline: takeFirst(orig.Deadline, time.Now().Add(time.Hour)),
94+
Reason: takeFirst(orig.Reason, database.BuildReasonInitiator),
95+
})
96+
require.NoError(t, err, "insert workspace build")
97+
return build
98+
}
99+
100+
func User(t *testing.T, db database.Store, orig database.User) database.User {
101+
user, err := db.InsertUser(context.Background(), database.InsertUserParams{
102+
ID: takeFirst(orig.ID, uuid.New()),
103+
Email: takeFirst(orig.Email, namesgenerator.GetRandomName(1)),
104+
Username: takeFirst(orig.Username, namesgenerator.GetRandomName(1)),
105+
HashedPassword: takeFirstBytes(orig.HashedPassword, []byte{}),
106+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
107+
UpdatedAt: takeFirst(orig.UpdatedAt, time.Now()),
108+
RBACRoles: []string{},
109+
LoginType: takeFirst(orig.LoginType, database.LoginTypePassword),
110+
})
111+
require.NoError(t, err, "insert user")
112+
return user
113+
}
114+
115+
func Organization(t *testing.T, db database.Store, ctx context.Context, orig database.Organization) database.Organization {
116+
org, err := db.InsertOrganization(context.Background(), database.InsertOrganizationParams{
117+
ID: takeFirst(orig.ID, uuid.New()),
118+
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
119+
Description: takeFirst(orig.Description, namesgenerator.GetRandomName(1)),
120+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
121+
UpdatedAt: takeFirst(orig.UpdatedAt, time.Now()),
122+
})
123+
require.NoError(t, err, "insert organization")
124+
return org
125+
}
126+
127+
func Group(t *testing.T, db database.Store, ctx context.Context, orig database.Group) database.Group {
128+
group, err := db.InsertGroup(context.Background(), database.InsertGroupParams{
129+
ID: takeFirst(orig.ID, uuid.New()),
130+
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
131+
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
132+
AvatarURL: takeFirst(orig.AvatarURL, "https://logo.example.com"),
133+
QuotaAllowance: takeFirst(orig.QuotaAllowance, 0),
134+
})
135+
require.NoError(t, err, "insert group")
136+
return group
137+
}
138+
139+
func ProvisionerJob(t *testing.T, db database.Store, ctx context.Context, orig database.ProvisionerJob) database.ProvisionerJob {
140+
job, err := db.InsertProvisionerJob(context.Background(), database.InsertProvisionerJobParams{
141+
ID: takeFirst(orig.ID, uuid.New()),
142+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
143+
UpdatedAt: takeFirst(orig.UpdatedAt, time.Now()),
144+
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
145+
InitiatorID: takeFirst(orig.InitiatorID, uuid.New()),
146+
Provisioner: takeFirst(orig.Provisioner, database.ProvisionerTypeEcho),
147+
StorageMethod: takeFirst(orig.StorageMethod, database.ProvisionerStorageMethodFile),
148+
FileID: takeFirst(orig.FileID, uuid.New()),
149+
Type: takeFirst(orig.Type, database.ProvisionerJobTypeWorkspaceBuild),
150+
Input: takeFirstBytes(orig.Input, []byte("{}")),
151+
Tags: orig.Tags,
152+
})
153+
require.NoError(t, err, "insert job")
154+
return job
155+
}
156+
157+
func WorkspaceResource(t *testing.T, db database.Store, ctx context.Context, orig database.WorkspaceResource) database.WorkspaceResource {
158+
resource, err := db.InsertWorkspaceResource(context.Background(), database.InsertWorkspaceResourceParams{
159+
ID: takeFirst(orig.ID, uuid.New()),
160+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
161+
JobID: takeFirst(orig.JobID, uuid.New()),
162+
Transition: takeFirst(orig.Transition, database.WorkspaceTransitionStart),
163+
Type: takeFirst(orig.Type, "fake_resource"),
164+
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
165+
Hide: takeFirst(orig.Hide, false),
166+
Icon: takeFirst(orig.Icon, ""),
167+
InstanceType: sql.NullString{
168+
String: takeFirst(orig.InstanceType.String, ""),
169+
Valid: takeFirst(orig.InstanceType.Valid, false),
170+
},
171+
DailyCost: takeFirst(orig.DailyCost, 0),
172+
})
173+
require.NoError(t, err, "insert resource")
174+
return resource
175+
}
176+
177+
func File(t *testing.T, db database.Store, ctx context.Context, orig database.File) database.File {
178+
file, err := db.InsertFile(context.Background(), database.InsertFileParams{
179+
ID: takeFirst(orig.ID, uuid.New()),
180+
Hash: takeFirst(orig.Hash, hex.EncodeToString(make([]byte, 32))),
181+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
182+
CreatedBy: takeFirst(orig.CreatedBy, uuid.New()),
183+
Mimetype: takeFirst(orig.Mimetype, "application/x-tar"),
184+
Data: takeFirstBytes(orig.Data, []byte{}),
185+
})
186+
require.NoError(t, err, "insert file")
187+
return file
188+
}
189+
190+
func UserLink(t *testing.T, db database.Store, ctx context.Context, orig database.UserLink) database.UserLink {
191+
link, err := db.InsertUserLink(context.Background(), database.InsertUserLinkParams{
192+
UserID: takeFirst(orig.UserID, uuid.New()),
193+
LoginType: takeFirst(orig.LoginType, database.LoginTypeGithub),
194+
LinkedID: takeFirst(orig.LinkedID),
195+
OAuthAccessToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()),
196+
OAuthRefreshToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()),
197+
OAuthExpiry: takeFirst(orig.OAuthExpiry, time.Now().Add(time.Hour*24)),
198+
})
199+
200+
require.NoError(t, err, "insert link")
201+
return link
202+
}
203+
204+
func TemplateVersion(t *testing.T, db database.Store, orig database.TemplateVersion) database.TemplateVersion {
205+
version, err := db.InsertTemplateVersion(context.Background(), database.InsertTemplateVersionParams{
206+
ID: takeFirst(orig.ID, uuid.New()),
207+
TemplateID: uuid.NullUUID{
208+
UUID: takeFirst(orig.TemplateID.UUID, uuid.New()),
209+
Valid: takeFirst(orig.TemplateID.Valid, true),
210+
},
211+
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
212+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
213+
UpdatedAt: takeFirst(orig.UpdatedAt, time.Now()),
214+
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
215+
Readme: takeFirst(orig.Readme, namesgenerator.GetRandomName(1)),
216+
JobID: takeFirst(orig.JobID, uuid.New()),
217+
CreatedBy: takeFirst(orig.CreatedBy, uuid.New()),
218+
})
219+
require.NoError(t, err, "insert template version")
220+
return version
221+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package fakegen
2+
3+
// takeFirstBytes implements takeFirst for []byte.
4+
// []byte is not a comparable type.
5+
func takeFirstBytes(values ...[]byte) []byte {
6+
return takeFirstF(values, func(v []byte) bool {
7+
return len(v) != 0
8+
})
9+
}
10+
11+
// takeFirstF takes the first value that returns true
12+
func takeFirstF[Value any](values []Value, take func(v Value) bool) Value {
13+
var empty Value
14+
for _, v := range values {
15+
if take(v) {
16+
return v
17+
}
18+
}
19+
// If all empty, return empty
20+
return empty
21+
}
22+
23+
// takeFirst will take the first non-empty value.
24+
func takeFirst[Value comparable](values ...Value) Value {
25+
var empty Value
26+
return takeFirstF(values, func(v Value) bool {
27+
return v != empty
28+
})
29+
}

coderd/database/databasefake/generator.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,28 @@ func Generate[Object Supported](t *testing.T, db database.Store, seed Object) Ob
6060
return v
6161
}
6262

63+
func Template(t *testing.T, db database.Store, seed database.Template) database.Template {
64+
template, err := db.InsertTemplate(context.Background(), database.InsertTemplateParams{
65+
ID: takeFirst(seed.ID, uuid.New()),
66+
CreatedAt: takeFirst(seed.CreatedAt, time.Now()),
67+
UpdatedAt: takeFirst(seed.UpdatedAt, time.Now()),
68+
OrganizationID: takeFirst(seed.OrganizationID, uuid.New()),
69+
Name: takeFirst(seed.Name, namesgenerator.GetRandomName(1)),
70+
Provisioner: takeFirst(seed.Provisioner, database.ProvisionerTypeEcho),
71+
ActiveVersionID: takeFirst(seed.ActiveVersionID, uuid.New()),
72+
Description: takeFirst(seed.Description, namesgenerator.GetRandomName(1)),
73+
DefaultTTL: takeFirst(seed.DefaultTTL, 3600),
74+
CreatedBy: takeFirst(seed.CreatedBy, uuid.New()),
75+
Icon: takeFirst(seed.Icon, namesgenerator.GetRandomName(1)),
76+
UserACL: seed.UserACL,
77+
GroupACL: seed.GroupACL,
78+
DisplayName: takeFirst(seed.DisplayName, namesgenerator.GetRandomName(1)),
79+
AllowUserCancelWorkspaceJobs: takeFirst(seed.AllowUserCancelWorkspaceJobs, true),
80+
})
81+
require.NoError(t, err, "insert template")
82+
return template
83+
}
84+
6385
func generate(t *testing.T, db database.Store, seed interface{}) interface{} {
6486
t.Helper()
6587

0 commit comments

Comments
 (0)