@@ -41,7 +41,9 @@ import (
4141 "github.com/containerd/containerd/plugin"
4242 "github.com/containerd/containerd/runtime/v2/runc/options"
4343 "github.com/containerd/containerd/sys"
44+
4445 "github.com/opencontainers/runtime-spec/specs-go"
46+ "github.com/stretchr/testify/require"
4547 exec "golang.org/x/sys/execabs"
4648 "golang.org/x/sys/unix"
4749)
@@ -1417,3 +1419,80 @@ func TestShimOOMScore(t *testing.T) {
14171419 case <- statusC :
14181420 }
14191421}
1422+
1423+ // TestIssue9103 is used as regression case for issue 9103.
1424+ //
1425+ // The runc-fp will kill the init process so that the shim should return stopped
1426+ // status after container.NewTask. It's used to simulate that the runc-init
1427+ // might be killed by oom-kill.
1428+ func TestIssue9103 (t * testing.T ) {
1429+ if os .Getenv ("RUNC_FLAVOR" ) == "crun" {
1430+ t .Skip ("skip it when using crun" )
1431+ }
1432+
1433+ client , err := newClient (t , address )
1434+ require .NoError (t , err )
1435+ defer client .Close ()
1436+
1437+ var (
1438+ image Image
1439+ ctx , cancel = testContext (t )
1440+ id = t .Name ()
1441+ )
1442+ defer cancel ()
1443+
1444+ image , err = client .GetImage (ctx , testImage )
1445+ require .NoError (t , err )
1446+
1447+ for idx , tc := range []struct {
1448+ desc string
1449+ cntrOpts []NewContainerOpts
1450+ expectedStatus ProcessStatus
1451+ }{
1452+ {
1453+ desc : "should be created status" ,
1454+ cntrOpts : []NewContainerOpts {
1455+ WithNewSpec (oci .WithImageConfig (image ),
1456+ withProcessArgs ("sleep" , "30" ),
1457+ ),
1458+ },
1459+ expectedStatus : Created ,
1460+ },
1461+ {
1462+ desc : "should be stopped status if init has been killed" ,
1463+ cntrOpts : []NewContainerOpts {
1464+ WithNewSpec (oci .WithImageConfig (image ),
1465+ withProcessArgs ("sleep" , "30" ),
1466+ oci .WithAnnotations (map [string ]string {
1467+ "oci.runc.failpoint.profile" : "issue9103" ,
1468+ }),
1469+ ),
1470+ WithRuntime (client .Runtime (), & options.Options {
1471+ BinaryName : "runc-fp" ,
1472+ }),
1473+ },
1474+ expectedStatus : Stopped ,
1475+ },
1476+ } {
1477+ tc := tc
1478+ tName := fmt .Sprintf ("%s%d" , id , idx )
1479+ t .Run (tc .desc , func (t * testing.T ) {
1480+ container , err := client .NewContainer (ctx , tName ,
1481+ append ([]NewContainerOpts {WithNewSnapshot (tName , image )}, tc .cntrOpts ... )... ,
1482+ )
1483+ require .NoError (t , err )
1484+ defer container .Delete (ctx , WithSnapshotCleanup )
1485+
1486+ cctx , ccancel := context .WithTimeout (ctx , 30 * time .Second )
1487+ task , err := container .NewTask (cctx , empty ())
1488+ ccancel ()
1489+ require .NoError (t , err )
1490+
1491+ defer task .Delete (ctx , WithProcessKill )
1492+
1493+ status , err := task .Status (ctx )
1494+ require .NoError (t , err )
1495+ require .Equal (t , status .Status , tc .expectedStatus )
1496+ })
1497+ }
1498+ }
0 commit comments