@@ -1556,6 +1556,112 @@ func TestStopVM_Isolated(t *testing.T) {
15561556 })
15571557 }
15581558}
1559+
1560+ func TestExec_Isolated (t * testing.T ) {
1561+ prepareIntegTest (t )
1562+
1563+ client , err := containerd .New (containerdSockPath , containerd .WithDefaultRuntime (firecrackerRuntime ))
1564+ require .NoError (t , err , "unable to create client to containerd service at %s, is containerd running?" , containerdSockPath )
1565+ defer client .Close ()
1566+
1567+ ctx := namespaces .WithNamespace (context .Background (), "default" )
1568+
1569+ image , err := alpineImage (ctx , client , defaultSnapshotterName )
1570+ require .NoError (t , err , "failed to get alpine image" )
1571+
1572+ pluginClient , err := ttrpcutil .NewClient (containerdSockPath + ".ttrpc" )
1573+ require .NoError (t , err , "failed to create ttrpc client" )
1574+
1575+ vmID := testNameToVMID (t .Name ())
1576+
1577+ fcClient := fccontrol .NewFirecrackerClient (pluginClient .Client ())
1578+ _ , err = fcClient .CreateVM (ctx , & proto.CreateVMRequest {VMID : vmID })
1579+ require .NoError (t , err )
1580+
1581+ c , err := client .NewContainer (ctx ,
1582+ "container-" + vmID ,
1583+ containerd .WithSnapshotter (defaultSnapshotterName ),
1584+ containerd .WithNewSnapshot ("snapshot-" + vmID , image ),
1585+ containerd .WithNewSpec (oci .WithProcessArgs ("/bin/sleep" , "3" ), firecrackeroci .WithVMID (vmID )),
1586+ )
1587+ require .NoError (t , err )
1588+
1589+ var taskStdout bytes.Buffer
1590+ var taskStderr bytes.Buffer
1591+
1592+ task , err := c .NewTask (ctx , cio .NewCreator (cio .WithStreams (nil , & taskStdout , & taskStderr )))
1593+ require .NoError (t , err , "failed to create task for container %s" , c .ID ())
1594+
1595+ taskExitCh , err := task .Wait (ctx )
1596+ require .NoError (t , err , "failed to wait on task for container %s" , c .ID ())
1597+
1598+ err = task .Start (ctx )
1599+ require .NoError (t , err , "failed to start task for container %s" , c .ID ())
1600+
1601+ var execStdout bytes.Buffer
1602+ var execStderr bytes.Buffer
1603+
1604+ taskExec , err := task .Exec (ctx , "exec" , & specs.Process {
1605+ Args : []string {"/bin/date" },
1606+ Cwd : "/" ,
1607+ }, cio .NewCreator (cio .WithStreams (nil , & execStdout , & execStderr )))
1608+ require .NoError (t , err )
1609+
1610+ execExitCh , err := taskExec .Wait (ctx )
1611+ require .NoError (t , err , "failed to wait on exec %s" , "exec" )
1612+
1613+ execBegin := time .Now ()
1614+ err = taskExec .Start (ctx )
1615+ require .NoError (t , err , "failed to start exec %s" , "exec" )
1616+
1617+ select {
1618+ case execStatus := <- execExitCh :
1619+ assert .NoError (t , execStatus .Error ())
1620+ assert .Equal (t , uint32 (0 ), execStatus .ExitCode ())
1621+
1622+ execElapsed := time .Since (execBegin )
1623+ assert .Truef (
1624+ t , execElapsed < 1 * time .Second ,
1625+ "The exec took %s to finish, which was too slow." , execElapsed ,
1626+ )
1627+
1628+ _ , err := taskExec .Delete (ctx )
1629+ assert .NoError (t , err )
1630+
1631+ deleteElapsed := time .Since (execBegin )
1632+ assert .Truef (
1633+ t , deleteElapsed < 1 * time .Second ,
1634+ "The deletion of the exec took %s to finish, which was too slow." , deleteElapsed ,
1635+ )
1636+
1637+ assert .NotEqual (t , "" , execStdout .String ())
1638+ assert .Equal (t , "" , execStderr .String ())
1639+ case <- ctx .Done ():
1640+ require .Fail (t , "context cancelled" ,
1641+ "context cancelled while waiting for container %s to exit, err: %v" , c .ID (), ctx .Err ())
1642+ }
1643+
1644+ select {
1645+ case taskStatus := <- taskExitCh :
1646+ assert .NoError (t , taskStatus .Error ())
1647+ assert .Equal (t , uint32 (0 ), taskStatus .ExitCode ())
1648+
1649+ deleteResult , err := task .Delete (ctx )
1650+ assert .NoErrorf (t , err , "failed to delete task %q after exit" , c .ID ())
1651+ assert .NoError (t , deleteResult .Error ())
1652+
1653+ assert .Equal (t , "" , taskStdout .String ())
1654+ assert .Equal (t , "" , taskStderr .String ())
1655+ case <- ctx .Done ():
1656+ require .Fail (t , "context cancelled" ,
1657+ "context cancelled while waiting for container %s to exit, err: %v" , c .ID (), ctx .Err ())
1658+ }
1659+
1660+ _ , err = fcClient .StopVM (ctx , & proto.StopVMRequest {VMID : vmID })
1661+ assert .NoError (t , err )
1662+ require .Equal (t , status .Code (err ), codes .OK )
1663+ }
1664+
15591665func TestEvents_Isolated (t * testing.T ) {
15601666 prepareIntegTest (t )
15611667 require := require .New (t )
0 commit comments