@@ -1323,6 +1323,29 @@ func TestRandomness_Isolated(t *testing.T) {
1323
1323
}
1324
1324
}
1325
1325
1326
+ func findProcess (
1327
+ ctx context.Context ,
1328
+ matcher func (context.Context , * process.Process ) (bool , error ),
1329
+ ) ([]* process.Process , error ) {
1330
+ processes , err := process .ProcessesWithContext (ctx )
1331
+ if err != nil {
1332
+ return nil , err
1333
+ }
1334
+
1335
+ var matches []* process.Process
1336
+ for _ , p := range processes {
1337
+ isMatch , err := matcher (ctx , p )
1338
+ if err != nil {
1339
+ return nil , err
1340
+ }
1341
+ if isMatch {
1342
+ matches = append (matches , p )
1343
+ }
1344
+ }
1345
+
1346
+ return matches , nil
1347
+ }
1348
+
1326
1349
func TestStopVM_Isolated (t * testing.T ) {
1327
1350
prepareIntegTest (t )
1328
1351
require := require .New (t )
@@ -1344,9 +1367,12 @@ func TestStopVM_Isolated(t *testing.T) {
1344
1367
name string
1345
1368
createVMRequest proto.CreateVMRequest
1346
1369
stopFunc func (ctx context.Context , fcClient fccontrol.FirecrackerService , vmID string )
1370
+ withStopVM bool
1347
1371
}{
1348
1372
{
1349
- name : "Successful" ,
1373
+ name : "Successful" ,
1374
+ withStopVM : true ,
1375
+
1350
1376
createVMRequest : proto.CreateVMRequest {},
1351
1377
stopFunc : func (ctx context.Context , fcClient fccontrol.FirecrackerService , vmID string ) {
1352
1378
_ , err = fcClient .StopVM (ctx , & proto.StopVMRequest {VMID : vmID })
@@ -1355,7 +1381,9 @@ func TestStopVM_Isolated(t *testing.T) {
1355
1381
},
1356
1382
1357
1383
{
1358
- name : "Jailer" ,
1384
+ name : "Jailer" ,
1385
+ withStopVM : true ,
1386
+
1359
1387
createVMRequest : proto.CreateVMRequest {
1360
1388
JailerConfig : & proto.JailerConfig {
1361
1389
UID : 300000 ,
@@ -1398,7 +1426,9 @@ func TestStopVM_Isolated(t *testing.T) {
1398
1426
// Firecracker is too fast to test a case where we hit the timeout on a StopVMRequest.
1399
1427
// The rootfs below explicitly sleeps 60 seconds after shutting down the agent to simulate the case.
1400
1428
{
1401
- name : "Timeout" ,
1429
+ name : "Timeout" ,
1430
+ withStopVM : true ,
1431
+
1402
1432
createVMRequest : proto.CreateVMRequest {
1403
1433
RootDrive : & proto.FirecrackerRootDrive {
1404
1434
HostPath : "/var/lib/firecracker-containerd/runtime/rootfs-slow-reboot.img" ,
@@ -1414,10 +1444,12 @@ func TestStopVM_Isolated(t *testing.T) {
1414
1444
1415
1445
// Test that the shim shuts down if the VM stops unexpectedly
1416
1446
{
1417
- name : "SIGKILLFirecracker" ,
1447
+ name : "SIGKILLFirecracker" ,
1448
+ withStopVM : false ,
1449
+
1418
1450
createVMRequest : proto.CreateVMRequest {},
1419
1451
stopFunc : func (ctx context.Context , _ fccontrol.FirecrackerService , _ string ) {
1420
- firecrackerProcesses , err := internal . WaitForProcessToExist (ctx , time . Second , findFirecracker )
1452
+ firecrackerProcesses , err := findProcess (ctx , findFirecracker )
1421
1453
require .NoError (err , "failed waiting for expected firecracker process %q to come up" , firecrackerProcessName )
1422
1454
require .Len (firecrackerProcesses , 1 , "expected only one firecracker process to exist" )
1423
1455
firecrackerProcess := firecrackerProcesses [0 ]
@@ -1430,14 +1462,16 @@ func TestStopVM_Isolated(t *testing.T) {
1430
1462
// Test that StopVM returns the expected error when the VMM exits with an error (simulated by sending
1431
1463
// SIGKILL to the VMM in the middle of a StopVM call).
1432
1464
{
1433
- name : "ErrorExit" ,
1465
+ name : "ErrorExit" ,
1466
+ withStopVM : true ,
1467
+
1434
1468
createVMRequest : proto.CreateVMRequest {
1435
1469
RootDrive : & proto.FirecrackerRootDrive {
1436
1470
HostPath : "/var/lib/firecracker-containerd/runtime/rootfs-slow-reboot.img" ,
1437
1471
},
1438
1472
},
1439
1473
stopFunc : func (ctx context.Context , fcClient fccontrol.FirecrackerService , vmID string ) {
1440
- firecrackerProcesses , err := internal . WaitForProcessToExist (ctx , time . Second , findFirecracker )
1474
+ firecrackerProcesses , err := findProcess (ctx , findFirecracker )
1441
1475
require .NoError (err , "failed waiting for expected firecracker process %q to come up" , firecrackerProcessName )
1442
1476
require .Len (firecrackerProcesses , 1 , "expected only one firecracker process to exist" )
1443
1477
firecrackerProcess := firecrackerProcesses [0 ]
@@ -1482,15 +1516,30 @@ func TestStopVM_Isolated(t *testing.T) {
1482
1516
stdout := startAndWaitTask (ctx , t , c )
1483
1517
require .Equal ("hello" , stdout )
1484
1518
1485
- shimProcesses , err := internal . WaitForProcessToExist (ctx , time . Second , findShim )
1486
- require .NoError (err , "failed waiting for expected shim process %q to come up " , shimProcessName )
1519
+ shimProcesses , err := findProcess (ctx , findShim )
1520
+ require .NoError (err , "failed to find shim process %q" , shimProcessName )
1487
1521
require .Len (shimProcesses , 1 , "expected only one shim process to exist" )
1488
1522
shimProcess := shimProcesses [0 ]
1489
1523
1490
- if test .stopFunc != nil {
1491
- test .stopFunc (ctx , fcClient , vmID )
1524
+ fcProcesses , err := findProcess (ctx , findFirecracker )
1525
+ require .NoError (err , "failed to find firecracker" )
1526
+ require .Len (fcProcesses , 1 , "expected only one firecracker process to exist" )
1527
+ fcProcess := fcProcesses [0 ]
1528
+
1529
+ test .stopFunc (ctx , fcClient , vmID )
1530
+
1531
+ // If the function above uses StopVMRequest,
1532
+ // shim gurantees that the underlying Firecracker process is dead
1533
+ // (either gracefully or forcibly) at the end of the request.
1534
+ if test .withStopVM {
1535
+ fcExists , err := process .PidExists (fcProcess .Pid )
1536
+ require .NoError (err , "failed to find firecracker" )
1537
+ require .False (fcExists , "firecracker %s is still there" , vmID )
1492
1538
}
1493
1539
1540
+ // Since the shim is the one which is writing the response,
1541
+ // it cannot gurantee that the itself is dead at the end of the request.
1542
+ // But it should be dead eventually.
1494
1543
err = internal .WaitForPidToExit (ctx , time .Second , shimProcess .Pid )
1495
1544
require .NoError (err , "shim hasn't been terminated" )
1496
1545
})
0 commit comments