blob: 52d318c45e7329956294a25030f22619ff9ddaba [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
7from __future__ import print_function
8
9import os
10
11from chromite.lib import cros_build_lib
12from chromite.lib import cros_logging as logging
13from chromite.lib import cros_test_lib
14from chromite.lib import osutils
15from chromite.lib import sudo
16
17
18# TODO(bmgordon): Figure out how to mock out --create and --enter and then
19# add tests that combine those with snapshots.
20class CrosSdkSnapshotTest(cros_test_lib.TempDirTestCase):
21 """Tests for the snapshot functionality in cros_sdk."""
22
23 def setUp(self):
24 with sudo.SudoKeepAlive():
25 # Create just enough of a chroot to fool cros_sdk into accepting it.
26 self.chroot = os.path.join(self.tempdir, 'chroot')
27 cros_build_lib.MountChroot(self.chroot, create=True)
28 logging.debug('Chroot mounted on %s', self.chroot)
29
30 chroot_etc = os.path.join(self.chroot, 'etc')
31 osutils.SafeMakedirsNonRoot(chroot_etc)
32
33 self.chroot_version_file = os.path.join(chroot_etc, 'cros_chroot_version')
34 osutils.Touch(self.chroot_version_file, makedirs=True)
35
36 def tearDown(self):
37 with sudo.SudoKeepAlive():
38 cros_build_lib.CleanupChrootMount(self.chroot, delete_image=True)
39
40 def _crosSdk(self, args):
41 cmd = ['cros_sdk', '--chroot', self.chroot]
42 cmd.extend(args)
43
44 try:
45 result = cros_build_lib.RunCommand(
46 cmd, print_cmd=False, capture_output=True, error_code_ok=True,
47 combine_stdout_stderr=True)
48 except cros_build_lib.RunCommandError as e:
49 raise SystemExit('Running %r failed!: %s' % (cmd, e))
50
51 return result.returncode, result.output
52
53 def testSnapshotsRequireImage(self):
54 code, output = self._crosSdk(['--snapshot-list', '--nouse-image'])
55 self.assertNotEqual(code, 0)
56 self.assertIn('Snapshot operations are not compatible with', output)
57
58 code, output = self._crosSdk(['--snapshot-delete', 'test', '--nouse-image'])
59 self.assertNotEqual(code, 0)
60 self.assertIn('Snapshot operations are not compatible with', output)
61
62 code, output = self._crosSdk(['--snapshot-create', 'test', '--nouse-image'])
63 self.assertNotEqual(code, 0)
64 self.assertIn('Snapshot operations are not compatible with', output)
65
66 code, output = self._crosSdk(['--snapshot-restore', 'test',
67 '--nouse-image'])
68 self.assertNotEqual(code, 0)
69 self.assertIn('Snapshot operations are not compatible with', output)
70
71 def testSnapshotWithDeleteChroot(self):
72 code, output = self._crosSdk(['--delete', '--snapshot-list'])
73 self.assertNotEqual(code, 0)
74 self.assertIn('Trying to enter or snapshot the chroot', output)
75
76 code, output = self._crosSdk(['--delete', '--snapshot-delete', 'test'])
77 self.assertNotEqual(code, 0)
78 self.assertIn('Trying to enter or snapshot the chroot', output)
79
80 code, output = self._crosSdk(['--delete', '--snapshot-create', 'test'])
81 self.assertNotEqual(code, 0)
82 self.assertIn('Trying to enter or snapshot the chroot', output)
83
84 code, output = self._crosSdk(['--delete', '--snapshot-restore', 'test'])
85 self.assertNotEqual(code, 0)
86 self.assertIn('Trying to enter or snapshot the chroot', output)
87
88 def testEmptySnapshotList(self):
89 code, output = self._crosSdk(['--snapshot-list'])
90 self.assertEqual(code, 0)
91 self.assertEqual(output, '')
92
93 def testOneSnapshot(self):
94 code, _ = self._crosSdk(['--snapshot-create', 'test'])
95 self.assertEqual(code, 0)
96
97 code, output = self._crosSdk(['--snapshot-list'])
98 self.assertEqual(code, 0)
99 self.assertEqual(output.strip(), 'test')
100
101 def testMultipleSnapshots(self):
102 code, _ = self._crosSdk(['--snapshot-create', 'test'])
103 self.assertEqual(code, 0)
104 code, _ = self._crosSdk(['--snapshot-create', 'test2'])
105 self.assertEqual(code, 0)
106
107 code, output = self._crosSdk(['--snapshot-list'])
108 self.assertEqual(code, 0)
109 self.assertSetEqual(set(output.strip().split('\n')), {'test', 'test2'})
110
111 def testCantCreateSameSnapshotTwice(self):
112 code, _ = self._crosSdk(['--snapshot-create', 'test'])
113 self.assertEqual(code, 0)
114 code, _ = self._crosSdk(['--snapshot-create', 'test'])
115 self.assertNotEqual(code, 0)
116
117 code, output = self._crosSdk(['--snapshot-list'])
118 self.assertEqual(code, 0)
119 self.assertEqual(output.strip(), 'test')
120
121 def testCreateSnapshotMountsAsNeeded(self):
122 with sudo.SudoKeepAlive():
123 cros_build_lib.CleanupChrootMount(self.chroot)
124
125 code, _ = self._crosSdk(['--snapshot-create', 'test'])
126 self.assertEqual(code, 0)
127 self.assertTrue(os.path.exists(self.chroot_version_file))
128
129 code, output = self._crosSdk(['--snapshot-list'])
130 self.assertEqual(code, 0)
131 self.assertEqual(output.strip(), 'test')
132
133 def testDeleteGoodSnapshot(self):
134 code, _ = self._crosSdk(['--snapshot-create', 'test'])
135 self.assertEqual(code, 0)
136 code, _ = self._crosSdk(['--snapshot-create', 'test2'])
137 self.assertEqual(code, 0)
138
139 code, _ = self._crosSdk(['--snapshot-delete', 'test'])
140 self.assertEqual(code, 0)
141
142 code, output = self._crosSdk(['--snapshot-list'])
143 self.assertEqual(code, 0)
144 self.assertEqual(output.strip(), 'test2')
145
146 def testDeleteMissingSnapshot(self):
147 code, _ = self._crosSdk(['--snapshot-create', 'test'])
148 self.assertEqual(code, 0)
149 code, _ = self._crosSdk(['--snapshot-create', 'test2'])
150 self.assertEqual(code, 0)
151
152 code, _ = self._crosSdk(['--snapshot-delete', 'test3'])
153 self.assertEqual(code, 0)
154
155 code, output = self._crosSdk(['--snapshot-list'])
156 self.assertEqual(code, 0)
157 self.assertSetEqual(set(output.strip().split('\n')), {'test', 'test2'})
158
159 def testDeleteAndCreateSnapshot(self):
160 code, _ = self._crosSdk(['--snapshot-create', 'test'])
161 self.assertEqual(code, 0)
162 code, _ = self._crosSdk(['--snapshot-create', 'test2'])
163 self.assertEqual(code, 0)
164
165 code, _ = self._crosSdk(['--snapshot-create', 'test',
166 '--snapshot-delete', 'test'])
167 self.assertEqual(code, 0)
168
169 code, output = self._crosSdk(['--snapshot-list'])
170 self.assertEqual(code, 0)
171 self.assertSetEqual(set(output.strip().split('\n')), {'test', 'test2'})
172
173 def testRestoreSnapshot(self):
174 with sudo.SudoKeepAlive():
175 test_file = os.path.join(self.chroot, 'etc', 'test_file')
176 osutils.Touch(test_file)
177
178 code, _ = self._crosSdk(['--snapshot-create', 'test'])
179 self.assertEqual(code, 0)
180
181 osutils.SafeUnlink(test_file)
182
183 code, _ = self._crosSdk(['--snapshot-restore', 'test'])
184 self.assertEqual(code, 0)
185 self.assertTrue(cros_build_lib.MountChroot(self.chroot, create=False))
186 self.assertTrue(os.path.exists(test_file))
187
188 code, output = self._crosSdk(['--snapshot-list'])
189 self.assertEqual(code, 0)
190 self.assertEqual(output, '')
191
192 def testRestoreAndCreateSnapshot(self):
193 with sudo.SudoKeepAlive():
194 test_file = os.path.join(self.chroot, 'etc', 'test_file')
195 osutils.Touch(test_file)
196
197 code, _ = self._crosSdk(['--snapshot-create', 'test'])
198 self.assertEqual(code, 0)
199
200 osutils.SafeUnlink(test_file)
201
202 code, _ = self._crosSdk(['--snapshot-restore', 'test',
203 '--snapshot-create', 'test'])
204 self.assertEqual(code, 0)
205 self.assertTrue(cros_build_lib.MountChroot(self.chroot, create=False))
206 self.assertTrue(os.path.exists(test_file))
207
208 code, output = self._crosSdk(['--snapshot-list'])
209 self.assertEqual(code, 0)
210 self.assertEqual(output.strip(), 'test')
211
212 def testDeleteCantRestoreSameSnapshot(self):
213 code, _ = self._crosSdk(['--snapshot-create', 'test'])
214 self.assertEqual(code, 0)
215
216 code, _ = self._crosSdk(['--snapshot-delete', 'test',
217 '--snapshot-restore', 'test'])
218 self.assertNotEqual(code, 0)
219
220 code, output = self._crosSdk(['--snapshot-list'])
221 self.assertEqual(code, 0)
222 self.assertEqual(output.strip(), 'test')
223
224 def testCantRestoreInvalidSnapshot(self):
225 with sudo.SudoKeepAlive():
226 test_file = os.path.join(self.chroot, 'etc', 'test_file')
227 osutils.Touch(test_file)
228
229 code, _ = self._crosSdk(['--snapshot-restore', 'test'])
230 self.assertNotEqual(code, 0)
231 # Failed restore leaves the existing snapshot in place.
232 self.assertTrue(os.path.exists(test_file))
233
234 def testRestoreSnapshotMountsAsNeeded(self):
235 with sudo.SudoKeepAlive():
236 test_file = os.path.join(self.chroot, 'etc', 'test_file')
237 osutils.Touch(test_file)
238
239 code, _ = self._crosSdk(['--snapshot-create', 'test'])
240 self.assertEqual(code, 0)
241
242 osutils.SafeUnlink(test_file)
243
244 cros_build_lib.CleanupChrootMount(self.chroot)
245
246 code, _ = self._crosSdk(['--snapshot-restore', 'test'])
247 self.assertEqual(code, 0)
248 self.assertTrue(os.path.exists(test_file))
249
250 code, output = self._crosSdk(['--snapshot-list'])
251 self.assertEqual(code, 0)
252 self.assertEqual(output, '')