@@ -1476,3 +1476,172 @@ func TestSignalForwarding(t *testing.T) {
14761476
14771477 assert .ElementsMatch (t , forwardedSignals , receivedSignals )
14781478}
1479+
1480+ func TestPauseResume (t * testing.T ) {
1481+ fctesting .RequiresRoot (t )
1482+
1483+ cases := []struct {
1484+ name string
1485+ state func (m * Machine , ctx context.Context )
1486+ }{
1487+ {
1488+ name : "PauseVM" ,
1489+ state : func (m * Machine , ctx context.Context ) {
1490+ err := m .PauseVM (ctx )
1491+ require .NoError (t , err )
1492+ },
1493+ },
1494+ {
1495+ name : "ResumeVM" ,
1496+ state : func (m * Machine , ctx context.Context ) {
1497+ err := m .ResumeVM (ctx )
1498+ require .NoError (t , err )
1499+ },
1500+ },
1501+ {
1502+ name : "Consecutive PauseVM" ,
1503+ state : func (m * Machine , ctx context.Context ) {
1504+ err := m .PauseVM (ctx )
1505+ require .NoError (t , err )
1506+
1507+ err = m .PauseVM (ctx )
1508+ require .NoError (t , err )
1509+ },
1510+ },
1511+ {
1512+ name : "Consecutive ResumeVM" ,
1513+ state : func (m * Machine , ctx context.Context ) {
1514+ err := m .ResumeVM (ctx )
1515+ require .NoError (t , err )
1516+
1517+ err = m .ResumeVM (ctx )
1518+ require .NoError (t , err )
1519+ },
1520+ },
1521+ {
1522+ name : "ResumeVM PauseVM" ,
1523+ state : func (m * Machine , ctx context.Context ) {
1524+ err := m .ResumeVM (ctx )
1525+ require .NoError (t , err )
1526+
1527+ err = m .PauseVM (ctx )
1528+ require .NoError (t , err )
1529+ },
1530+ },
1531+ {
1532+ name : "PauseVM ResumeVM" ,
1533+ state : func (m * Machine , ctx context.Context ) {
1534+ err := m .PauseVM (ctx )
1535+ require .NoError (t , err )
1536+
1537+ err = m .ResumeVM (ctx )
1538+ require .NoError (t , err )
1539+ },
1540+ },
1541+ }
1542+
1543+ for _ , c := range cases {
1544+ t .Run (c .name , func (t * testing.T ) {
1545+ ctx := context .Background ()
1546+
1547+ socketPath := filepath .Join (testDataPath , fsSafeTestName .Replace (t .Name ()))
1548+ defer os .Remove (socketPath )
1549+
1550+ // Tee logs for validation:
1551+ var logBuffer bytes.Buffer
1552+ machineLogger := logrus .New ()
1553+ machineLogger .Out = io .MultiWriter (os .Stderr , & logBuffer )
1554+
1555+ cfg := createValidConfig (t , socketPath )
1556+ m , err := NewMachine (ctx , cfg , func (m * Machine ) {
1557+ // Rewriting m.cmd partially wouldn't work since Cmd has
1558+ // some unexported members
1559+ args := m .cmd .Args [1 :]
1560+ m .cmd = exec .Command (getFirecrackerBinaryPath (), args ... )
1561+ }, WithLogger (logrus .NewEntry (machineLogger )))
1562+ require .NoError (t , err )
1563+
1564+ err = m .PauseVM (ctx )
1565+ require .Error (t , err , "PauseVM must fail before Start is called" )
1566+
1567+ err = m .ResumeVM (ctx )
1568+ require .Error (t , err , "ResumeVM must fail before Start is called" )
1569+
1570+ err = m .Start (ctx )
1571+ require .NoError (t , err )
1572+
1573+ c .state (m , ctx )
1574+
1575+ err = m .StopVMM ()
1576+ require .NoError (t , err )
1577+
1578+ err = m .PauseVM (ctx )
1579+ require .Error (t , err , "PauseVM must fail after StopVMM is called" )
1580+
1581+ err = m .ResumeVM (ctx )
1582+ require .Error (t , err , "ResumeVM must fail after StopVMM is called" )
1583+ })
1584+ }
1585+ }
1586+
1587+ func TestCreateSnapshot (t * testing.T ) {
1588+ fctesting .RequiresRoot (t )
1589+
1590+ cases := []struct {
1591+ name string
1592+ createSnapshot func (m * Machine , ctx context.Context , memPath , snapPath string )
1593+ }{
1594+ {
1595+ name : "CreateSnapshot" ,
1596+ createSnapshot : func (m * Machine , ctx context.Context , memPath , snapPath string ) {
1597+ err := m .PauseVM (ctx )
1598+ require .NoError (t , err )
1599+
1600+ err = m .CreateSnapshot (ctx , memPath , snapPath )
1601+ require .NoError (t , err )
1602+ },
1603+ },
1604+ {
1605+ name : "CreateSnapshot before pause" ,
1606+ createSnapshot : func (m * Machine , ctx context.Context , memPath , snapPath string ) {
1607+ err := m .CreateSnapshot (ctx , memPath , snapPath )
1608+ require .Error (t , err )
1609+ },
1610+ },
1611+ }
1612+
1613+ for _ , c := range cases {
1614+ t .Run (c .name , func (t * testing.T ) {
1615+ ctx := context .Background ()
1616+
1617+ socketPath := filepath .Join (testDataPath , fsSafeTestName .Replace (t .Name ()))
1618+ snapPath := socketPath + "SnapFile"
1619+ memPath := socketPath + "MemFile"
1620+ defer os .Remove (socketPath )
1621+ defer os .Remove (snapPath )
1622+ defer os .Remove (memPath )
1623+
1624+ // Tee logs for validation:
1625+ var logBuffer bytes.Buffer
1626+ machineLogger := logrus .New ()
1627+ machineLogger .Out = io .MultiWriter (os .Stderr , & logBuffer )
1628+
1629+ cfg := createValidConfig (t , socketPath )
1630+ m , err := NewMachine (ctx , cfg , func (m * Machine ) {
1631+ // Rewriting m.cmd partially wouldn't work since Cmd has
1632+ // some unexported members
1633+ args := m .cmd .Args [1 :]
1634+ m .cmd = exec .Command (getFirecrackerBinaryPath (), args ... )
1635+ }, WithLogger (logrus .NewEntry (machineLogger )))
1636+ require .NoError (t , err )
1637+
1638+ err = m .Start (ctx )
1639+ require .NoError (t , err )
1640+
1641+ c .createSnapshot (m , ctx , memPath , snapPath )
1642+
1643+ err = m .StopVMM ()
1644+ require .NoError (t , err )
1645+ })
1646+ }
1647+ }
0 commit comments