@@ -1556,6 +1556,112 @@ func TestStopVM_Isolated(t *testing.T) {
1556
1556
})
1557
1557
}
1558
1558
}
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
+
1559
1665
func TestEvents_Isolated (t * testing.T ) {
1560
1666
prepareIntegTest (t )
1561
1667
require := require .New (t )
0 commit comments