Skip to content
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

chore: Use contexts with timeout in coderd tests #3381

Merged
merged 15 commits into from
Aug 9, 2022

Conversation

mafredri
Copy link
Member

@mafredri mafredri commented Aug 4, 2022

Tests sometimes flake with (unknown) status, which is not helpful for debugging. This PR moves to having contexts with timeout in all applicable tests under coderd.

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 (think ctx := testutil.Context() for the default case).

@mafredri mafredri self-assigned this Aug 4, 2022
@mafredri mafredri requested a review from a team August 4, 2022 11:07
@@ -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)
Copy link
Member Author

@mafredri mafredri Aug 4, 2022

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.

@mafredri mafredri force-pushed the mafredri/coderd-test-timeouts branch from c261c88 to 0a7642c Compare August 4, 2022 12:25
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defer t.Cleanup(cancel) // Defer to ensure cancelFunc is executed first.
defer t.Cleanup(cancel) // Defer to ensure cancel is executed first.

Comment on lines 829 to 850
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
Copy link
Member

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.

Copy link
Member Author

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.
Copy link
Member

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!

@mafredri mafredri requested a review from Emyrk August 5, 2022 10:51
@mafredri
Copy link
Member Author

mafredri commented Aug 5, 2022

@Emyrk tagged you as a reviewer here since I made some changes to pagination tests, in case you want to take a look (TestPaginatedUsers and TestPaginatedTemplateVersions mainly).

Copy link
Member

@Emyrk Emyrk left a 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 😢

Comment on lines +828 to +853
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()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines +856 to +867
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--
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much faster speedup 👍

Comment on lines 928 to 929
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
Copy link
Member

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.

Copy link
Member Author

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.

@mafredri mafredri merged commit ccf6f4e into main Aug 9, 2022
@mafredri mafredri deleted the mafredri/coderd-test-timeouts branch August 9, 2022 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants