blob: c812cee6a3e011566e958c63e476d6a8b0adf76f [file] [log] [blame]
Benjamin Gordon2d7bf582017-07-12 10:11:26 -06001# Copyright 2017 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Tests for cros_sdk."""
6
Chris McDonald59650c32021-07-20 15:29:28 -06007import logging
Benjamin Gordon2d7bf582017-07-12 10:11:26 -06008import os
Mike Frysinger5f5c70b2022-07-19 12:55:21 -04009import re
Mike Frysinger66d32cd2019-12-17 14:55:29 -050010import subprocess
Mike Frysinger5f5c70b2022-07-19 12:55:21 -040011import sys
Mike Frysingeredc04912019-11-16 01:30:43 -050012import unittest
Benjamin Gordon2d7bf582017-07-12 10:11:26 -060013
Mike Frysinger5f5c70b2022-07-19 12:55:21 -040014from chromite.lib import constants
Benjamin Gordon2d7bf582017-07-12 10:11:26 -060015from chromite.lib import cros_build_lib
Benjamin Gordon74645232018-05-04 17:40:42 -060016from chromite.lib import cros_sdk_lib
Benjamin Gordon2d7bf582017-07-12 10:11:26 -060017from chromite.lib import cros_test_lib
18from chromite.lib import osutils
Mike Frysingerdaf57b82019-11-23 17:26:51 -050019from chromite.lib import retry_util
Benjamin Gordon2d7bf582017-07-12 10:11:26 -060020from chromite.lib import sudo
Mike Frysingerdaf57b82019-11-23 17:26:51 -050021from chromite.scripts import cros_sdk
Benjamin Gordon2d7bf582017-07-12 10:11:26 -060022
23
Mike Frysingeredc04912019-11-16 01:30:43 -050024# This long decorator triggers a false positive in the docstring test.
25# https://github.com/PyCQA/pylint/issues/3077
26# pylint: disable=bad-docstring-quotes
Alex Klein1699fab2022-09-08 08:46:06 -060027@unittest.skipIf(
28 cros_build_lib.IsInsideChroot(), "Tests only make sense outside the chroot"
29)
Benjamin Gordon03c56e42017-09-11 15:48:39 -040030class CrosSdkPrerequisitesTest(cros_test_lib.TempDirTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -060031 """Tests for required packages on the host machine.
Benjamin Gordon03c56e42017-09-11 15:48:39 -040032
Alex Klein1699fab2022-09-08 08:46:06 -060033 These are not real unit tests. If these tests fail, it means your machine is
34 missing necessary commands to support image-backed chroots. Run cros_sdk in
35 a terminal to get info about what you need to install.
36 """
Benjamin Gordon03c56e42017-09-11 15:48:39 -040037
Alex Klein1699fab2022-09-08 08:46:06 -060038 def testLvmCommandsPresent(self):
39 """Check for commands from the lvm2 package."""
40 with sudo.SudoKeepAlive():
41 cmd = ["lvs", "--version"]
42 result = cros_build_lib.run(cmd, check=False)
43 self.assertEqual(result.returncode, 0)
Benjamin Gordon03c56e42017-09-11 15:48:39 -040044
Alex Klein1699fab2022-09-08 08:46:06 -060045 def testThinProvisioningToolsPresent(self):
46 """Check for commands from the thin-provisioning-tools package."""
47 with sudo.SudoKeepAlive():
48 cmd = ["thin_check", "-V"]
49 result = cros_build_lib.run(cmd, check=False)
50 self.assertEqual(result.returncode, 0)
Benjamin Gordon03c56e42017-09-11 15:48:39 -040051
Alex Klein1699fab2022-09-08 08:46:06 -060052 def testLosetupCommandPresent(self):
53 """Check for commands from the mount package."""
54 with sudo.SudoKeepAlive():
55 cmd = ["losetup", "--help"]
56 result = cros_build_lib.run(cmd, check=False)
57 self.assertEqual(result.returncode, 0)
Benjamin Gordon03c56e42017-09-11 15:48:39 -040058
59
Mike Frysingerdaf57b82019-11-23 17:26:51 -050060class CrosSdkUtilsTest(cros_test_lib.MockTempDirTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -060061 """Tests for misc util funcs."""
Mike Frysingerdaf57b82019-11-23 17:26:51 -050062
Alex Klein1699fab2022-09-08 08:46:06 -060063 def testGetArchStageTarballs(self):
64 """Basic test of GetArchStageTarballs."""
65 self.assertCountEqual(
66 [
67 "https://storage.googleapis.com/chromiumos-sdk/cros-sdk-123.tar.xz",
68 ],
69 cros_sdk.GetArchStageTarballs("123"),
70 )
Mike Frysingerdaf57b82019-11-23 17:26:51 -050071
Alex Klein1699fab2022-09-08 08:46:06 -060072 def testFetchRemoteTarballsEmpty(self):
73 """Test FetchRemoteTarballs with no results."""
74 m = self.PatchObject(retry_util, "RunCurl")
75 with self.assertRaises(ValueError):
76 cros_sdk.FetchRemoteTarballs(self.tempdir, [])
77 m.return_value = cros_build_lib.CompletedProcess(stdout=b"Foo: bar\n")
78 with self.assertRaises(ValueError):
79 cros_sdk.FetchRemoteTarballs(self.tempdir, ["gs://x.tar"])
Mike Frysingerdaf57b82019-11-23 17:26:51 -050080
Alex Klein1699fab2022-09-08 08:46:06 -060081 def testFetchRemoteTarballsSuccess(self):
82 """Test FetchRemoteTarballs with a successful download."""
83 curl = cros_build_lib.CompletedProcess(
84 stdout=(b"HTTP/1.0 200\n" b"Foo: bar\n" b"Content-Length: 100\n")
85 )
86 self.PatchObject(retry_util, "RunCurl", return_value=curl)
87 self.assertEqual(
88 os.path.join(self.tempdir, "tar"),
89 cros_sdk.FetchRemoteTarballs(self.tempdir, ["gs://x/tar"]),
90 )
Mike Frysingerdaf57b82019-11-23 17:26:51 -050091
92
Mike Frysinger5f5c70b2022-07-19 12:55:21 -040093class CrosSdkParserCommandLineTest(cros_test_lib.MockTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -060094 """Tests involving the CLI."""
Mike Frysinger5f5c70b2022-07-19 12:55:21 -040095
Alex Klein1699fab2022-09-08 08:46:06 -060096 # pylint: disable=protected-access
Mike Frysinger5f5c70b2022-07-19 12:55:21 -040097
Alex Klein1699fab2022-09-08 08:46:06 -060098 # A typical sys.argv[0] that cros_sdk sees.
99 ARGV0 = "/home/chronos/chromiumos/chromite/bin/cros_sdk"
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400100
Alex Klein1699fab2022-09-08 08:46:06 -0600101 def setUp(self):
102 self.parser, _ = cros_sdk._CreateParser("1", "2")
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400103
Alex Klein1699fab2022-09-08 08:46:06 -0600104 def testSudoCommand(self):
105 """Verify basic sudo command building works."""
106 # Stabilize the env for testing.
107 for v in (
108 constants.CHROOT_ENVIRONMENT_ALLOWLIST + constants.ENV_PASSTHRU
109 ):
110 os.environ[v] = "value"
111 os.environ["PATH"] = "path"
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400112
Alex Klein1699fab2022-09-08 08:46:06 -0600113 cmd = cros_sdk._SudoCommand()
114 assert cmd[0] == "sudo"
115 assert "CHROMEOS_SUDO_PATH=path" in cmd
116 rlimits = [x for x in cmd if x.startswith("CHROMEOS_SUDO_RLIMITS=")]
117 assert len(rlimits) == 1
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400118
Alex Klein1699fab2022-09-08 08:46:06 -0600119 # Spot check some pass thru vars.
120 assert "GIT_AUTHOR_EMAIL=value" in cmd
121 assert "https_proxy=value" in cmd
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400122
Alex Klein1699fab2022-09-08 08:46:06 -0600123 # Make sure we only pass vars after `sudo`.
124 for i in range(1, len(cmd)):
125 assert "=" in cmd[i]
126 v = cmd[i].split("=", 1)[0]
127 assert re.match(r"^[A-Za-z0-9_]+$", v) is not None
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400128
Alex Klein1699fab2022-09-08 08:46:06 -0600129 def testReexecCommand(self):
130 """Verify reexec command line building."""
131 # Stub sudo logic since we tested it above already.
132 self.PatchObject(cros_sdk, "_SudoCommand", return_value=["sudo"])
133 opts = self.parser.parse_args([])
134 new_cmd = cros_sdk._BuildReExecCommand([self.ARGV0], opts)
135 assert new_cmd == ["sudo", "--", sys.executable, self.ARGV0]
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400136
Alex Klein1699fab2022-09-08 08:46:06 -0600137 def testReexecCommandStrace(self):
138 """Verify reexec command line building w/strace."""
139 # Stub sudo logic since we tested it above already.
140 self.PatchObject(cros_sdk, "_SudoCommand", return_value=["sudo"])
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400141
Alex Klein1699fab2022-09-08 08:46:06 -0600142 # Strace args passed, but not enabled.
143 opts = self.parser.parse_args(["--strace-arguments=-s4096 -v"])
144 new_cmd = cros_sdk._BuildReExecCommand([self.ARGV0], opts)
145 assert new_cmd == ["sudo", "--", sys.executable, self.ARGV0]
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400146
Alex Klein1699fab2022-09-08 08:46:06 -0600147 # Strace enabled.
148 opts = self.parser.parse_args(["--strace"])
149 new_cmd = cros_sdk._BuildReExecCommand([self.ARGV0], opts)
150 assert new_cmd == [
151 "sudo",
152 "--",
153 "strace",
154 "--",
155 sys.executable,
156 self.ARGV0,
157 ]
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400158
Alex Klein1699fab2022-09-08 08:46:06 -0600159 # Strace enabled w/args.
160 opts = self.parser.parse_args(
161 ["--strace", "--strace-arguments=-s4096 -v"]
162 )
163 new_cmd = cros_sdk._BuildReExecCommand([self.ARGV0], opts)
164 assert new_cmd == [
165 "sudo",
166 "--",
167 "strace",
168 "-s4096",
169 "-v",
170 "--",
171 sys.executable,
172 self.ARGV0,
173 ]
Mike Frysinger5f5c70b2022-07-19 12:55:21 -0400174
175
Alex Klein1699fab2022-09-08 08:46:06 -0600176@unittest.skipIf(
177 cros_build_lib.IsInsideChroot(), "Tests only make sense outside the chroot"
178)
Mike Frysingeredc04912019-11-16 01:30:43 -0500179@unittest.skip(
Alex Klein1699fab2022-09-08 08:46:06 -0600180 "These are triggering hangs inside lvm when run through run_tests. "
181 "https://crbug.com/764335"
182)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600183class CrosSdkSnapshotTest(cros_test_lib.TempDirTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600184 """Tests for the snapshot functionality in cros_sdk."""
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600185
Alex Klein1699fab2022-09-08 08:46:06 -0600186 def setUp(self):
187 with sudo.SudoKeepAlive():
188 # Create just enough of a chroot to fool cros_sdk into accepting it.
189 self.chroot = os.path.join(self.tempdir, "chroot")
190 cros_sdk_lib.MountChroot(self.chroot, create=True)
191 logging.debug("Chroot mounted on %s", self.chroot)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600192
Alex Klein1699fab2022-09-08 08:46:06 -0600193 chroot_etc = os.path.join(self.chroot, "etc")
194 osutils.SafeMakedirsNonRoot(chroot_etc)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600195
Alex Klein1699fab2022-09-08 08:46:06 -0600196 self.chroot_version_file = os.path.join(
197 chroot_etc, "cros_chroot_version"
198 )
199 osutils.Touch(self.chroot_version_file, makedirs=True)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600200
Alex Klein1699fab2022-09-08 08:46:06 -0600201 def tearDown(self):
202 with sudo.SudoKeepAlive():
203 cros_sdk_lib.CleanupChrootMount(self.chroot, delete=True)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600204
Alex Klein1699fab2022-09-08 08:46:06 -0600205 def _crosSdk(self, args):
206 cmd = ["cros_sdk", "--chroot", self.chroot]
207 cmd.extend(args)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600208
Alex Klein1699fab2022-09-08 08:46:06 -0600209 try:
210 result = cros_build_lib.run(
211 cmd,
212 print_cmd=False,
213 stdout=True,
214 check=False,
215 stderr=subprocess.STDOUT,
216 )
217 except cros_build_lib.RunCommandError as e:
218 raise SystemExit("Running %r failed!: %s" % (cmd, e))
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600219
Alex Klein1699fab2022-09-08 08:46:06 -0600220 return result.returncode, result.stdout
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600221
Alex Klein1699fab2022-09-08 08:46:06 -0600222 def testSnapshotsRequireImage(self):
223 code, output = self._crosSdk(["--snapshot-list", "--nouse-image"])
224 self.assertNotEqual(code, 0)
225 self.assertIn("Snapshot operations are not compatible with", output)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600226
Alex Klein1699fab2022-09-08 08:46:06 -0600227 code, output = self._crosSdk(
228 ["--snapshot-delete", "test", "--nouse-image"]
229 )
230 self.assertNotEqual(code, 0)
231 self.assertIn("Snapshot operations are not compatible with", output)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600232
Alex Klein1699fab2022-09-08 08:46:06 -0600233 code, output = self._crosSdk(
234 ["--snapshot-create", "test", "--nouse-image"]
235 )
236 self.assertNotEqual(code, 0)
237 self.assertIn("Snapshot operations are not compatible with", output)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600238
Alex Klein1699fab2022-09-08 08:46:06 -0600239 code, output = self._crosSdk(
240 ["--snapshot-restore", "test", "--nouse-image"]
241 )
242 self.assertNotEqual(code, 0)
243 self.assertIn("Snapshot operations are not compatible with", output)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600244
Alex Klein1699fab2022-09-08 08:46:06 -0600245 def testSnapshotWithDeleteChroot(self):
246 code, output = self._crosSdk(["--delete", "--snapshot-list"])
247 self.assertNotEqual(code, 0)
248 self.assertIn("Trying to enter or snapshot the chroot", output)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600249
Alex Klein1699fab2022-09-08 08:46:06 -0600250 code, output = self._crosSdk(["--delete", "--snapshot-delete", "test"])
251 self.assertNotEqual(code, 0)
252 self.assertIn("Trying to enter or snapshot the chroot", output)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600253
Alex Klein1699fab2022-09-08 08:46:06 -0600254 code, output = self._crosSdk(["--delete", "--snapshot-create", "test"])
255 self.assertNotEqual(code, 0)
256 self.assertIn("Trying to enter or snapshot the chroot", output)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600257
Alex Klein1699fab2022-09-08 08:46:06 -0600258 code, output = self._crosSdk(["--delete", "--snapshot-restore", "test"])
259 self.assertNotEqual(code, 0)
260 self.assertIn("Trying to enter or snapshot the chroot", output)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600261
Alex Klein1699fab2022-09-08 08:46:06 -0600262 def testEmptySnapshotList(self):
263 code, output = self._crosSdk(["--snapshot-list"])
264 self.assertEqual(code, 0)
265 self.assertEqual(output, "")
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600266
Alex Klein1699fab2022-09-08 08:46:06 -0600267 def testOneSnapshot(self):
268 code, _ = self._crosSdk(["--snapshot-create", "test"])
269 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600270
Alex Klein1699fab2022-09-08 08:46:06 -0600271 code, output = self._crosSdk(["--snapshot-list"])
272 self.assertEqual(code, 0)
273 self.assertEqual(output.strip(), "test")
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600274
Alex Klein1699fab2022-09-08 08:46:06 -0600275 def testMultipleSnapshots(self):
276 code, _ = self._crosSdk(["--snapshot-create", "test"])
277 self.assertEqual(code, 0)
278 code, _ = self._crosSdk(["--snapshot-create", "test2"])
279 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600280
Alex Klein1699fab2022-09-08 08:46:06 -0600281 code, output = self._crosSdk(["--snapshot-list"])
282 self.assertEqual(code, 0)
283 self.assertSetEqual(set(output.strip().split("\n")), {"test", "test2"})
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600284
Alex Klein1699fab2022-09-08 08:46:06 -0600285 def testCantCreateSameSnapshotTwice(self):
286 code, _ = self._crosSdk(["--snapshot-create", "test"])
287 self.assertEqual(code, 0)
288 code, _ = self._crosSdk(["--snapshot-create", "test"])
289 self.assertNotEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600290
Alex Klein1699fab2022-09-08 08:46:06 -0600291 code, output = self._crosSdk(["--snapshot-list"])
292 self.assertEqual(code, 0)
293 self.assertEqual(output.strip(), "test")
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600294
Alex Klein1699fab2022-09-08 08:46:06 -0600295 def testCreateSnapshotMountsAsNeeded(self):
296 with sudo.SudoKeepAlive():
297 cros_sdk_lib.CleanupChrootMount(self.chroot)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600298
Alex Klein1699fab2022-09-08 08:46:06 -0600299 code, _ = self._crosSdk(["--snapshot-create", "test"])
300 self.assertEqual(code, 0)
301 self.assertExists(self.chroot_version_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600302
Alex Klein1699fab2022-09-08 08:46:06 -0600303 code, output = self._crosSdk(["--snapshot-list"])
304 self.assertEqual(code, 0)
305 self.assertEqual(output.strip(), "test")
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600306
Alex Klein1699fab2022-09-08 08:46:06 -0600307 def testDeleteGoodSnapshot(self):
308 code, _ = self._crosSdk(["--snapshot-create", "test"])
309 self.assertEqual(code, 0)
310 code, _ = self._crosSdk(["--snapshot-create", "test2"])
311 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600312
Alex Klein1699fab2022-09-08 08:46:06 -0600313 code, _ = self._crosSdk(["--snapshot-delete", "test"])
314 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600315
Alex Klein1699fab2022-09-08 08:46:06 -0600316 code, output = self._crosSdk(["--snapshot-list"])
317 self.assertEqual(code, 0)
318 self.assertEqual(output.strip(), "test2")
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600319
Alex Klein1699fab2022-09-08 08:46:06 -0600320 def testDeleteMissingSnapshot(self):
321 code, _ = self._crosSdk(["--snapshot-create", "test"])
322 self.assertEqual(code, 0)
323 code, _ = self._crosSdk(["--snapshot-create", "test2"])
324 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600325
Alex Klein1699fab2022-09-08 08:46:06 -0600326 code, _ = self._crosSdk(["--snapshot-delete", "test3"])
327 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600328
Alex Klein1699fab2022-09-08 08:46:06 -0600329 code, output = self._crosSdk(["--snapshot-list"])
330 self.assertEqual(code, 0)
331 self.assertSetEqual(set(output.strip().split("\n")), {"test", "test2"})
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600332
Alex Klein1699fab2022-09-08 08:46:06 -0600333 def testDeleteAndCreateSnapshot(self):
334 code, _ = self._crosSdk(["--snapshot-create", "test"])
335 self.assertEqual(code, 0)
336 code, _ = self._crosSdk(["--snapshot-create", "test2"])
337 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600338
Alex Klein1699fab2022-09-08 08:46:06 -0600339 code, _ = self._crosSdk(
340 ["--snapshot-create", "test", "--snapshot-delete", "test"]
341 )
342 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600343
Alex Klein1699fab2022-09-08 08:46:06 -0600344 code, output = self._crosSdk(["--snapshot-list"])
345 self.assertEqual(code, 0)
346 self.assertSetEqual(set(output.strip().split("\n")), {"test", "test2"})
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600347
Alex Klein1699fab2022-09-08 08:46:06 -0600348 def testRestoreSnapshot(self):
349 with sudo.SudoKeepAlive():
350 test_file = os.path.join(self.chroot, "etc", "test_file")
351 osutils.Touch(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600352
Alex Klein1699fab2022-09-08 08:46:06 -0600353 code, _ = self._crosSdk(["--snapshot-create", "test"])
354 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600355
Alex Klein1699fab2022-09-08 08:46:06 -0600356 osutils.SafeUnlink(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600357
Alex Klein1699fab2022-09-08 08:46:06 -0600358 code, _ = self._crosSdk(["--snapshot-restore", "test"])
359 self.assertEqual(code, 0)
360 self.assertTrue(cros_sdk_lib.MountChroot(self.chroot, create=False))
361 self.assertExists(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600362
Alex Klein1699fab2022-09-08 08:46:06 -0600363 code, output = self._crosSdk(["--snapshot-list"])
364 self.assertEqual(code, 0)
365 self.assertEqual(output, "")
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600366
Alex Klein1699fab2022-09-08 08:46:06 -0600367 def testRestoreAndCreateSnapshot(self):
368 with sudo.SudoKeepAlive():
369 test_file = os.path.join(self.chroot, "etc", "test_file")
370 osutils.Touch(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600371
Alex Klein1699fab2022-09-08 08:46:06 -0600372 code, _ = self._crosSdk(["--snapshot-create", "test"])
373 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600374
Alex Klein1699fab2022-09-08 08:46:06 -0600375 osutils.SafeUnlink(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600376
Alex Klein1699fab2022-09-08 08:46:06 -0600377 code, _ = self._crosSdk(
378 ["--snapshot-restore", "test", "--snapshot-create", "test"]
379 )
380 self.assertEqual(code, 0)
381 self.assertTrue(cros_sdk_lib.MountChroot(self.chroot, create=False))
382 self.assertExists(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600383
Alex Klein1699fab2022-09-08 08:46:06 -0600384 code, output = self._crosSdk(["--snapshot-list"])
385 self.assertEqual(code, 0)
386 self.assertEqual(output.strip(), "test")
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600387
Alex Klein1699fab2022-09-08 08:46:06 -0600388 def testDeleteCantRestoreSameSnapshot(self):
389 code, _ = self._crosSdk(["--snapshot-create", "test"])
390 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600391
Alex Klein1699fab2022-09-08 08:46:06 -0600392 code, _ = self._crosSdk(
393 ["--snapshot-delete", "test", "--snapshot-restore", "test"]
394 )
395 self.assertNotEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600396
Alex Klein1699fab2022-09-08 08:46:06 -0600397 code, output = self._crosSdk(["--snapshot-list"])
398 self.assertEqual(code, 0)
399 self.assertEqual(output.strip(), "test")
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600400
Alex Klein1699fab2022-09-08 08:46:06 -0600401 def testCantRestoreInvalidSnapshot(self):
402 with sudo.SudoKeepAlive():
403 test_file = os.path.join(self.chroot, "etc", "test_file")
404 osutils.Touch(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600405
Alex Klein1699fab2022-09-08 08:46:06 -0600406 code, _ = self._crosSdk(["--snapshot-restore", "test"])
407 self.assertNotEqual(code, 0)
408 # Failed restore leaves the existing snapshot in place.
409 self.assertExists(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600410
Alex Klein1699fab2022-09-08 08:46:06 -0600411 def testRestoreSnapshotMountsAsNeeded(self):
412 with sudo.SudoKeepAlive():
413 test_file = os.path.join(self.chroot, "etc", "test_file")
414 osutils.Touch(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600415
Alex Klein1699fab2022-09-08 08:46:06 -0600416 code, _ = self._crosSdk(["--snapshot-create", "test"])
417 self.assertEqual(code, 0)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600418
Alex Klein1699fab2022-09-08 08:46:06 -0600419 osutils.SafeUnlink(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600420
Alex Klein1699fab2022-09-08 08:46:06 -0600421 cros_sdk_lib.CleanupChrootMount(self.chroot)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600422
Alex Klein1699fab2022-09-08 08:46:06 -0600423 code, _ = self._crosSdk(["--snapshot-restore", "test"])
424 self.assertEqual(code, 0)
425 self.assertExists(test_file)
Benjamin Gordon2d7bf582017-07-12 10:11:26 -0600426
Alex Klein1699fab2022-09-08 08:46:06 -0600427 code, output = self._crosSdk(["--snapshot-list"])
428 self.assertEqual(code, 0)
429 self.assertEqual(output, "")