blob: 70eed5cd246100b1d917c518fb7bcd0366d8e02e [file] [log] [blame]
David Pursellf1d16a62015-03-25 13:31:04 -07001# Copyright 2015 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"""Unit tests for the flash module."""
6
7from __future__ import print_function
8
9import mock
10import os
11
12from chromite.cli import flash
13from chromite.lib import brick_lib
14from chromite.lib import commandline
15from chromite.lib import cros_build_lib
16from chromite.lib import cros_test_lib
17from chromite.lib import dev_server_wrapper
18from chromite.lib import partial_mock
19from chromite.lib import remote_access
20
21
22class RemoteDeviceUpdaterMock(partial_mock.PartialCmdMock):
23 """Mock out RemoteDeviceUpdater."""
24 TARGET = 'chromite.cli.flash.RemoteDeviceUpdater'
25 ATTRS = ('UpdateStateful', 'UpdateRootfs', 'SetupRootfsUpdate', 'Verify')
26
27 def __init__(self):
28 partial_mock.PartialCmdMock.__init__(self)
29
30 def UpdateStateful(self, _inst, *_args, **_kwargs):
31 """Mock out UpdateStateful."""
32
33 def UpdateRootfs(self, _inst, *_args, **_kwargs):
34 """Mock out UpdateRootfs."""
35
36 def SetupRootfsUpdate(self, _inst, *_args, **_kwargs):
37 """Mock out SetupRootfsUpdate."""
38
39 def Verify(self, _inst, *_args, **_kwargs):
40 """Mock out SetupRootfsUpdate."""
41
42
43class BrickMock(partial_mock.PartialMock):
44 """Mock out brick_lib.Brick."""
45 TARGET = 'chromite.lib.brick_lib.Brick'
46 ATTRS = ('Inherits')
47
48 def __init__(self):
49 partial_mock.PartialMock.__init__(self)
50
51 def Inherits(self, _inst, *_args, **_kwargs):
52 """Mock out Inherits."""
53 return True
54
55
56class RemoteDeviceUpdaterTest(cros_test_lib.MockTempDirTestCase):
57 """Test the flow of flash.Flash() with RemoteDeviceUpdater."""
58
59 IMAGE = '/path/to/image'
60 DEVICE = commandline.Device(scheme=commandline.DEVICE_SCHEME_SSH,
61 hostname='1.1.1.1')
62
63 def setUp(self):
64 """Patches objects."""
65 self.updater_mock = self.StartPatcher(RemoteDeviceUpdaterMock())
66 self.PatchObject(dev_server_wrapper, 'GenerateXbuddyRequest',
67 return_value='xbuddy/local/latest')
68 self.PatchObject(dev_server_wrapper, 'DevServerWrapper')
69 self.PatchObject(dev_server_wrapper, 'GetImagePathWithXbuddy',
70 return_value='taco-paladin/R36/chromiumos_test_image.bin')
71 self.PatchObject(dev_server_wrapper, 'GetUpdatePayloads')
72 self.PatchObject(remote_access, 'CHECK_INTERVAL', new=0)
73 self.PatchObject(remote_access, 'ChromiumOSDevice')
74
75 def testUpdateAll(self):
76 """Tests that update methods are called correctly."""
77 proj = BrickMock()
78 with mock.patch('os.path.exists', return_value=True):
79 with mock.patch('chromite.lib.brick_lib.FindBrickByName',
80 return_value=proj):
81 flash.Flash(self.DEVICE, self.IMAGE)
82 self.assertTrue(self.updater_mock.patched['UpdateStateful'].called)
83 self.assertTrue(self.updater_mock.patched['UpdateRootfs'].called)
84
85 def testUpdateStateful(self):
86 """Tests that update methods are called correctly."""
87 proj = BrickMock()
88 with mock.patch('os.path.exists', return_value=True):
89 with mock.patch('chromite.lib.brick_lib.FindBrickByName',
90 return_value=proj):
91 flash.Flash(self.DEVICE, self.IMAGE, rootfs_update=False)
92 self.assertTrue(self.updater_mock.patched['UpdateStateful'].called)
93 self.assertFalse(self.updater_mock.patched['UpdateRootfs'].called)
94
95 def testUpdateRootfs(self):
96 """Tests that update methods are called correctly."""
97 proj = BrickMock()
98 with mock.patch('os.path.exists', return_value=True):
99 with mock.patch('chromite.lib.brick_lib.FindBrickByName',
100 return_value=proj):
101 flash.Flash(self.DEVICE, self.IMAGE, stateful_update=False)
102 self.assertFalse(self.updater_mock.patched['UpdateStateful'].called)
103 self.assertTrue(self.updater_mock.patched['UpdateRootfs'].called)
104
105 def testMissingPayloads(self):
106 """Tests we raise FlashError when payloads are missing."""
107 with mock.patch('os.path.exists', return_value=False):
108 self.assertRaises(flash.FlashError, flash.Flash, self.DEVICE, self.IMAGE)
109
110 def testProjectSdk(self):
111 """Tests that Project SDK flashing invoked as expected."""
112 proj = BrickMock()
113 with mock.patch('os.path.exists', return_value=True):
114 with mock.patch('chromite.lib.brick_lib.FindBrickByName',
115 return_value=proj):
116 with mock.patch('chromite.lib.project_sdk.FindVersion',
117 return_value='1.2.3'):
118 flash.Flash(self.DEVICE, self.IMAGE, project_sdk_image=True)
119 dev_server_wrapper.GetImagePathWithXbuddy.assert_called_with(
120 'project_sdk', mock.ANY, version='1.2.3', static_dir=mock.ANY,
121 lookup_only=True)
122 self.assertTrue(self.updater_mock.patched['UpdateStateful'].called)
123 self.assertTrue(self.updater_mock.patched['UpdateRootfs'].called)
124
125
126class USBImagerMock(partial_mock.PartialCmdMock):
127 """Mock out USBImager."""
128 TARGET = 'chromite.cli.flash.USBImager'
129 ATTRS = ('CopyImageToDevice', 'InstallImageToDevice',
130 'ChooseRemovableDevice', 'ListAllRemovableDevices',
131 'GetRemovableDeviceDescription', 'IsFilePathGPTDiskImage')
132 VALID_IMAGE = True
133
134 def __init__(self):
135 partial_mock.PartialCmdMock.__init__(self)
136
137 def CopyImageToDevice(self, _inst, *_args, **_kwargs):
138 """Mock out CopyImageToDevice."""
139
140 def InstallImageToDevice(self, _inst, *_args, **_kwargs):
141 """Mock out InstallImageToDevice."""
142
143 def ChooseRemovableDevice(self, _inst, *_args, **_kwargs):
144 """Mock out ChooseRemovableDevice."""
145
146 def ListAllRemovableDevices(self, _inst, *_args, **_kwargs):
147 """Mock out ListAllRemovableDevices."""
148 return ['foo', 'taco', 'milk']
149
150 def GetRemovableDeviceDescription(self, _inst, *_args, **_kwargs):
151 """Mock out GetRemovableDeviceDescription."""
152
153 def IsFilePathGPTDiskImage(self, _inst, *_args, **_kwargs):
154 """Mock out IsFilePathGPTDiskImage."""
155 return self.VALID_IMAGE
156
157
158class USBImagerTest(cros_test_lib.MockTempDirTestCase):
159 """Test the flow of flash.Flash() with USBImager."""
160 IMAGE = '/path/to/image'
161
162 def Device(self, path):
163 """Create a USB device for passing to flash.Flash()."""
164 return commandline.Device(scheme=commandline.DEVICE_SCHEME_USB,
165 path=path)
166
167 def setUp(self):
168 """Patches objects."""
169 self.usb_mock = USBImagerMock()
170 self.imager_mock = self.StartPatcher(self.usb_mock)
171 self.PatchObject(dev_server_wrapper, 'GenerateXbuddyRequest',
172 return_value='xbuddy/local/latest')
173 self.PatchObject(dev_server_wrapper, 'DevServerWrapper')
174 self.PatchObject(dev_server_wrapper, 'GetImagePathWithXbuddy',
175 return_value='taco-paladin/R36/chromiumos_test_image.bin')
176 self.PatchObject(os.path, 'exists', return_value=True)
177 self.PatchObject(brick_lib, 'FindBrickInPath', return_value=None)
178
179 def testLocalImagePathCopy(self):
180 """Tests that imaging methods are called correctly."""
181 with mock.patch('os.path.isfile', return_value=True):
182 flash.Flash(self.Device('/dev/foo'), self.IMAGE)
183 self.assertTrue(self.imager_mock.patched['CopyImageToDevice'].called)
184
185 def testLocalImagePathInstall(self):
186 """Tests that imaging methods are called correctly."""
187 with mock.patch('os.path.isfile', return_value=True):
188 flash.Flash(self.Device('/dev/foo'), self.IMAGE, board='taco',
189 install=True)
190 self.assertTrue(self.imager_mock.patched['InstallImageToDevice'].called)
191
192 def testLocalBadImagePath(self):
193 """Tests that using an image not having the magic bytes has prompt."""
194 self.usb_mock.VALID_IMAGE = False
195 with mock.patch('os.path.isfile', return_value=True):
196 with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
197 mock_prompt.return_value = False
198 flash.Flash(self.Device('/dev/foo'), self.IMAGE)
199 self.assertTrue(mock_prompt.called)
200
201 def testNonLocalImagePath(self):
202 """Tests that we try to get the image path using xbuddy."""
203 with mock.patch.object(
204 dev_server_wrapper,
205 'GetImagePathWithXbuddy',
206 return_value='translated/xbuddy/path') as mock_xbuddy:
207 with mock.patch('os.path.isfile', return_value=False):
208 with mock.patch('os.path.isdir', return_value=False):
209 flash.Flash(self.Device('/dev/foo'), self.IMAGE)
210 self.assertTrue(mock_xbuddy.called)
211
212 def testConfirmNonRemovableDevice(self):
213 """Tests that we ask user to confirm if the device is not removable."""
214 with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
215 flash.Flash(self.Device('/dev/dummy'), self.IMAGE)
216 self.assertTrue(mock_prompt.called)
217
218 def testSkipPromptNonRemovableDevice(self):
219 """Tests that we skip the prompt for non-removable with --yes."""
220 with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
221 flash.Flash(self.Device('/dev/dummy'), self.IMAGE, yes=True)
222 self.assertFalse(mock_prompt.called)
223
224 def testChooseRemovableDevice(self):
225 """Tests that we ask user to choose a device if none is given."""
226 flash.Flash(self.Device(''), self.IMAGE)
227 self.assertTrue(self.imager_mock.patched['ChooseRemovableDevice'].called)