Skip to content

feat: Enable workspace debug logging #6838

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

Merged
merged 18 commits into from
Mar 30, 2023
Prev Previous commit
Next Next commit
more tests
  • Loading branch information
mtojek committed Mar 29, 2023
commit 35cf5092b3fb0f387b1b3ccd8ecdc2786434de0a
160 changes: 100 additions & 60 deletions coderd/workspacebuilds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"

"github.com/coder/coder/coderd/audit"
"github.com/coder/coder/coderd/coderdtest"
Expand Down Expand Up @@ -1154,76 +1155,115 @@ func TestMigrateLegacyToRichParameters(t *testing.T) {

func TestWorkspaceBuildDebugMode(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: echo.ParseComplete,
ProvisionPlan: echo.ProvisionComplete,
ProvisionApply: []*proto.Provision_Response{{
Type: &proto.Provision_Response_Log{
Log: &proto.Log{
Level: proto.LogLevel_DEBUG,
Output: "want-it",

t.Run("AsRegularUser", func(t *testing.T) {
t.Parallel()

// Create users
templateAuthorClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
templateAuthor := coderdtest.CreateFirstUser(t, templateAuthorClient)
regularUserClient, _ := coderdtest.CreateAnotherUser(t, templateAuthorClient, templateAuthor.OrganizationID)

// Template owner: create a template
version := coderdtest.CreateTemplateVersion(t, templateAuthorClient, templateAuthor.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, templateAuthorClient, templateAuthor.OrganizationID, version.ID)
coderdtest.AwaitTemplateVersionJob(t, templateAuthorClient, version.ID)

// Regular user: create a workspace
workspace := coderdtest.CreateWorkspace(t, regularUserClient, templateAuthor.OrganizationID, template.ID)
coderdtest.AwaitWorkspaceBuildJob(t, regularUserClient, workspace.LatestBuild.ID)

// Regular user: try to start a workspace build in debug mode
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()

_, err := regularUserClient.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
TemplateVersionID: workspace.LatestBuild.TemplateVersionID,
Transition: codersdk.WorkspaceTransitionStart,
LogLevel: "debug",
})

// Regular user: expect an error
require.NotNil(t, err)
var sdkError *codersdk.Error
isSdkError := xerrors.As(err, &sdkError)
require.True(t, isSdkError)
require.Contains(t, sdkError.Message, "Workspace builds with a custom log level are restricted to template authors only.")
})
t.Run("AsTemplateAuthor", func(t *testing.T) {
t.Parallel()

client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
Copy link
Member

Choose a reason for hiding this comment

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

Blocking: instead of running this as the "admin" user, we should instead do as above and create another user with template admin permissions. This would more properly test that the template author has the correct permissions to create this sort of job.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you for the hint! Refactored.

version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: echo.ParseComplete,
ProvisionPlan: echo.ProvisionComplete,
ProvisionApply: []*proto.Provision_Response{{
Type: &proto.Provision_Response_Log{
Log: &proto.Log{
Level: proto.LogLevel_DEBUG,
Output: "want-it",
},
},
},
}, {
Type: &proto.Provision_Response_Log{
Log: &proto.Log{
Level: proto.LogLevel_TRACE,
Output: "dont-want-it",
}, {
Type: &proto.Provision_Response_Log{
Log: &proto.Log{
Level: proto.LogLevel_TRACE,
Output: "dont-want-it",
},
},
},
}, {
Type: &proto.Provision_Response_Log{
Log: &proto.Log{
Level: proto.LogLevel_DEBUG,
Output: "done",
}, {
Type: &proto.Provision_Response_Log{
Log: &proto.Log{
Level: proto.LogLevel_DEBUG,
Output: "done",
},
},
},
}, {
Type: &proto.Provision_Response_Complete{
Complete: &proto.Provision_Complete{},
},
}},
})
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
}, {
Type: &proto.Provision_Response_Complete{
Complete: &proto.Provision_Complete{},
},
}},
})
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)

// Create workspace
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
// Create workspace
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)

// Create workspace build
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
// Create workspace build
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()

build, err := client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
TemplateVersionID: workspace.LatestBuild.TemplateVersionID,
Transition: codersdk.WorkspaceTransitionStart,
ProvisionerState: []byte(" "),
LogLevel: "debug",
})
require.Nil(t, err)
build, err := client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
TemplateVersionID: workspace.LatestBuild.TemplateVersionID,
Transition: codersdk.WorkspaceTransitionStart,
ProvisionerState: []byte(" "),
LogLevel: "debug",
})
require.Nil(t, err)

build = coderdtest.AwaitWorkspaceBuildJob(t, client, build.ID)
build = coderdtest.AwaitWorkspaceBuildJob(t, client, build.ID)

// Watch for incoming logs
logs, closer, err := client.WorkspaceBuildLogsAfter(ctx, build.ID, 0)
require.NoError(t, err)
defer closer.Close()
// Watch for incoming logs
logs, closer, err := client.WorkspaceBuildLogsAfter(ctx, build.ID, 0)
require.NoError(t, err)
defer closer.Close()

for {
log, ok := <-logs
if !ok {
break
}
for {
log, ok := <-logs
if !ok {
break
}

if log.Output == "dont-want-it" {
require.Failf(t, "unexpected log message", "%s log message shouldn't be logged: %s", log.Level, log.Output)
}
if log.Output == "dont-want-it" {
require.Failf(t, "unexpected log message", "%s log message shouldn't be logged: %s", log.Level, log.Output)
}

if log.Output == "done" {
return
if log.Output == "done" {
return
}
}
}
})
}