@@ -12,10 +12,12 @@ import (
12
12
"github.com/google/uuid"
13
13
"github.com/stretchr/testify/assert"
14
14
"github.com/stretchr/testify/require"
15
+ "golang.org/x/xerrors"
15
16
16
17
"github.com/coder/coder/coderd/audit"
17
18
"github.com/coder/coder/coderd/coderdtest"
18
19
"github.com/coder/coder/coderd/database"
20
+ "github.com/coder/coder/coderd/rbac"
19
21
"github.com/coder/coder/codersdk"
20
22
"github.com/coder/coder/provisioner/echo"
21
23
"github.com/coder/coder/provisionersdk/proto"
@@ -1151,3 +1153,133 @@ func TestMigrateLegacyToRichParameters(t *testing.T) {
1151
1153
require .Len (t , buildParameters , 1 )
1152
1154
require .Equal (t , "carrot" , buildParameters [0 ].Value )
1153
1155
}
1156
+
1157
+ func TestWorkspaceBuildDebugMode (t * testing.T ) {
1158
+ t .Parallel ()
1159
+
1160
+ t .Run ("AsRegularUser" , func (t * testing.T ) {
1161
+ t .Parallel ()
1162
+
1163
+ // Create users
1164
+ templateAuthorClient := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
1165
+ templateAuthor := coderdtest .CreateFirstUser (t , templateAuthorClient )
1166
+ regularUserClient , _ := coderdtest .CreateAnotherUser (t , templateAuthorClient , templateAuthor .OrganizationID )
1167
+
1168
+ // Template owner: create a template
1169
+ version := coderdtest .CreateTemplateVersion (t , templateAuthorClient , templateAuthor .OrganizationID , nil )
1170
+ template := coderdtest .CreateTemplate (t , templateAuthorClient , templateAuthor .OrganizationID , version .ID )
1171
+ coderdtest .AwaitTemplateVersionJob (t , templateAuthorClient , version .ID )
1172
+
1173
+ // Regular user: create a workspace
1174
+ workspace := coderdtest .CreateWorkspace (t , regularUserClient , templateAuthor .OrganizationID , template .ID )
1175
+ coderdtest .AwaitWorkspaceBuildJob (t , regularUserClient , workspace .LatestBuild .ID )
1176
+
1177
+ // Regular user: try to start a workspace build in debug mode
1178
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitLong )
1179
+ defer cancel ()
1180
+
1181
+ _ , err := regularUserClient .CreateWorkspaceBuild (ctx , workspace .ID , codersdk.CreateWorkspaceBuildRequest {
1182
+ TemplateVersionID : workspace .LatestBuild .TemplateVersionID ,
1183
+ Transition : codersdk .WorkspaceTransitionStart ,
1184
+ LogLevel : "debug" ,
1185
+ })
1186
+
1187
+ // Regular user: expect an error
1188
+ require .NotNil (t , err )
1189
+ var sdkError * codersdk.Error
1190
+ isSdkError := xerrors .As (err , & sdkError )
1191
+ require .True (t , isSdkError )
1192
+ require .Contains (t , sdkError .Message , "Workspace builds with a custom log level are restricted to template authors only." )
1193
+ })
1194
+ t .Run ("AsTemplateAuthor" , func (t * testing.T ) {
1195
+ t .Parallel ()
1196
+
1197
+ // Create users
1198
+ adminClient := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
1199
+ admin := coderdtest .CreateFirstUser (t , adminClient )
1200
+ templateAdminClient , _ := coderdtest .CreateAnotherUser (t , adminClient , admin .OrganizationID , rbac .RoleTemplateAdmin ())
1201
+
1202
+ // Interact as template admin
1203
+ echoResponses := & echo.Responses {
1204
+ Parse : echo .ParseComplete ,
1205
+ ProvisionPlan : echo .ProvisionComplete ,
1206
+ ProvisionApply : []* proto.Provision_Response {{
1207
+ Type : & proto.Provision_Response_Log {
1208
+ Log : & proto.Log {
1209
+ Level : proto .LogLevel_DEBUG ,
1210
+ Output : "want-it" ,
1211
+ },
1212
+ },
1213
+ }, {
1214
+ Type : & proto.Provision_Response_Log {
1215
+ Log : & proto.Log {
1216
+ Level : proto .LogLevel_TRACE ,
1217
+ Output : "dont-want-it" ,
1218
+ },
1219
+ },
1220
+ }, {
1221
+ Type : & proto.Provision_Response_Log {
1222
+ Log : & proto.Log {
1223
+ Level : proto .LogLevel_DEBUG ,
1224
+ Output : "done" ,
1225
+ },
1226
+ },
1227
+ }, {
1228
+ Type : & proto.Provision_Response_Complete {
1229
+ Complete : & proto.Provision_Complete {},
1230
+ },
1231
+ }},
1232
+ }
1233
+ version := coderdtest .CreateTemplateVersion (t , templateAdminClient , admin .OrganizationID , echoResponses )
1234
+ template := coderdtest .CreateTemplate (t , templateAdminClient , admin .OrganizationID , version .ID )
1235
+ coderdtest .AwaitTemplateVersionJob (t , templateAdminClient , version .ID )
1236
+
1237
+ // Create workspace
1238
+ workspace := coderdtest .CreateWorkspace (t , templateAdminClient , admin .OrganizationID , template .ID )
1239
+ coderdtest .AwaitWorkspaceBuildJob (t , templateAdminClient , workspace .LatestBuild .ID )
1240
+
1241
+ // Create workspace build
1242
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitLong )
1243
+ defer cancel ()
1244
+
1245
+ build , err := templateAdminClient .CreateWorkspaceBuild (ctx , workspace .ID , codersdk.CreateWorkspaceBuildRequest {
1246
+ TemplateVersionID : workspace .LatestBuild .TemplateVersionID ,
1247
+ Transition : codersdk .WorkspaceTransitionStart ,
1248
+ ProvisionerState : []byte (" " ),
1249
+ LogLevel : "debug" ,
1250
+ })
1251
+ require .Nil (t , err )
1252
+
1253
+ build = coderdtest .AwaitWorkspaceBuildJob (t , templateAdminClient , build .ID )
1254
+
1255
+ // Watch for incoming logs
1256
+ logs , closer , err := templateAdminClient .WorkspaceBuildLogsAfter (ctx , build .ID , 0 )
1257
+ require .NoError (t , err )
1258
+ defer closer .Close ()
1259
+
1260
+ var logsProcessed int
1261
+
1262
+ processingLogs:
1263
+ for {
1264
+ select {
1265
+ case <- ctx .Done ():
1266
+ require .Fail (t , "timeout occurred while processing logs" )
1267
+ return
1268
+ case log , ok := <- logs :
1269
+ if ! ok {
1270
+ break processingLogs
1271
+ }
1272
+
1273
+ logsProcessed ++
1274
+
1275
+ require .NotEqual (t , "dont-want-it" , log .Output , "unexpected log message" , "%s log message shouldn't be logged: %s" )
1276
+
1277
+ if log .Output == "done" {
1278
+ break processingLogs
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ require .Len (t , echoResponses .ProvisionApply , logsProcessed )
1284
+ })
1285
+ }
0 commit comments