blob: 8ec90984ecfd25bbb81585df29be1000ed2628cc [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
David Pursellf1d16a62015-03-25 13:31:04 -070043class RemoteDeviceUpdaterTest(cros_test_lib.MockTempDirTestCase):
44 """Test the flow of flash.Flash() with RemoteDeviceUpdater."""
45
46 IMAGE = '/path/to/image'
47 DEVICE = commandline.Device(scheme=commandline.DEVICE_SCHEME_SSH,
48 hostname='1.1.1.1')
49
50 def setUp(self):
51 """Patches objects."""
52 self.updater_mock = self.StartPatcher(RemoteDeviceUpdaterMock())
53 self.PatchObject(dev_server_wrapper, 'GenerateXbuddyRequest',
54 return_value='xbuddy/local/latest')
55 self.PatchObject(dev_server_wrapper, 'DevServerWrapper')
56 self.PatchObject(dev_server_wrapper, 'GetImagePathWithXbuddy',
57 return_value='taco-paladin/R36/chromiumos_test_image.bin')
58 self.PatchObject(dev_server_wrapper, 'GetUpdatePayloads')
59 self.PatchObject(remote_access, 'CHECK_INTERVAL', new=0)
60 self.PatchObject(remote_access, 'ChromiumOSDevice')
61
62 def testUpdateAll(self):
63 """Tests that update methods are called correctly."""
David Pursellf1d16a62015-03-25 13:31:04 -070064 with mock.patch('os.path.exists', return_value=True):
Bertrand SIMONNETb34a98b2015-04-22 14:30:04 -070065 flash.Flash(self.DEVICE, self.IMAGE)
66 self.assertTrue(self.updater_mock.patched['UpdateStateful'].called)
67 self.assertTrue(self.updater_mock.patched['UpdateRootfs'].called)
David Pursellf1d16a62015-03-25 13:31:04 -070068
69 def testUpdateStateful(self):
70 """Tests that update methods are called correctly."""
David Pursellf1d16a62015-03-25 13:31:04 -070071 with mock.patch('os.path.exists', return_value=True):
Bertrand SIMONNETb34a98b2015-04-22 14:30:04 -070072 flash.Flash(self.DEVICE, self.IMAGE, rootfs_update=False)
73 self.assertTrue(self.updater_mock.patched['UpdateStateful'].called)
74 self.assertFalse(self.updater_mock.patched['UpdateRootfs'].called)
David Pursellf1d16a62015-03-25 13:31:04 -070075
76 def testUpdateRootfs(self):
77 """Tests that update methods are called correctly."""
David Pursellf1d16a62015-03-25 13:31:04 -070078 with mock.patch('os.path.exists', return_value=True):
Bertrand SIMONNETb34a98b2015-04-22 14:30:04 -070079 flash.Flash(self.DEVICE, self.IMAGE, stateful_update=False)
80 self.assertFalse(self.updater_mock.patched['UpdateStateful'].called)
81 self.assertTrue(self.updater_mock.patched['UpdateRootfs'].called)
David Pursellf1d16a62015-03-25 13:31:04 -070082
83 def testMissingPayloads(self):
84 """Tests we raise FlashError when payloads are missing."""
85 with mock.patch('os.path.exists', return_value=False):
86 self.assertRaises(flash.FlashError, flash.Flash, self.DEVICE, self.IMAGE)
87
88 def testProjectSdk(self):
89 """Tests that Project SDK flashing invoked as expected."""
David Pursellf1d16a62015-03-25 13:31:04 -070090 with mock.patch('os.path.exists', return_value=True):
Bertrand SIMONNETb34a98b2015-04-22 14:30:04 -070091 with mock.patch('chromite.lib.project_sdk.FindVersion',
92 return_value='1.2.3'):
93 flash.Flash(self.DEVICE, self.IMAGE, project_sdk_image=True)
94 dev_server_wrapper.GetImagePathWithXbuddy.assert_called_with(
95 'project_sdk', mock.ANY, version='1.2.3', static_dir=mock.ANY,
96 lookup_only=True)
97 self.assertTrue(self.updater_mock.patched['UpdateStateful'].called)
98 self.assertTrue(self.updater_mock.patched['UpdateRootfs'].called)
David Pursellf1d16a62015-03-25 13:31:04 -070099
100
101class USBImagerMock(partial_mock.PartialCmdMock):
102 """Mock out USBImager."""
103 TARGET = 'chromite.cli.flash.USBImager'
104 ATTRS = ('CopyImageToDevice', 'InstallImageToDevice',
105 'ChooseRemovableDevice', 'ListAllRemovableDevices',
106 'GetRemovableDeviceDescription', 'IsFilePathGPTDiskImage')
107 VALID_IMAGE = True
108
109 def __init__(self):
110 partial_mock.PartialCmdMock.__init__(self)
111
112 def CopyImageToDevice(self, _inst, *_args, **_kwargs):
113 """Mock out CopyImageToDevice."""
114
115 def InstallImageToDevice(self, _inst, *_args, **_kwargs):
116 """Mock out InstallImageToDevice."""
117
118 def ChooseRemovableDevice(self, _inst, *_args, **_kwargs):
119 """Mock out ChooseRemovableDevice."""
120
121 def ListAllRemovableDevices(self, _inst, *_args, **_kwargs):
122 """Mock out ListAllRemovableDevices."""
123 return ['foo', 'taco', 'milk']
124
125 def GetRemovableDeviceDescription(self, _inst, *_args, **_kwargs):
126 """Mock out GetRemovableDeviceDescription."""
127
128 def IsFilePathGPTDiskImage(self, _inst, *_args, **_kwargs):
129 """Mock out IsFilePathGPTDiskImage."""
130 return self.VALID_IMAGE
131
132
133class USBImagerTest(cros_test_lib.MockTempDirTestCase):
134 """Test the flow of flash.Flash() with USBImager."""
135 IMAGE = '/path/to/image'
136
137 def Device(self, path):
138 """Create a USB device for passing to flash.Flash()."""
139 return commandline.Device(scheme=commandline.DEVICE_SCHEME_USB,
140 path=path)
141
142 def setUp(self):
143 """Patches objects."""
144 self.usb_mock = USBImagerMock()
145 self.imager_mock = self.StartPatcher(self.usb_mock)
146 self.PatchObject(dev_server_wrapper, 'GenerateXbuddyRequest',
147 return_value='xbuddy/local/latest')
148 self.PatchObject(dev_server_wrapper, 'DevServerWrapper')
149 self.PatchObject(dev_server_wrapper, 'GetImagePathWithXbuddy',
150 return_value='taco-paladin/R36/chromiumos_test_image.bin')
151 self.PatchObject(os.path, 'exists', return_value=True)
152 self.PatchObject(brick_lib, 'FindBrickInPath', return_value=None)
153
154 def testLocalImagePathCopy(self):
155 """Tests that imaging methods are called correctly."""
156 with mock.patch('os.path.isfile', return_value=True):
157 flash.Flash(self.Device('/dev/foo'), self.IMAGE)
158 self.assertTrue(self.imager_mock.patched['CopyImageToDevice'].called)
159
160 def testLocalImagePathInstall(self):
161 """Tests that imaging methods are called correctly."""
162 with mock.patch('os.path.isfile', return_value=True):
163 flash.Flash(self.Device('/dev/foo'), self.IMAGE, board='taco',
164 install=True)
165 self.assertTrue(self.imager_mock.patched['InstallImageToDevice'].called)
166
167 def testLocalBadImagePath(self):
168 """Tests that using an image not having the magic bytes has prompt."""
169 self.usb_mock.VALID_IMAGE = False
170 with mock.patch('os.path.isfile', return_value=True):
171 with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
172 mock_prompt.return_value = False
173 flash.Flash(self.Device('/dev/foo'), self.IMAGE)
174 self.assertTrue(mock_prompt.called)
175
176 def testNonLocalImagePath(self):
177 """Tests that we try to get the image path using xbuddy."""
178 with mock.patch.object(
179 dev_server_wrapper,
180 'GetImagePathWithXbuddy',
181 return_value='translated/xbuddy/path') as mock_xbuddy:
182 with mock.patch('os.path.isfile', return_value=False):
183 with mock.patch('os.path.isdir', return_value=False):
184 flash.Flash(self.Device('/dev/foo'), self.IMAGE)
185 self.assertTrue(mock_xbuddy.called)
186
187 def testConfirmNonRemovableDevice(self):
188 """Tests that we ask user to confirm if the device is not removable."""
189 with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
190 flash.Flash(self.Device('/dev/dummy'), self.IMAGE)
191 self.assertTrue(mock_prompt.called)
192
193 def testSkipPromptNonRemovableDevice(self):
194 """Tests that we skip the prompt for non-removable with --yes."""
195 with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
196 flash.Flash(self.Device('/dev/dummy'), self.IMAGE, yes=True)
197 self.assertFalse(mock_prompt.called)
198
199 def testChooseRemovableDevice(self):
200 """Tests that we ask user to choose a device if none is given."""
201 flash.Flash(self.Device(''), self.IMAGE)
202 self.assertTrue(self.imager_mock.patched['ChooseRemovableDevice'].called)