|  | 
| 71 | 71 | 	testBalloonDeflateOnOom      = true | 
| 72 | 72 | 	testStatsPollingIntervals    = int64(1) | 
| 73 | 73 | 	testNewStatsPollingIntervals = int64(6) | 
|  | 74 | + | 
|  | 75 | +	// How long to wait for the socket to appear. | 
|  | 76 | +	firecrackerSocketWait = int64(10) | 
| 74 | 77 | ) | 
| 75 | 78 | 
 | 
| 76 | 79 | func envOrDefault(k, empty string) string { | 
| @@ -1728,6 +1731,76 @@ func TestCreateSnapshot(t *testing.T) { | 
| 1728 | 1731 | 	} | 
| 1729 | 1732 | } | 
| 1730 | 1733 | 
 | 
|  | 1734 | +func TestLoadSnapshot(t *testing.T) { | 
|  | 1735 | +	fctesting.RequiresKVM(t) | 
|  | 1736 | +	fctesting.RequiresRoot(t) | 
|  | 1737 | + | 
|  | 1738 | +	ctx := context.Background() | 
|  | 1739 | + | 
|  | 1740 | +	dir, err := ioutil.TempDir("", t.Name()) | 
|  | 1741 | +	require.NoError(t, err) | 
|  | 1742 | +	defer os.RemoveAll(dir) | 
|  | 1743 | + | 
|  | 1744 | +	// Set snap and mem paths | 
|  | 1745 | +	socketPath := filepath.Join(dir, fsSafeTestName.Replace(t.Name())) | 
|  | 1746 | +	snapPath := socketPath + "SnapFile" | 
|  | 1747 | +	memPath := socketPath + "MemFile" | 
|  | 1748 | +	defer os.Remove(socketPath) | 
|  | 1749 | +	defer os.Remove(snapPath) | 
|  | 1750 | +	defer os.Remove(memPath) | 
|  | 1751 | + | 
|  | 1752 | +	// Tee logs for validation: | 
|  | 1753 | +	var logBuffer bytes.Buffer | 
|  | 1754 | +	machineLogger := logrus.New() | 
|  | 1755 | +	machineLogger.Out = io.MultiWriter(os.Stderr, &logBuffer) | 
|  | 1756 | + | 
|  | 1757 | +	// Create a snapshot | 
|  | 1758 | +	{ | 
|  | 1759 | +		cfg := createValidConfig(t, socketPath+".create") | 
|  | 1760 | +		m, err := NewMachine(ctx, cfg, func(m *Machine) { | 
|  | 1761 | +			// Rewriting m.cmd partially wouldn't work since Cmd has | 
|  | 1762 | +			// some unexported members | 
|  | 1763 | +			args := m.cmd.Args[1:] | 
|  | 1764 | +			m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) | 
|  | 1765 | +		}, WithLogger(logrus.NewEntry(machineLogger))) | 
|  | 1766 | +		require.NoError(t, err) | 
|  | 1767 | + | 
|  | 1768 | +		err = m.Start(ctx) | 
|  | 1769 | +		require.NoError(t, err) | 
|  | 1770 | + | 
|  | 1771 | +		err = m.PauseVM(ctx) | 
|  | 1772 | +		require.NoError(t, err) | 
|  | 1773 | + | 
|  | 1774 | +		err = m.CreateSnapshot(ctx, memPath, snapPath) | 
|  | 1775 | +		require.NoError(t, err) | 
|  | 1776 | + | 
|  | 1777 | +		err = m.StopVMM() | 
|  | 1778 | +		require.NoError(t, err) | 
|  | 1779 | +	} | 
|  | 1780 | + | 
|  | 1781 | +	// Load a snapshot | 
|  | 1782 | +	{ | 
|  | 1783 | +		cfg := createValidConfig(t, socketPath+".load") | 
|  | 1784 | +		m, err := NewMachine(ctx, cfg, func(m *Machine) { | 
|  | 1785 | +			// Rewriting m.cmd partially wouldn't work since Cmd has | 
|  | 1786 | +			// some unexported members | 
|  | 1787 | +			args := m.cmd.Args[1:] | 
|  | 1788 | +			m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) | 
|  | 1789 | +		}, WithLogger(logrus.NewEntry(machineLogger))) | 
|  | 1790 | +		require.NoError(t, err) | 
|  | 1791 | + | 
|  | 1792 | +		err = m.Start(ctx, WithSnapshot(ctx, memPath, snapPath)) | 
|  | 1793 | +		require.NoError(t, err) | 
|  | 1794 | + | 
|  | 1795 | +		err = m.ResumeVM(ctx) | 
|  | 1796 | +		require.NoError(t, err) | 
|  | 1797 | + | 
|  | 1798 | +		err = m.StopVMM() | 
|  | 1799 | +		require.NoError(t, err) | 
|  | 1800 | +	} | 
|  | 1801 | + | 
|  | 1802 | +} | 
|  | 1803 | + | 
| 1731 | 1804 | func testCreateBalloon(ctx context.Context, t *testing.T, m *Machine) { | 
| 1732 | 1805 | 	if err := m.CreateBalloon(ctx, testBalloonMemory, testBalloonDeflateOnOom, testStatsPollingIntervals); err != nil { | 
| 1733 | 1806 | 		t.Errorf("Create balloon device failed from testAttachBalloon: %s", err) | 
|  | 
0 commit comments