Skip to content

Commit 8015701

Browse files
committed
Add durable profile acceptance fixtures
1 parent 84d2e8f commit 8015701

4 files changed

Lines changed: 193 additions & 0 deletions

File tree

internal/acctest/acctest.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,48 @@ func cleanupExtension(t testing.TB, client extensionCleaner, projectID, id strin
201201
})
202202
}
203203

204+
// CleanupProfile registers a cleanup that deletes the profile from projectID;
205+
// empty means the env-configured default project.
206+
func CleanupProfile(t testing.TB, projectID, id string) {
207+
t.Helper()
208+
209+
cleanupProfile(t, ClientFromEnv(), projectID, id)
210+
}
211+
212+
type profileCleaner interface {
213+
DefaultProjectID() string
214+
DeleteProfile(context.Context, string, string) error
215+
}
216+
217+
func cleanupProfile(t testing.TB, client profileCleaner, projectID, id string) {
218+
t.Helper()
219+
220+
if id == "" {
221+
return
222+
}
223+
if !AcceptanceEnabled() {
224+
t.Fatalf("%s must be set to clean up Kernel acceptance test resources", EnvAcceptance)
225+
return
226+
}
227+
if os.Getenv(EnvAPIKey) == "" {
228+
t.Fatalf("%s must be set to clean up Kernel acceptance test resources", EnvAPIKey)
229+
return
230+
}
231+
232+
if projectID == "" {
233+
projectID = client.DefaultProjectID()
234+
}
235+
236+
t.Cleanup(func() {
237+
ctx, cancel := context.WithTimeout(context.Background(), cleanupTimeout)
238+
defer cancel()
239+
240+
if err := client.DeleteProfile(ctx, projectID, id); err != nil && !IsNotFound(err) {
241+
t.Errorf("cleanup Kernel profile %s: %v", id, err)
242+
}
243+
})
244+
}
245+
204246
func ClientFromEnv() kernelclient.Clients {
205247
return kernelclient.New(kernelclient.Config{
206248
APIKey: os.Getenv(EnvAPIKey),

internal/acctest/profile_test.go

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package acctest
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
)
8+
9+
type fakeProfileCleaner struct {
10+
defaultProjectID string
11+
delete func(context.Context, string, string) error
12+
}
13+
14+
func (f fakeProfileCleaner) DefaultProjectID() string {
15+
return f.defaultProjectID
16+
}
17+
18+
func (f fakeProfileCleaner) DeleteProfile(ctx context.Context, projectID, id string) error {
19+
return f.delete(ctx, projectID, id)
20+
}
21+
22+
func TestCleanupProfile(t *testing.T) {
23+
tests := map[string]struct {
24+
acceptance string
25+
apiKey string
26+
projectID string
27+
defaultProject string
28+
id string
29+
deleteErr error
30+
wantProjectID string
31+
wantCleanups int
32+
wantDelete bool
33+
wantFailure bool
34+
}{
35+
"empty ID is ignored": {},
36+
"acceptance disabled": {
37+
apiKey: "test-key",
38+
id: "profile_123",
39+
wantFailure: true,
40+
},
41+
"API key missing": {
42+
acceptance: "1",
43+
id: "profile_123",
44+
wantFailure: true,
45+
},
46+
"default project is resolved": {
47+
acceptance: "1",
48+
apiKey: "test-key",
49+
defaultProject: "project_default",
50+
id: "profile_123",
51+
wantProjectID: "project_default",
52+
wantCleanups: 1,
53+
wantDelete: true,
54+
},
55+
"not found is already clean": {
56+
acceptance: "1",
57+
apiKey: "test-key",
58+
projectID: "project_explicit",
59+
id: "profile_123",
60+
deleteErr: notFoundAPIError(),
61+
wantProjectID: "project_explicit",
62+
wantCleanups: 1,
63+
wantDelete: true,
64+
},
65+
"delete error is reported": {
66+
acceptance: "1",
67+
apiKey: "test-key",
68+
projectID: "project_explicit",
69+
id: "profile_123",
70+
deleteErr: errors.New("connection reset"),
71+
wantProjectID: "project_explicit",
72+
wantCleanups: 1,
73+
wantDelete: true,
74+
wantFailure: true,
75+
},
76+
}
77+
78+
for name, test := range tests {
79+
t.Run(name, func(t *testing.T) {
80+
t.Setenv(EnvAcceptance, test.acceptance)
81+
t.Setenv(EnvAPIKey, test.apiKey)
82+
83+
var gotID, gotProjectID string
84+
deleteCalled := false
85+
deadlineSet := false
86+
recorder := &testRecorder{TB: t}
87+
cleanupProfile(recorder, fakeProfileCleaner{
88+
defaultProjectID: test.defaultProject,
89+
delete: func(ctx context.Context, projectID, id string) error {
90+
deleteCalled = true
91+
_, deadlineSet = ctx.Deadline()
92+
gotProjectID = projectID
93+
gotID = id
94+
return test.deleteErr
95+
},
96+
}, test.projectID, test.id)
97+
98+
if got, want := len(recorder.cleanups), test.wantCleanups; got != want {
99+
t.Fatalf("cleanupProfile registered %d cleanups, want %d", got, want)
100+
}
101+
if test.wantCleanups == 1 {
102+
recorder.cleanups[0]()
103+
}
104+
if recorder.failed != test.wantFailure {
105+
t.Fatalf("cleanupProfile failure = %t, want %t", recorder.failed, test.wantFailure)
106+
}
107+
if deleteCalled != test.wantDelete {
108+
t.Fatalf("cleanupProfile called delete = %t, want %t", deleteCalled, test.wantDelete)
109+
}
110+
if deleteCalled && !deadlineSet {
111+
t.Fatal("cleanupProfile called delete without a context deadline")
112+
}
113+
if test.wantDelete && (gotID != test.id || gotProjectID != test.wantProjectID) {
114+
t.Fatalf("cleanup profile scope/id = %q/%q, want %q/%q", gotProjectID, gotID, test.wantProjectID, test.id)
115+
}
116+
})
117+
}
118+
}

internal/kernelclient/client.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,14 @@ func (c Clients) GetProfile(ctx context.Context, projectID, idOrName string) (*k
168168
return c.profiles.Get(ctx, idOrName, scope(projectID)...)
169169
}
170170

171+
func (c Clients) CreateProfile(ctx context.Context, projectID string, params kernel.ProfileNewParams) (*kernel.Profile, error) {
172+
return c.profiles.New(ctx, params, scope(projectID, noMutationRetries())...)
173+
}
174+
175+
func (c Clients) DeleteProfile(ctx context.Context, projectID, idOrName string) error {
176+
return c.profiles.Delete(ctx, idOrName, scope(projectID, noMutationRetries())...)
177+
}
178+
171179
func (c Clients) ListProfilePage(ctx context.Context, projectID, query string, offset int64) (ProfilePage, error) {
172180
var raw *http.Response
173181
params := kernel.ProfileListParams{

internal/kernelclient/client_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,23 @@ func TestMutationsDisableSDKRetriesAndUseExpectedScope(t *testing.T) {
387387
return clients.DeleteProject(ctx, "project_123")
388388
},
389389
},
390+
"profile create": {
391+
method: http.MethodPost,
392+
path: "/profiles",
393+
projectID: "project_123",
394+
call: func(ctx context.Context, clients Clients) error {
395+
_, err := clients.CreateProfile(ctx, "project_123", kernel.ProfileNewParams{Name: kernel.String("Profile")})
396+
return err
397+
},
398+
},
399+
"profile delete": {
400+
method: http.MethodDelete,
401+
path: "/profiles/profile_123",
402+
projectID: "project_123",
403+
call: func(ctx context.Context, clients Clients) error {
404+
return clients.DeleteProfile(ctx, "project_123", "profile_123")
405+
},
406+
},
390407
"browser pool create": {
391408
method: http.MethodPost,
392409
path: "/browser_pools",
@@ -528,6 +545,14 @@ func TestClientsDoNotExposeExtensionArchiveMethods(t *testing.T) {
528545
}
529546
}
530547

548+
func TestClientsDoNotExposeProfileArchiveMethods(t *testing.T) {
549+
t.Parallel()
550+
551+
if _, ok := reflect.TypeOf(Clients{}).MethodByName("DownloadProfile"); ok {
552+
t.Fatal("Clients exposes profile archive download")
553+
}
554+
}
555+
531556
func appListPage(id string) string {
532557
return `[{"id":"` + id + `","app_name":"demo","version":"v1","region":"aws.us-east-1a","deployment":"deployment-1","actions":[],"env_vars":{}}]`
533558
}

0 commit comments

Comments
 (0)