1#!/usr/bin/env python
2# Copyright 2015 The Chromium 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"""
6Unit tests for the contents of fastboot_utils.py
7"""
8
9# pylint: disable=protected-access,unused-argument
10
11import collections
12import io
13import logging
14import unittest
15
16from devil import devil_env
17from devil.android import device_errors
18from devil.android import device_utils
19from devil.android import fastboot_utils
20from devil.android.sdk import fastboot
21from devil.utils import mock_calls
22
23with devil_env.SysPath(devil_env.PYMOCK_PATH):
24  import mock  # pylint: disable=import-error
25
26_BOARD = 'board_type'
27_SERIAL = '0123456789abcdef'
28_PARTITIONS = [
29    'bootloader', 'radio', 'boot', 'recovery', 'system', 'userdata', 'cache'
30]
31_IMAGES = collections.OrderedDict([
32    ('bootloader', 'bootloader.img'),
33    ('radio', 'radio.img'),
34    ('boot', 'boot.img'),
35    ('recovery', 'recovery.img'),
36    ('system', 'system.img'),
37    ('userdata', 'userdata.img'),
38    ('cache', 'cache.img'),
39])
40_VALID_FILES = [_BOARD + '.zip', 'android-info.txt']
41_INVALID_FILES = ['test.zip', 'android-info.txt']
42
43
44class MockFile(object):
45  def __init__(self, name='/tmp/some/file'):
46    self.file = mock.MagicMock(spec=file)
47    self.file.name = name
48
49  def __enter__(self):
50    return self.file
51
52  def __exit__(self, exc_type, exc_val, exc_tb):
53    pass
54
55  @property
56  def name(self):
57    return self.file.name
58
59
60def _FastbootWrapperMock(test_serial):
61  fastbooter = mock.Mock(spec=fastboot.Fastboot)
62  fastbooter.__str__ = mock.Mock(return_value=test_serial)
63  fastbooter.Devices.return_value = [test_serial]
64  return fastbooter
65
66
67def _DeviceUtilsMock(test_serial):
68  device = mock.Mock(spec=device_utils.DeviceUtils)
69  device.__str__ = mock.Mock(return_value=test_serial)
70  device.product_board = mock.Mock(return_value=_BOARD)
71  device.adb = mock.Mock()
72  return device
73
74
75class FastbootUtilsTest(mock_calls.TestCase):
76  def setUp(self):
77    self.device_utils_mock = _DeviceUtilsMock(_SERIAL)
78    self.fastboot_wrapper = _FastbootWrapperMock(_SERIAL)
79    self.fastboot = fastboot_utils.FastbootUtils(
80        device=self.device_utils_mock,
81        fastbooter=self.fastboot_wrapper,
82        default_timeout=2,
83        default_retries=0)
84    self.fastboot._board = _BOARD
85
86  def FastbootCommandFailedError(self,
87                                 args=None,
88                                 output=None,
89                                 status=None,
90                                 msg=None):
91    return mock.Mock(side_effect=device_errors.FastbootCommandFailedError(
92        args, output, status, msg, str(self.device_utils_mock)))
93
94
95class FastbootUtilsInitTest(FastbootUtilsTest):
96  def testInitWithDeviceUtil(self):
97    f = fastboot_utils.FastbootUtils(self.device_utils_mock)
98    self.assertEqual(str(self.device_utils_mock), str(f._device))
99
100  def testInitWithMissing_fails(self):
101    with self.assertRaises(ValueError):
102      fastboot_utils.FastbootUtils(device=None, fastbooter=None)
103    with self.assertRaises(AttributeError):
104      fastboot_utils.FastbootUtils('abc')
105
106
107class FastbootUtilsWaitForFastbootMode(FastbootUtilsTest):
108
109  # If this test fails by timing out after 1 second.
110  @mock.patch('time.sleep', mock.Mock())
111  def testWaitForFastbootMode(self):
112    self.fastboot.WaitForFastbootMode()
113
114
115class FastbootUtilsIsFastbootMode(FastbootUtilsTest):
116  def testIsFastbootMode_True(self):
117    self.assertEqual(True, self.fastboot.IsFastbootMode())
118
119  def testIsFastbootMode_False(self):
120    self.fastboot._serial = 'not' + _SERIAL
121    self.assertEqual(False, self.fastboot.IsFastbootMode())
122
123
124class FastbootUtils_supports_ab(FastbootUtilsTest):
125  def test_supports_ab_fastboot_True(self):
126    with self.assertCalls(
127        (self.call.fastboot.IsFastbootMode(), True),
128        (self.call.fastboot.fastboot.GetVar('slot-count'), '2')):
129      self.assertEqual(True, self.fastboot.supports_ab)
130
131  def test_supports_ab_fastboot_False(self):
132    with self.assertCalls(
133        (self.call.fastboot.IsFastbootMode(), True),
134        (self.call.fastboot.fastboot.GetVar('slot-count'), '1')):
135      self.assertEqual(False, self.fastboot.supports_ab)
136
137  def test_supports_ab_fastboot_FalseWithEmpty(self):
138    with self.assertCalls(
139        (self.call.fastboot.IsFastbootMode(), True),
140        (self.call.fastboot.fastboot.GetVar('slot-count'), '')):
141      self.assertEqual(False, self.fastboot.supports_ab)
142
143  def test_supports_ab_fastboot_FalseWithError(self):
144    with self.assertCalls((self.call.fastboot.IsFastbootMode(), True),
145                          (self.call.fastboot.fastboot.GetVar('slot-count'),
146                           self.FastbootCommandFailedError([], ''))):
147      self.assertEqual(False, self.fastboot.supports_ab)
148
149  def test_supports_ab_device_True(self):
150    with self.assertCalls(
151        (self.call.fastboot.IsFastbootMode(), False),
152        (self.call.fastboot._device.GetProp('ro.build.ab_update'), 'true')):
153      self.assertEqual(True, self.fastboot.supports_ab)
154
155  def test_supports_ab_device_False(self):
156    with self.assertCalls(
157        (self.call.fastboot.IsFastbootMode(), False),
158        (self.call.fastboot._device.GetProp('ro.build.ab_update'), '')):
159      self.assertEqual(False, self.fastboot.supports_ab)
160
161
162class FastbootUtils_requires_dtbo(FastbootUtilsTest):
163  def test_requires_dtbo_fastboot_True(self):
164    with self.assertCalls(
165        (self.call.fastboot.IsFastbootMode(), True),
166        (self.call.fastboot.fastboot.GetVar('has-slot:dtbo'), 'yes')):
167      self.assertEqual(True, self.fastboot.requires_dtbo)
168
169  def test_requires_dtbo_fastboot_FalseWithEmpty(self):
170    with self.assertCalls(
171        (self.call.fastboot.IsFastbootMode(), True),
172        (self.call.fastboot.fastboot.GetVar('has-slot:dtbo'), '')):
173      self.assertEqual(False, self.fastboot.requires_dtbo)
174
175  def test_requires_dtbo_fastboot_FalseWithError(self):
176    with self.assertCalls((self.call.fastboot.IsFastbootMode(), True),
177                          (self.call.fastboot.fastboot.GetVar('has-slot:dtbo'),
178                           self.FastbootCommandFailedError([], ''))):
179      self.assertEqual(False, self.fastboot.requires_dtbo)
180
181  def test_requires_dtbo_device_True(self):
182    with self.assertCalls(
183        (self.call.fastboot.IsFastbootMode(), False),
184        (self.call.fastboot._device.GetProp('ro.boot.dtbo_idx'), '1')):
185      self.assertEqual(True, self.fastboot.requires_dtbo)
186
187  def test_requires_dtbo_device_False(self):
188    with self.assertCalls(
189        (self.call.fastboot.IsFastbootMode(), False),
190        (self.call.fastboot._device.GetProp('ro.boot.dtbo_idx'), '')):
191      self.assertEqual(False, self.fastboot.requires_dtbo)
192
193
194class FastbootUtils_requires_vbmeta(FastbootUtilsTest):
195  def test_requires_vbmeta_fastboot_True(self):
196    with self.assertCalls(
197        (self.call.fastboot.IsFastbootMode(), True),
198        (self.call.fastboot.fastboot.GetVar('has-slot:vbmeta'), 'yes')):
199      self.assertEqual(True, self.fastboot.requires_vbmeta)
200
201  def test_requires_vbmeta_fastboot_FalseWithEmpty(self):
202    with self.assertCalls(
203        (self.call.fastboot.IsFastbootMode(), True),
204        (self.call.fastboot.fastboot.GetVar('has-slot:vbmeta'), '')):
205      self.assertEqual(False, self.fastboot.requires_vbmeta)
206
207  def test_requires_vbmeta_fastboot_FalseWithError(self):
208    with self.assertCalls(
209        (self.call.fastboot.IsFastbootMode(), True),
210        (self.call.fastboot.fastboot.GetVar('has-slot:vbmeta'),
211         self.FastbootCommandFailedError([], ''))):
212      self.assertEqual(False, self.fastboot.requires_vbmeta)
213
214  def test_requires_vbmeta_device_True(self):
215    with self.assertCalls(
216        (self.call.fastboot.IsFastbootMode(), False),
217        (self.call.fastboot._device.GetProp('ro.boot.vbmeta.digest'),
218         '1')):
219      self.assertEqual(True, self.fastboot.requires_vbmeta)
220
221  def test_requires_vbmeta_device_False(self):
222    with self.assertCalls(
223        (self.call.fastboot.IsFastbootMode(), False),
224        (self.call.fastboot._device.GetProp('ro.boot.vbmeta.digest'), '')):
225      self.assertEqual(False, self.fastboot.requires_vbmeta)
226
227
228class FastbootUtilsEnableFastbootMode(FastbootUtilsTest):
229  def testEnableFastbootMode(self):
230    with self.assertCalls(
231        (self.call.fastboot.IsFastbootMode(), False),
232        self.call.fastboot._device.EnableRoot(),
233        self.call.fastboot._device.adb.Reboot(to_bootloader=True),
234        self.call.fastboot.WaitForFastbootMode()):
235      self.fastboot.EnableFastbootMode()
236
237
238class FastbootUtilsReboot(FastbootUtilsTest):
239  def testReboot_bootloader(self):
240    with self.assertCalls(self.call.fastboot.fastboot.RebootBootloader(),
241                          self.call.fastboot.WaitForFastbootMode()):
242      self.fastboot.Reboot(bootloader=True)
243
244  def testReboot_normal(self):
245    with self.assertCalls(
246        self.call.fastboot.fastboot.Reboot(),
247        self.call.fastboot._device.WaitUntilFullyBooted(timeout=mock.ANY)):
248      self.fastboot.Reboot()
249
250
251class FastbootUtilsFlashPartitions(FastbootUtilsTest):
252  def testFlashPartitions_wipe(self):
253    with self.patch_call(self.call.fastboot.supports_ab, return_value=False):
254      with self.assertCalls(
255          (self.call.fastboot._VerifyBoard('test'), True),
256          (self.call.fastboot._FindAndVerifyPartitionsAndImages(
257              _PARTITIONS, 'test'), _IMAGES),
258          (self.call.fastboot.fastboot.Flash('bootloader', 'bootloader.img')),
259          (self.call.fastboot.Reboot(bootloader=True)),
260          (self.call.fastboot.fastboot.Flash('radio', 'radio.img')),
261          (self.call.fastboot.Reboot(bootloader=True)),
262          (self.call.fastboot.fastboot.Flash('boot', 'boot.img')),
263          (self.call.fastboot.fastboot.Flash('recovery', 'recovery.img')),
264          (self.call.fastboot.fastboot.Flash('system', 'system.img')),
265          (self.call.fastboot.fastboot.Flash('userdata', 'userdata.img')),
266          (self.call.fastboot.fastboot.Flash('cache', 'cache.img'))):
267        self.fastboot._FlashPartitions(_PARTITIONS, 'test', wipe=True)
268
269  def testFlashPartitions_noWipe(self):
270    with self.patch_call(self.call.fastboot.supports_ab, return_value=False):
271      with self.assertCalls(
272          (self.call.fastboot._VerifyBoard('test'), True),
273          (self.call.fastboot._FindAndVerifyPartitionsAndImages(
274              _PARTITIONS, 'test'), _IMAGES),
275          (self.call.fastboot.fastboot.Flash('bootloader', 'bootloader.img')),
276          (self.call.fastboot.Reboot(bootloader=True)),
277          (self.call.fastboot.fastboot.Flash('radio', 'radio.img')),
278          (self.call.fastboot.Reboot(bootloader=True)),
279          (self.call.fastboot.fastboot.Flash('boot', 'boot.img')),
280          (self.call.fastboot.fastboot.Flash('recovery', 'recovery.img')),
281          (self.call.fastboot.fastboot.Flash('system', 'system.img'))):
282        self.fastboot._FlashPartitions(_PARTITIONS, 'test')
283
284  def testFlashPartitions_AB_device(self):
285    ab_images = _IMAGES.copy()
286    ab_images['dtbo'] = 'dtbo.img'
287    ab_images['vbmeta'] = 'vbmeta.img'
288    ab_partitions = _PARTITIONS[:]
289    ab_partitions.append('dtbo')
290    ab_partitions.append('vbmeta')
291    with self.patch_call(self.call.fastboot.supports_ab, return_value=True):
292      with self.patch_call(self.call.fastboot.requires_dtbo, return_value=True):
293        with self.patch_call(self.call.fastboot.requires_vbmeta,
294                             return_value=True):
295          with self.assertCalls(
296              (self.call.fastboot._VerifyBoard('test'), True),
297              (self.call.fastboot._FindAndVerifyPartitionsAndImages(
298                  ab_partitions, 'test'), ab_images),
299              (self.call.fastboot.fastboot.Flash('bootloader',
300                                                 'bootloader.img')),
301              (self.call.fastboot.Reboot(bootloader=True)),
302              (self.call.fastboot.fastboot.Flash('radio', 'radio.img')),
303              (self.call.fastboot.Reboot(bootloader=True)),
304              (self.call.fastboot.fastboot.Flash('boot', 'boot.img')),
305              (self.call.fastboot.fastboot.Flash('recovery', 'recovery.img')),
306              (self.call.fastboot.fastboot.Flash('system', 'system.img')),
307              (self.call.fastboot.fastboot.Flash('userdata', 'userdata.img')),
308              (self.call.fastboot.fastboot.Flash('cache', 'cache.img')),
309              (self.call.fastboot.fastboot.Flash('dtbo', 'dtbo.img')),
310              (self.call.fastboot.fastboot.Flash('vbmeta', 'vbmeta.img'))):
311            self.fastboot._FlashPartitions(ab_partitions, 'test', wipe=True)
312
313
314class FastbootUtilsFastbootMode(FastbootUtilsTest):
315  def testFastbootMode_goodWait(self):
316    with self.assertCalls(
317        self.call.fastboot.EnableFastbootMode(),
318        self.call.fastboot.fastboot.SetOemOffModeCharge(False),
319        self.call.fastboot.fastboot.SetOemOffModeCharge(True),
320        self.call.fastboot.Reboot(wait_for_reboot=True)):
321      with self.fastboot.FastbootMode() as fbm:
322        self.assertEqual(self.fastboot, fbm)
323
324  def testFastbootMode_goodNoWait(self):
325    with self.assertCalls(
326        self.call.fastboot.EnableFastbootMode(),
327        self.call.fastboot.fastboot.SetOemOffModeCharge(False),
328        self.call.fastboot.fastboot.SetOemOffModeCharge(True),
329        self.call.fastboot.Reboot(wait_for_reboot=False)):
330      with self.fastboot.FastbootMode(wait_for_reboot=False) as fbm:
331        self.assertEqual(self.fastboot, fbm)
332
333  def testFastbootMode_exception(self):
334    with self.assertCalls(
335        self.call.fastboot.EnableFastbootMode(),
336        self.call.fastboot.fastboot.SetOemOffModeCharge(False)):
337      with self.assertRaises(NotImplementedError):
338        with self.fastboot.FastbootMode() as fbm:
339          self.assertEqual(self.fastboot, fbm)
340          raise NotImplementedError
341
342  def testFastbootMode_exceptionInEnableFastboot(self):
343    self.fastboot.EnableFastbootMode = mock.Mock()
344    self.fastboot.EnableFastbootMode.side_effect = NotImplementedError
345    with self.assertRaises(NotImplementedError):
346      with self.fastboot.FastbootMode():
347        pass
348
349
350class FastbootUtilsVerifyBoard(FastbootUtilsTest):
351  def testVerifyBoard_bothValid(self):
352    mock_file = io.StringIO(u'require board=%s\n' % _BOARD)
353    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
354      with mock.patch('os.listdir', return_value=_VALID_FILES):
355        self.assertTrue(self.fastboot._VerifyBoard('test'))
356
357  def testVerifyBoard_BothNotValid(self):
358    mock_file = io.StringIO(u'abc')
359    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
360      with mock.patch('os.listdir', return_value=_INVALID_FILES):
361        self.assertFalse(self.assertFalse(self.fastboot._VerifyBoard('test')))
362
363  def testVerifyBoard_FileNotFoundZipValid(self):
364    with mock.patch('os.listdir', return_value=[_BOARD + '.zip']):
365      self.assertTrue(self.fastboot._VerifyBoard('test'))
366
367  def testVerifyBoard_ZipNotFoundFileValid(self):
368    mock_file = io.StringIO(u'require board=%s\n' % _BOARD)
369    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
370      with mock.patch('os.listdir', return_value=['android-info.txt']):
371        self.assertTrue(self.fastboot._VerifyBoard('test'))
372
373  def testVerifyBoard_zipNotValidFileIs(self):
374    mock_file = io.StringIO(u'require board=%s\n' % _BOARD)
375    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
376      with mock.patch('os.listdir', return_value=_INVALID_FILES):
377        self.assertTrue(self.fastboot._VerifyBoard('test'))
378
379  def testVerifyBoard_fileNotValidZipIs(self):
380    mock_file = io.StringIO(u'require board=WrongBoard')
381    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
382      with mock.patch('os.listdir', return_value=_VALID_FILES):
383        self.assertFalse(self.fastboot._VerifyBoard('test'))
384
385  def testVerifyBoard_noBoardInFileValidZip(self):
386    mock_file = io.StringIO(u'Regex wont match')
387    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
388      with mock.patch('os.listdir', return_value=_VALID_FILES):
389        self.assertTrue(self.fastboot._VerifyBoard('test'))
390
391  def testVerifyBoard_noBoardInFileInvalidZip(self):
392    mock_file = io.StringIO(u'Regex wont match')
393    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
394      with mock.patch('os.listdir', return_value=_INVALID_FILES):
395        self.assertFalse(self.fastboot._VerifyBoard('test'))
396
397
398class FastbootUtilsFindAndVerifyPartitionsAndImages(FastbootUtilsTest):
399  def testFindAndVerifyPartitionsAndImages_validNoVendor(self):
400    PARTITIONS = [
401        'bootloader', 'radio', 'boot', 'recovery', 'system', 'userdata',
402        'cache', 'vendor'
403    ]
404    files = [
405        'bootloader-test-.img', 'radio123.img', 'boot.img', 'recovery.img',
406        'system.img', 'userdata.img', 'cache.img'
407    ]
408    img_check = collections.OrderedDict([
409        ('bootloader', 'test/bootloader-test-.img'),
410        ('radio', 'test/radio123.img'),
411        ('boot', 'test/boot.img'),
412        ('recovery', 'test/recovery.img'),
413        ('system', 'test/system.img'),
414        ('userdata', 'test/userdata.img'),
415        ('cache', 'test/cache.img'),
416    ])
417    parts_check = [
418        'bootloader', 'radio', 'boot', 'recovery', 'system', 'userdata', 'cache'
419    ]
420    with mock.patch('os.listdir', return_value=files):
421      imgs = self.fastboot._FindAndVerifyPartitionsAndImages(PARTITIONS, 'test')
422      parts = imgs.keys()
423      self.assertDictEqual(imgs, img_check)
424      self.assertListEqual(parts, parts_check)
425
426  def testFindAndVerifyPartitionsAndImages_validVendor(self):
427    PARTITIONS = [
428        'bootloader', 'radio', 'boot', 'recovery', 'system', 'userdata',
429        'cache', 'vendor'
430    ]
431    files = [
432        'bootloader-test-.img', 'radio123.img', 'boot.img', 'recovery.img',
433        'system.img', 'userdata.img', 'cache.img', 'vendor.img'
434    ]
435    img_check = {
436        'bootloader': 'test/bootloader-test-.img',
437        'radio': 'test/radio123.img',
438        'boot': 'test/boot.img',
439        'recovery': 'test/recovery.img',
440        'system': 'test/system.img',
441        'userdata': 'test/userdata.img',
442        'cache': 'test/cache.img',
443        'vendor': 'test/vendor.img',
444    }
445    parts_check = [
446        'bootloader', 'radio', 'boot', 'recovery', 'system', 'userdata',
447        'cache', 'vendor'
448    ]
449
450    with mock.patch('os.listdir', return_value=files):
451      with self.patch_call(self.call.fastboot.supports_ab, return_value=False):
452        imgs = self.fastboot._FindAndVerifyPartitionsAndImages(
453            PARTITIONS, 'test')
454        parts = imgs.keys()
455        self.assertDictEqual(imgs, img_check)
456        self.assertListEqual(parts, parts_check)
457
458  def testFindAndVerifyPartitionsAndImages_badPartition(self):
459    with mock.patch('os.listdir', return_value=['test']):
460      with self.patch_call(self.call.fastboot.supports_ab, return_value=False):
461        with self.assertRaises(KeyError):
462          self.fastboot._FindAndVerifyPartitionsAndImages(['test'], 'test')
463
464  def testFindAndVerifyPartitionsAndImages_noFile_RequiredImage(self):
465    with mock.patch('os.listdir', return_value=['test']):
466      with self.patch_call(self.call.fastboot.supports_ab, return_value=False):
467        with self.assertRaises(device_errors.FastbootCommandFailedError):
468          self.fastboot._FindAndVerifyPartitionsAndImages(['boot'], 'test')
469
470  def testFindAndVerifyPartitionsAndImages_noFile_RequiredImageAB(self):
471    with mock.patch('os.listdir', return_value=['test']):
472      with self.patch_call(self.call.fastboot.supports_ab, return_value=True):
473        with self.assertRaises(device_errors.FastbootCommandFailedError):
474          self.fastboot._FindAndVerifyPartitionsAndImages(['boot'], 'test')
475
476  def testFindAndVerifyPartitionsAndImages_noFile_NotRequiredImage(self):
477    with mock.patch('os.listdir', return_value=['test']):
478      with self.patch_call(self.call.fastboot.supports_ab, return_value=False):
479        with self.patch_call(self.call.fastboot.requires_dtbo,
480                             return_value=False):
481          self.assertFalse(
482              self.fastboot._FindAndVerifyPartitionsAndImages(['vendor'],
483                                                              'test'))
484          self.assertFalse(
485              self.fastboot._FindAndVerifyPartitionsAndImages(['dtbo'], 'test'))
486
487  def testFindAndVerifyPartitionsAndImages_noFile_NotRequiredImageAB(self):
488    with mock.patch('os.listdir', return_value=['test']):
489      with self.patch_call(self.call.fastboot.supports_ab, return_value=True):
490        with self.patch_call(self.call.fastboot.requires_dtbo,
491                             return_value=False):
492          self.assertFalse(
493              self.fastboot._FindAndVerifyPartitionsAndImages(['vendor'],
494                                                              'test'))
495          self.assertFalse(
496              self.fastboot._FindAndVerifyPartitionsAndImages(['cache'],
497                                                              'test'))
498          self.assertFalse(
499              self.fastboot._FindAndVerifyPartitionsAndImages(['dtbo'], 'test'))
500
501
502class FastbootUtilsFlashDevice(FastbootUtilsTest):
503  def testFlashDevice_wipe(self):
504    with self.assertCalls(
505        self.call.fastboot.EnableFastbootMode(),
506        self.call.fastboot.fastboot.SetOemOffModeCharge(False),
507        self.call.fastboot._FlashPartitions(mock.ANY, 'test', wipe=True),
508        self.call.fastboot.fastboot.SetOemOffModeCharge(True),
509        self.call.fastboot.Reboot(wait_for_reboot=False)):
510      self.fastboot.FlashDevice('test', wipe=True)
511
512  def testFlashDevice_noWipe(self):
513    with self.assertCalls(
514        self.call.fastboot.EnableFastbootMode(),
515        self.call.fastboot.fastboot.SetOemOffModeCharge(False),
516        self.call.fastboot._FlashPartitions(mock.ANY, 'test', wipe=False),
517        self.call.fastboot.fastboot.SetOemOffModeCharge(True),
518        self.call.fastboot.Reboot(wait_for_reboot=True)):
519      self.fastboot.FlashDevice('test', wipe=False)
520
521  def testFlashDevice_partitions(self):
522    with self.assertCalls(
523        self.call.fastboot.EnableFastbootMode(),
524        self.call.fastboot.fastboot.SetOemOffModeCharge(False),
525        self.call.fastboot._FlashPartitions(['boot'], 'test', wipe=False),
526        self.call.fastboot.fastboot.SetOemOffModeCharge(True),
527        self.call.fastboot.Reboot(wait_for_reboot=True)):
528      self.fastboot.FlashDevice('test', partitions=['boot'], wipe=False)
529
530
531if __name__ == '__main__':
532  logging.getLogger().setLevel(logging.DEBUG)
533  unittest.main(verbosity=2)
534