-
Notifications
You must be signed in to change notification settings - Fork 887
chore: Use contexts with timeout in coderd
tests
#3381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -17,26 +18,38 @@ func TestPostFiles(t *testing.T) { | |||
t.Parallel() | |||
client := coderdtest.New(t, nil) | |||
_ = coderdtest.CreateFirstUser(t, client) | |||
_, err := client.Upload(context.Background(), "bad", []byte{'a'}) | |||
|
|||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As much as possible, I tried to ensure contexts are initialized after test environment has been set up (e.g. post- coderd client, user creation etc). This ensures the timeout is applied only to the part being tested. The coderdtest
methods have their own timeouts.
c261c88
to
0a7642c
Compare
ctx, cancelFunc := context.WithCancel(context.Background()) | ||
defer t.Cleanup(cancelFunc) // Defer to ensure cancelFunc is executed first. | ||
ctx, cancel := context.WithCancel(ctx) // Shadowed to avoid mixing contexts. | ||
defer t.Cleanup(cancel) // Defer to ensure cancelFunc is executed first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defer t.Cleanup(cancel) // Defer to ensure cancelFunc is executed first. | |
defer t.Cleanup(cancel) // Defer to ensure cancel is executed first. |
coderd/templateversions_test.go
Outdated
eg.Go(func() error { | ||
data, err := echo.Tar(nil) | ||
if err != nil { | ||
return err | ||
} | ||
file, err := client.Upload(egCtx, codersdk.ContentTypeTar, data) | ||
if err != nil { | ||
return err | ||
} | ||
templateVersion, err := client.CreateTemplateVersion(egCtx, user.OrganizationID, codersdk.CreateTemplateVersionRequest{ | ||
TemplateID: template.ID, | ||
StorageSource: file.Hash, | ||
StorageMethod: codersdk.ProvisionerStorageMethodFile, | ||
Provisioner: codersdk.ProvisionerTypeEcho, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
templateVersionIDs[i] = templateVersion.ID | ||
|
||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the sort of thing where it would be really useful to have a mock database and just return some predefined fixture.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very much agreed!
@@ -720,22 +816,45 @@ func TestPaginatedTemplateVersions(t *testing.T) { | |||
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) | |||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) | |||
|
|||
// This test takes longer than a long time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It apparently takes even longer than that!
@Emyrk tagged you as a reviewer here since I made some changes to pagination tests, in case you want to take a look ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the speedups. 👍
The pagination stuff does have a lot of setup 😢
i := i | ||
eg.Go(func() error { | ||
data, err := echo.Tar(nil) | ||
if err != nil { | ||
return err | ||
} | ||
file, err := client.Upload(egCtx, codersdk.ContentTypeTar, data) | ||
if err != nil { | ||
return err | ||
} | ||
templateVersion, err := client.CreateTemplateVersion(egCtx, user.OrganizationID, codersdk.CreateTemplateVersionRequest{ | ||
TemplateID: template.ID, | ||
StorageSource: file.Hash, | ||
StorageMethod: codersdk.ProvisionerStorageMethodFile, | ||
Provisioner: codersdk.ProvisionerTypeEcho, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
templateVersionIDs[i] = templateVersion.ID | ||
|
||
_ = coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID) | ||
return nil | ||
}) | ||
} | ||
err := eg.Wait() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
for i := 0; i < len(templateVersionIDs); i++ { | ||
// We don't use coderdtest.AwaitTemplateVersionJob here because | ||
// we can't control the timeouts, the concurrent creations take | ||
// a while. | ||
templateVersion, err := client.TemplateVersion(ctx, templateVersionIDs[i]) | ||
if err == nil && templateVersion.Job.CompletedAt != nil { | ||
continue | ||
} | ||
require.NotErrorIs(t, err, context.DeadlineExceeded, "template version %d not created in time", i) | ||
// Retry. | ||
time.Sleep(testutil.IntervalMedium) | ||
i-- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much faster speedup 👍
coderd/templateversions_test.go
Outdated
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) | ||
defer cancel() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be shorter since the api call shouldn't take that long.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I lowered it 👍🏻, didn't initially put any effort into reducing the timeouts. Defaulted everything to high so it would break as little as possible.
Tests sometimes flake with
(unknown)
status, which is not helpful for debugging. This PR moves to having contexts with timeout in all applicable tests undercoderd
.All uses of
context.Background()
were replaced and code fixed to add the contexts. A few spots required extra care/rewriting due to parallel/subtests to ensure tests passed.This is a practice I feel we should adopt everywhere across the codebase, esp. since we rely heavily on parallel tests. We could consider adding helpers to
testutil
(thinkctx := testutil.Context()
for the default case).