2023-10-19 22:16:15 +00:00
package cli_test
import (
2023-11-02 19:41:34 +00:00
"bytes"
2023-10-19 22:16:15 +00:00
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license"
"github.com/coder/coder/v2/testutil"
)
// TestStart also tests restart since the tests are virtually identical.
func TestStart ( t * testing . T ) {
t . Parallel ( )
t . Run ( "RequireActiveVersion" , func ( t * testing . T ) {
t . Parallel ( )
ctx := testutil . Context ( t , testutil . WaitMedium )
ownerClient , owner := coderdenttest . New ( t , & coderdenttest . Options {
Options : & coderdtest . Options {
IncludeProvisionerDaemon : true ,
} ,
LicenseOptions : & coderdenttest . LicenseOptions {
Features : license . Features {
codersdk . FeatureAccessControl : 1 ,
codersdk . FeatureTemplateRBAC : 1 ,
codersdk . FeatureAdvancedTemplateScheduling : 1 ,
} ,
} ,
} )
2023-11-08 14:54:48 +00:00
templateAdminClient , templateAdmin := coderdtest . CreateAnotherUser ( t , ownerClient , owner . OrganizationID , rbac . RoleTemplateAdmin ( ) )
2023-10-19 22:16:15 +00:00
// Create an initial version.
2023-11-08 14:54:48 +00:00
oldVersion := coderdtest . CreateTemplateVersion ( t , templateAdminClient , owner . OrganizationID , nil )
2023-10-19 22:16:15 +00:00
// Create a template that mandates the promoted version.
// This should be enforced for everyone except template admins.
2023-11-08 14:54:48 +00:00
template := coderdtest . CreateTemplate ( t , templateAdminClient , owner . OrganizationID , oldVersion . ID )
coderdtest . AwaitTemplateVersionJobCompleted ( t , templateAdminClient , oldVersion . ID )
2023-10-19 22:16:15 +00:00
require . Equal ( t , oldVersion . ID , template . ActiveVersionID )
2023-11-08 14:54:48 +00:00
template = coderdtest . UpdateTemplateMeta ( t , templateAdminClient , template . ID , codersdk . UpdateTemplateMeta {
2023-10-19 22:16:15 +00:00
RequireActiveVersion : true ,
} )
require . True ( t , template . RequireActiveVersion )
// Create a new version that we will promote.
2023-11-08 14:54:48 +00:00
activeVersion := coderdtest . CreateTemplateVersion ( t , templateAdminClient , owner . OrganizationID , nil , func ( ctvr * codersdk . CreateTemplateVersionRequest ) {
2023-10-19 22:16:15 +00:00
ctvr . TemplateID = template . ID
} )
2023-11-08 14:54:48 +00:00
coderdtest . AwaitTemplateVersionJobCompleted ( t , templateAdminClient , activeVersion . ID )
err := templateAdminClient . UpdateActiveTemplateVersion ( ctx , template . ID , codersdk . UpdateActiveTemplateVersion {
2023-10-19 22:16:15 +00:00
ID : activeVersion . ID ,
} )
require . NoError ( t , err )
templateACLAdminClient , templateACLAdmin := coderdtest . CreateAnotherUser ( t , ownerClient , owner . OrganizationID )
templateGroupACLAdminClient , templateGroupACLAdmin := coderdtest . CreateAnotherUser ( t , ownerClient , owner . OrganizationID )
memberClient , member := coderdtest . CreateAnotherUser ( t , ownerClient , owner . OrganizationID )
// Create a group so we can also test group template admin ownership.
// Add the user who gains template admin via group membership.
2023-11-08 14:54:48 +00:00
group := coderdtest . CreateGroup ( t , ownerClient , owner . OrganizationID , "test" , templateGroupACLAdmin )
2023-10-19 22:16:15 +00:00
// Update the template for both users and groups.
err = ownerClient . UpdateTemplateACL ( ctx , template . ID , codersdk . UpdateTemplateACL {
UserPerms : map [ string ] codersdk . TemplateRole {
templateACLAdmin . ID . String ( ) : codersdk . TemplateRoleAdmin ,
} ,
GroupPerms : map [ string ] codersdk . TemplateRole {
group . ID . String ( ) : codersdk . TemplateRoleAdmin ,
} ,
} )
require . NoError ( t , err )
type testcase struct {
Name string
Client * codersdk . Client
WorkspaceOwner uuid . UUID
ExpectedVersion uuid . UUID
}
cases := [ ] testcase {
{
Name : "OwnerUnchanged" ,
Client : ownerClient ,
WorkspaceOwner : owner . UserID ,
ExpectedVersion : oldVersion . ID ,
} ,
{
Name : "TemplateAdminUnchanged" ,
Client : templateAdminClient ,
WorkspaceOwner : templateAdmin . ID ,
ExpectedVersion : oldVersion . ID ,
} ,
{
Name : "TemplateACLAdminUnchanged" ,
Client : templateACLAdminClient ,
WorkspaceOwner : templateACLAdmin . ID ,
ExpectedVersion : oldVersion . ID ,
} ,
{
Name : "TemplateGroupACLAdminUnchanged" ,
Client : templateGroupACLAdminClient ,
WorkspaceOwner : templateGroupACLAdmin . ID ,
ExpectedVersion : oldVersion . ID ,
} ,
{
Name : "MemberUpdates" ,
Client : memberClient ,
WorkspaceOwner : member . ID ,
ExpectedVersion : activeVersion . ID ,
} ,
}
for _ , cmd := range [ ] string { "start" , "restart" } {
cmd := cmd
t . Run ( cmd , func ( t * testing . T ) {
t . Parallel ( )
for _ , c := range cases {
c := c
t . Run ( c . Name , func ( t * testing . T ) {
t . Parallel ( )
// Instantiate a new context for each subtest since
// they can potentially be lengthy.
ctx := testutil . Context ( t , testutil . WaitMedium )
// Create the workspace using the admin since we want
// to force the old version.
ws , err := ownerClient . CreateWorkspace ( ctx , owner . OrganizationID , c . WorkspaceOwner . String ( ) , codersdk . CreateWorkspaceRequest {
TemplateVersionID : oldVersion . ID ,
Name : coderdtest . RandomUsername ( t ) ,
AutomaticUpdates : codersdk . AutomaticUpdatesNever ,
} )
require . NoError ( t , err )
coderdtest . AwaitWorkspaceBuildJobCompleted ( t , c . Client , ws . LatestBuild . ID )
2023-11-02 19:41:34 +00:00
initialTemplateVersion := ws . LatestBuild . TemplateVersionID
2023-10-19 22:16:15 +00:00
if cmd == "start" {
// Stop the workspace so that we can start it.
2023-11-02 19:41:34 +00:00
coderdtest . MustTransitionWorkspace ( t , c . Client , ws . ID , database . WorkspaceTransitionStart , database . WorkspaceTransitionStop )
2023-10-19 22:16:15 +00:00
}
// Start the workspace. Every test permutation should
// pass.
2023-11-02 19:41:34 +00:00
var buf bytes . Buffer
2023-10-19 22:16:15 +00:00
inv , conf := newCLI ( t , cmd , ws . Name , "-y" )
2023-11-02 19:41:34 +00:00
inv . Stdout = & buf
2023-10-19 22:16:15 +00:00
clitest . SetupConfig ( t , c . Client , conf )
err = inv . Run ( )
require . NoError ( t , err )
ws = coderdtest . MustWorkspace ( t , c . Client , ws . ID )
require . Equal ( t , c . ExpectedVersion , ws . LatestBuild . TemplateVersionID )
2023-11-02 19:41:34 +00:00
if initialTemplateVersion != ws . LatestBuild . TemplateVersionID {
require . Contains ( t , buf . String ( ) , "Failed to restart with the template version from your last build. Policy may require you to restart with the current active template version." )
}
2023-10-19 22:16:15 +00:00
} )
}
} )
}
} )
}