blob: 2c875a2553473fe46c8bdb28531bd9e6ea46ede3 [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
Benjamin Gordon2d7bf582017-07-12 10:11:26 -06002# Copyright 2017 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Tests for cros_sdk."""
7
8from __future__ import print_function
9
10import os
11
12from chromite.lib import cros_build_lib
13from chromite.lib import cros_logging as logging
14from chromite.lib import cros_test_lib
15from chromite.lib import osutils
16from chromite.lib import sudo
17
18
Benjamin Gordon03c56e42017-09-11 15:48:39 -040019class CrosSdkPrerequisitesTest(cros_test_lib.TempDirTestCase):
20 """Tests for required packages on the host machine.
21
22 These are not real unit tests. If these tests fail, it means your machine is
23 missing necessary commands to support image-backed chroots. Run cros_sdk in
24 a terminal to get info about what you need to install.
25 """
26
27 def testLvmCommandsPresent(self):
28 """Check for commands from the lvm2 package."""
29 with sudo.SudoKeepAlive():
30 cmd = ['lvs', '--version']
31 result = cros_build_lib.RunCommand(cmd, error_code_ok=True)
32 self.assertEqual(result.returncode, 0)
33
34 def testThinProvisioningToolsPresent(self):
35 """Check for commands from the thin-provisioning-tools package."""
36 with sudo.SudoKeepAlive():
37 cmd = ['thin_check', '-V']
38 result = cros_build_lib.RunCommand(cmd, error_code_ok=True)
39 self.assertEqual(result.returncode, 0)
40
41 def testLosetupCommandPresent(self):
42 """Check for commands from the mount package."""
43 with sudo.SudoKeepAlive():
44 cmd = ['losetup', '--help']
45 result = cros_build_lib.RunCommand(cmd, error_code_ok=True)
46 self.assertEqual(result.returncode, 0)
47
48
Benjamin Gordon2d7bf582017-07-12 10:11:26 -060049# TODO(bmgordon): Figure out how to mock out --create and --enter and then
50# add tests that combine those with snapshots.
51class CrosSdkSnapshotTest(cros_test_lib.TempDirTestCase):
52 """Tests for the snapshot functionality in cros_sdk."""
53
54 def setUp(self):
55 with sudo.SudoKeepAlive():
56 # Create just enough of a chroot to fool cros_sdk into accepting it.
57 self.chroot = os.path.join(self.tempdir, 'chroot')
58 cros_build_lib.MountChroot(self.chroot, create=True)
59 logging.debug('Chroot mounted on %s', self.chroot)
60
61 chroot_etc = os.path.join(self.chroot, 'etc')
62 osutils.SafeMakedirsNonRoot(chroot_etc)
63
64 self.chroot_version_file = os.path.join(chroot_etc, 'cros_chroot_version')
65 osutils.Touch(self.chroot_version_file, makedirs=True)
66
67 def tearDown(self):
68 with sudo.SudoKeepAlive():
69 cros_build_lib.CleanupChrootMount(self.chroot, delete_image=True)
70
71 def _crosSdk(self, args):
72 cmd = ['cros_sdk', '--chroot', self.chroot]
73 cmd.extend(args)
74
75 try:
76 result = cros_build_lib.RunCommand(
77 cmd, print_cmd=False, capture_output=True, error_code_ok=True,
78 combine_stdout_stderr=True)
79 except cros_build_lib.RunCommandError as e:
80 raise SystemExit('Running %r failed!: %s' % (cmd, e))
81
82 return result.returncode, result.output
83
84 def testSnapshotsRequireImage(self):
85 code, output = self._crosSdk(['--snapshot-list', '--nouse-image'])
86 self.assertNotEqual(code, 0)
87 self.assertIn('Snapshot operations are not compatible with', output)
88
89 code, output = self._crosSdk(['--snapshot-delete', 'test', '--nouse-image'])
90 self.assertNotEqual(code, 0)
91 self.assertIn('Snapshot operations are not compatible with', output)
92
93 code, output = self._crosSdk(['--snapshot-create', 'test', '--nouse-image'])
94 self.assertNotEqual(code, 0)
95 self.assertIn('Snapshot operations are not compatible with', output)
96
97 code, output = self._crosSdk(['--snapshot-restore', 'test',
98 '--nouse-image'])
99 self.assertNotEqual(code, 0)
100 self.assertIn('Snapshot operations are not compatible with', output)
101
102 def testSnapshotWithDeleteChroot(self):
103 code, output = self._crosSdk(['--delete', '--snapshot-list'])
104 self.assertNotEqual(code, 0)
105 self.assertIn('Trying to enter or snapshot the chroot', output)
106
107 code, output = self._crosSdk(['--delete', '--snapshot-delete', 'test'])
108 self.assertNotEqual(code, 0)
109 self.assertIn('Trying to enter or snapshot the chroot', output)
110
111 code, output = self._crosSdk(['--delete', '--snapshot-create', 'test'])
112 self.assertNotEqual(code, 0)
113 self.assertIn('Trying to enter or snapshot the chroot', output)
114
115 code, output = self._crosSdk(['--delete', '--snapshot-restore', 'test'])
116 self.assertNotEqual(code, 0)
117 self.assertIn('Trying to enter or snapshot the chroot', output)
118
119 def testEmptySnapshotList(self):
120 code, output = self._crosSdk(['--snapshot-list'])
121 self.assertEqual(code, 0)
122 self.assertEqual(output, '')
123
124 def testOneSnapshot(self):
125 code, _ = self._crosSdk(['--snapshot-create', 'test'])
126 self.assertEqual(code, 0)
127
128 code, output = self._crosSdk(['--snapshot-list'])
129 self.assertEqual(code, 0)
130 self.assertEqual(output.strip(), 'test')
131
132 def testMultipleSnapshots(self):
133 code, _ = self._crosSdk(['--snapshot-create', 'test'])
134 self.assertEqual(code, 0)
135 code, _ = self._crosSdk(['--snapshot-create', 'test2'])
136 self.assertEqual(code, 0)
137
138 code, output = self._crosSdk(['--snapshot-list'])
139 self.assertEqual(code, 0)
140 self.assertSetEqual(set(output.strip().split('\n')), {'test', 'test2'})
141
142 def testCantCreateSameSnapshotTwice(self):
143 code, _ = self._crosSdk(['--snapshot-create', 'test'])
144 self.assertEqual(code, 0)
145 code, _ = self._crosSdk(['--snapshot-create', 'test'])
146 self.assertNotEqual(code, 0)
147
148 code, output = self._crosSdk(['--snapshot-list'])
149 self.assertEqual(code, 0)
150 self.assertEqual(output.strip(), 'test')
151
152 def testCreateSnapshotMountsAsNeeded(self):
153 with sudo.SudoKeepAlive():
154 cros_build_lib.CleanupChrootMount(self.chroot)
155
156 code, _ = self._crosSdk(['--snapshot-create', 'test'])
157 self.assertEqual(code, 0)
158 self.assertTrue(os.path.exists(self.chroot_version_file))
159
160 code, output = self._crosSdk(['--snapshot-list'])
161 self.assertEqual(code, 0)
162 self.assertEqual(output.strip(), 'test')
163
164 def testDeleteGoodSnapshot(self):
165 code, _ = self._crosSdk(['--snapshot-create', 'test'])
166 self.assertEqual(code, 0)
167 code, _ = self._crosSdk(['--snapshot-create', 'test2'])
168 self.assertEqual(code, 0)
169
170 code, _ = self._crosSdk(['--snapshot-delete', 'test'])
171 self.assertEqual(code, 0)
172
173 code, output = self._crosSdk(['--snapshot-list'])
174 self.assertEqual(code, 0)
175 self.assertEqual(output.strip(), 'test2')
176
177 def testDeleteMissingSnapshot(self):
178 code, _ = self._crosSdk(['--snapshot-create', 'test'])
179 self.assertEqual(code, 0)
180 code, _ = self._crosSdk(['--snapshot-create', 'test2'])
181 self.assertEqual(code, 0)
182
183 code, _ = self._crosSdk(['--snapshot-delete', 'test3'])
184 self.assertEqual(code, 0)
185
186 code, output = self._crosSdk(['--snapshot-list'])
187 self.assertEqual(code, 0)
188 self.assertSetEqual(set(output.strip().split('\n')), {'test', 'test2'})
189
190 def testDeleteAndCreateSnapshot(self):
191 code, _ = self._crosSdk(['--snapshot-create', 'test'])
192 self.assertEqual(code, 0)
193 code, _ = self._crosSdk(['--snapshot-create', 'test2'])
194 self.assertEqual(code, 0)
195
196 code, _ = self._crosSdk(['--snapshot-create', 'test',
197 '--snapshot-delete', 'test'])
198 self.assertEqual(code, 0)
199
200 code, output = self._crosSdk(['--snapshot-list'])
201 self.assertEqual(code, 0)
202 self.assertSetEqual(set(output.strip().split('\n')), {'test', 'test2'})
203
204 def testRestoreSnapshot(self):
205 with sudo.SudoKeepAlive():
206 test_file = os.path.join(self.chroot, 'etc', 'test_file')
207 osutils.Touch(test_file)
208
209 code, _ = self._crosSdk(['--snapshot-create', 'test'])
210 self.assertEqual(code, 0)
211
212 osutils.SafeUnlink(test_file)
213
214 code, _ = self._crosSdk(['--snapshot-restore', 'test'])
215 self.assertEqual(code, 0)
216 self.assertTrue(cros_build_lib.MountChroot(self.chroot, create=False))
217 self.assertTrue(os.path.exists(test_file))
218
219 code, output = self._crosSdk(['--snapshot-list'])
220 self.assertEqual(code, 0)
221 self.assertEqual(output, '')
222
223 def testRestoreAndCreateSnapshot(self):
224 with sudo.SudoKeepAlive():
225 test_file = os.path.join(self.chroot, 'etc', 'test_file')
226 osutils.Touch(test_file)
227
228 code, _ = self._crosSdk(['--snapshot-create', 'test'])
229 self.assertEqual(code, 0)
230
231 osutils.SafeUnlink(test_file)
232
233 code, _ = self._crosSdk(['--snapshot-restore', 'test',
234 '--snapshot-create', 'test'])
235 self.assertEqual(code, 0)
236 self.assertTrue(cros_build_lib.MountChroot(self.chroot, create=False))
237 self.assertTrue(os.path.exists(test_file))
238
239 code, output = self._crosSdk(['--snapshot-list'])
240 self.assertEqual(code, 0)
241 self.assertEqual(output.strip(), 'test')
242
243 def testDeleteCantRestoreSameSnapshot(self):
244 code, _ = self._crosSdk(['--snapshot-create', 'test'])
245 self.assertEqual(code, 0)
246
247 code, _ = self._crosSdk(['--snapshot-delete', 'test',
248 '--snapshot-restore', 'test'])
249 self.assertNotEqual(code, 0)
250
251 code, output = self._crosSdk(['--snapshot-list'])
252 self.assertEqual(code, 0)
253 self.assertEqual(output.strip(), 'test')
254
255 def testCantRestoreInvalidSnapshot(self):
256 with sudo.SudoKeepAlive():
257 test_file = os.path.join(self.chroot, 'etc', 'test_file')
258 osutils.Touch(test_file)
259
260 code, _ = self._crosSdk(['--snapshot-restore', 'test'])
261 self.assertNotEqual(code, 0)
262 # Failed restore leaves the existing snapshot in place.
263 self.assertTrue(os.path.exists(test_file))
264
265 def testRestoreSnapshotMountsAsNeeded(self):
266 with sudo.SudoKeepAlive():
267 test_file = os.path.join(self.chroot, 'etc', 'test_file')
268 osutils.Touch(test_file)
269
270 code, _ = self._crosSdk(['--snapshot-create', 'test'])
271 self.assertEqual(code, 0)
272
273 osutils.SafeUnlink(test_file)
274
275 cros_build_lib.CleanupChrootMount(self.chroot)
276
277 code, _ = self._crosSdk(['--snapshot-restore', 'test'])
278 self.assertEqual(code, 0)
279 self.assertTrue(os.path.exists(test_file))
280
281 code, output = self._crosSdk(['--snapshot-list'])
282 self.assertEqual(code, 0)
283 self.assertEqual(output, '')