@@ -1227,7 +1227,7 @@ func TestHostResourceManagerResourceUtilization(t *testing.T) {
1227
1227
testTask := createTestTask (taskArn )
1228
1228
1229
1229
// create container
1230
- A := createTestContainerWithImageAndName (baseImageForOS , "A" )
1230
+ A := createTestContainerWithImageAndName (baseImageForOS , fmt . Sprintf ( "A-%d" , i ) )
1231
1231
A .EntryPoint = & entryPointForOS
1232
1232
A .Command = []string {"trap shortsleep SIGTERM; shortsleep() { sleep 6; exit 1; }; sleep 10" }
1233
1233
A .Essential = true
@@ -1288,3 +1288,96 @@ func TestHostResourceManagerResourceUtilization(t *testing.T) {
1288
1288
1289
1289
waitFinished (t , finished , testTimeout )
1290
1290
}
1291
+
1292
+ // This task verifies resources are properly released for all tasks for the case where
1293
+ // stopTask is received from ACS for a task which is queued up in waitingTasksQueue
1294
+ func TestHostResourceManagerStopTaskNotBlockWaitingTasks (t * testing.T ) {
1295
+ testTimeout := 1 * time .Minute
1296
+ taskEngine , done , _ := setupWithDefaultConfig (t )
1297
+ defer done ()
1298
+
1299
+ stateChangeEvents := taskEngine .StateChangeEvents ()
1300
+
1301
+ tasks := []* apitask.Task {}
1302
+ stopTasks := []* apitask.Task {}
1303
+ for i := 0 ; i < 2 ; i ++ {
1304
+ taskArn := fmt .Sprintf ("IntegTaskArn-%d" , i )
1305
+ testTask := createTestTask (taskArn )
1306
+ testTask .Memory = int64 (768 )
1307
+
1308
+ // create container
1309
+ A := createTestContainerWithImageAndName (baseImageForOS , fmt .Sprintf ("A-%d" , i ))
1310
+ A .EntryPoint = & entryPointForOS
1311
+ A .Command = []string {"trap shortsleep SIGTERM; shortsleep() { sleep 6; exit 1; }; sleep 10" }
1312
+ A .Essential = true
1313
+ A .StopTimeout = uint (6 )
1314
+ testTask .Containers = []* apicontainer.Container {
1315
+ A ,
1316
+ }
1317
+
1318
+ tasks = append (tasks , testTask )
1319
+
1320
+ // Stop task payloads from ACS for the tasks
1321
+ stopTask := createTestTask (fmt .Sprintf ("IntegTaskArn-%d" , i ))
1322
+ stopTask .DesiredStatusUnsafe = apitaskstatus .TaskStopped
1323
+ stopTask .Containers = []* apicontainer.Container {}
1324
+ stopTasks = append (stopTasks , stopTask )
1325
+ }
1326
+
1327
+ // goroutine to schedule tasks
1328
+ go func () {
1329
+ taskEngine .AddTask (tasks [0 ])
1330
+ time .Sleep (2 * time .Second )
1331
+
1332
+ // single managedTask which should have started
1333
+ assert .Equal (t , 1 , len (taskEngine .(* DockerTaskEngine ).managedTasks ), "exactly one task should be running" )
1334
+
1335
+ // stopTask[0] - stop running task[0], this task will go to STOPPING due to trap handler defined and STOPPED after 6s
1336
+ taskEngine .AddTask (stopTasks [0 ])
1337
+
1338
+ time .Sleep (2 * time .Second )
1339
+
1340
+ // this task (task[1]) goes in waitingTasksQueue because not enough memory available
1341
+ taskEngine .AddTask (tasks [1 ])
1342
+
1343
+ time .Sleep (2 * time .Second )
1344
+
1345
+ // stopTask[1] - stop waiting task - task[1]
1346
+ taskEngine .AddTask (stopTasks [1 ])
1347
+ }()
1348
+
1349
+ finished := make (chan interface {})
1350
+
1351
+ // goroutine to verify task running order and verify assertions
1352
+ go func () {
1353
+ // 1st task goes to RUNNING
1354
+ verifyContainerRunningStateChange (t , taskEngine )
1355
+ verifyTaskIsRunning (stateChangeEvents , tasks [0 ])
1356
+
1357
+ time .Sleep (2500 * time .Millisecond )
1358
+
1359
+ // At this time, task[0] stopTask is received, and SIGTERM sent to task
1360
+ // but the task[0] is still RUNNING due to trap handler
1361
+ assert .Equal (t , apitaskstatus .TaskRunning , tasks [0 ].GetKnownStatus (), "task 0 known status should be RUNNING" )
1362
+ assert .Equal (t , apitaskstatus .TaskStopped , tasks [0 ].GetDesiredStatus (), "task 0 status should be STOPPED" )
1363
+
1364
+ time .Sleep (2 * time .Second )
1365
+
1366
+ // task[1] stops while in waitingTasksQueue while task[0] is in progress
1367
+ // This is because it is still waiting to progress, has no containers created
1368
+ // and does not need to wait for stopTimeout, can immediately STSC out
1369
+ verifyTaskIsStopped (stateChangeEvents , tasks [1 ])
1370
+
1371
+ // task[0] stops
1372
+ verifyContainerStoppedStateChange (t , taskEngine )
1373
+ verifyTaskIsStopped (stateChangeEvents , tasks [0 ])
1374
+
1375
+ // Verify resources are properly released in host resource manager
1376
+ assert .False (t , taskEngine .(* DockerTaskEngine ).hostResourceManager .checkTaskConsumed (tasks [0 ].Arn ), "task 0 resources not released" )
1377
+ assert .False (t , taskEngine .(* DockerTaskEngine ).hostResourceManager .checkTaskConsumed (tasks [1 ].Arn ), "task 1 resources not released" )
1378
+
1379
+ close (finished )
1380
+ }()
1381
+
1382
+ waitFinished (t , finished , testTimeout )
1383
+ }
0 commit comments