Home | History | Annotate | Download | only in cros
      1 #!/usr/bin/python
      2 # Copyright (c) 2013 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 import mox
      7 import os
      8 import unittest
      9 
     10 import common
     11 import time
     12 
     13 import autoupdater
     14 from autotest_lib.client.common_lib import error
     15 from autotest_lib.client.common_lib.test_utils import mock
     16 
     17 class TestAutoUpdater(mox.MoxTestBase):
     18     """Test autoupdater module."""
     19 
     20 
     21     def testParseBuildFromUpdateUrlwithUpdate(self):
     22         """Test that we properly parse the build from an update_url."""
     23         update_url = ('http://172.22.50.205:8082/update/lumpy-release/'
     24                       'R27-3837.0.0')
     25         expected_value = 'lumpy-release/R27-3837.0.0'
     26         self.assertEqual(autoupdater.url_to_image_name(update_url),
     27                          expected_value)
     28 
     29 
     30     def testCheckVersion_1(self):
     31         """Test version check methods work for any build.
     32 
     33         Test two methods used to check version, check_version and
     34         check_version_to_confirm_install, for:
     35         1. trybot paladin build.
     36         update version: trybot-lumpy-paladin/R27-3837.0.0-b123
     37         booted version: 3837.0.2013_03_21_1340
     38 
     39         """
     40         update_url = ('http://172.22.50.205:8082/update/trybot-lumpy-paladin/'
     41                       'R27-1111.0.0-b123')
     42         updater = autoupdater.ChromiumOSUpdater(
     43                 update_url, host=self.mox.CreateMockAnything())
     44 
     45         self.mox.UnsetStubs()
     46         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     47         updater.host.get_release_version().MultipleTimes().AndReturn(
     48                                                     '1111.0.2013_03_21_1340')
     49         self.mox.ReplayAll()
     50 
     51         self.assertFalse(updater.check_version())
     52         self.assertTrue(updater.check_version_to_confirm_install())
     53 
     54         self.mox.UnsetStubs()
     55         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     56         updater.host.get_release_version().MultipleTimes().AndReturn(
     57                 '1111.0.0-rc1')
     58         self.mox.ReplayAll()
     59 
     60         self.assertFalse(updater.check_version())
     61         self.assertFalse(updater.check_version_to_confirm_install())
     62 
     63         self.mox.UnsetStubs()
     64         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     65         updater.host.get_release_version().MultipleTimes().AndReturn('1111.0.0')
     66         self.mox.ReplayAll()
     67 
     68         self.assertFalse(updater.check_version())
     69         self.assertFalse(updater.check_version_to_confirm_install())
     70 
     71         self.mox.UnsetStubs()
     72         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     73         updater.host.get_release_version().MultipleTimes().AndReturn(
     74                                                     '4444.0.0-pgo-generate')
     75         self.mox.ReplayAll()
     76 
     77         self.assertFalse(updater.check_version())
     78         self.assertFalse(updater.check_version_to_confirm_install())
     79 
     80 
     81     def testCheckVersion_2(self):
     82         """Test version check methods work for any build.
     83 
     84         Test two methods used to check version, check_version and
     85         check_version_to_confirm_install, for:
     86         2. trybot release build.
     87         update version: trybot-lumpy-release/R27-3837.0.0-b456
     88         booted version: 3837.0.0
     89 
     90         """
     91         update_url = ('http://172.22.50.205:8082/update/trybot-lumpy-release/'
     92                       'R27-2222.0.0-b456')
     93         updater = autoupdater.ChromiumOSUpdater(
     94                 update_url, host=self.mox.CreateMockAnything())
     95 
     96         self.mox.UnsetStubs()
     97         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     98         updater.host.get_release_version().MultipleTimes().AndReturn(
     99                                                     '2222.0.2013_03_21_1340')
    100         self.mox.ReplayAll()
    101 
    102         self.assertFalse(updater.check_version())
    103         self.assertFalse(updater.check_version_to_confirm_install())
    104 
    105         self.mox.UnsetStubs()
    106         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    107         updater.host.get_release_version().MultipleTimes().AndReturn(
    108                 '2222.0.0-rc1')
    109         self.mox.ReplayAll()
    110 
    111         self.assertFalse(updater.check_version())
    112         self.assertFalse(updater.check_version_to_confirm_install())
    113 
    114         self.mox.UnsetStubs()
    115         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    116         updater.host.get_release_version().MultipleTimes().AndReturn('2222.0.0')
    117         self.mox.ReplayAll()
    118 
    119         self.assertFalse(updater.check_version())
    120         self.assertTrue(updater.check_version_to_confirm_install())
    121 
    122         self.mox.UnsetStubs()
    123         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    124         updater.host.get_release_version().MultipleTimes().AndReturn(
    125                                                     '4444.0.0-pgo-generate')
    126         self.mox.ReplayAll()
    127 
    128         self.assertFalse(updater.check_version())
    129         self.assertFalse(updater.check_version_to_confirm_install())
    130 
    131 
    132     def testCheckVersion_3(self):
    133         """Test version check methods work for any build.
    134 
    135         Test two methods used to check version, check_version and
    136         check_version_to_confirm_install, for:
    137         3. buildbot official release build.
    138         update version: lumpy-release/R27-3837.0.0
    139         booted version: 3837.0.0
    140 
    141         """
    142         update_url = ('http://172.22.50.205:8082/update/lumpy-release/'
    143                       'R27-3333.0.0')
    144         updater = autoupdater.ChromiumOSUpdater(
    145                 update_url, host=self.mox.CreateMockAnything())
    146 
    147         self.mox.UnsetStubs()
    148         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    149         updater.host.get_release_version().MultipleTimes().AndReturn(
    150                                                     '3333.0.2013_03_21_1340')
    151         self.mox.ReplayAll()
    152 
    153         self.assertFalse(updater.check_version())
    154         self.assertFalse(updater.check_version_to_confirm_install())
    155 
    156         self.mox.UnsetStubs()
    157         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    158         updater.host.get_release_version().MultipleTimes().AndReturn(
    159                 '3333.0.0-rc1')
    160         self.mox.ReplayAll()
    161 
    162         self.assertFalse(updater.check_version())
    163         self.assertFalse(updater.check_version_to_confirm_install())
    164 
    165         self.mox.UnsetStubs()
    166         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    167         updater.host.get_release_version().MultipleTimes().AndReturn('3333.0.0')
    168         self.mox.ReplayAll()
    169 
    170         self.assertTrue(updater.check_version())
    171         self.assertTrue(updater.check_version_to_confirm_install())
    172 
    173         self.mox.UnsetStubs()
    174         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    175         updater.host.get_release_version().MultipleTimes().AndReturn(
    176                                                     '4444.0.0-pgo-generate')
    177         self.mox.ReplayAll()
    178 
    179         self.assertFalse(updater.check_version())
    180         self.assertFalse(updater.check_version_to_confirm_install())
    181 
    182 
    183     def testCheckVersion_4(self):
    184         """Test version check methods work for any build.
    185 
    186         Test two methods used to check version, check_version and
    187         check_version_to_confirm_install, for:
    188         4. non-official paladin rc build.
    189         update version: lumpy-paladin/R27-3837.0.0-rc7
    190         booted version: 3837.0.0-rc7
    191 
    192         """
    193         update_url = ('http://172.22.50.205:8082/update/lumpy-paladin/'
    194                       'R27-4444.0.0-rc7')
    195         updater = autoupdater.ChromiumOSUpdater(
    196                 update_url, host=self.mox.CreateMockAnything())
    197 
    198         self.mox.UnsetStubs()
    199         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    200         updater.host.get_release_version().MultipleTimes().AndReturn(
    201                                                     '4444.0.2013_03_21_1340')
    202         self.mox.ReplayAll()
    203 
    204         self.assertFalse(updater.check_version())
    205         self.assertFalse(updater.check_version_to_confirm_install())
    206 
    207         self.mox.UnsetStubs()
    208         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    209         updater.host.get_release_version().MultipleTimes().AndReturn(
    210                 '4444.0.0-rc7')
    211         self.mox.ReplayAll()
    212 
    213         self.assertTrue(updater.check_version())
    214         self.assertTrue(updater.check_version_to_confirm_install())
    215 
    216         self.mox.UnsetStubs()
    217         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    218         updater.host.get_release_version().MultipleTimes().AndReturn('4444.0.0')
    219         self.mox.ReplayAll()
    220 
    221         self.assertFalse(updater.check_version())
    222         self.assertFalse(updater.check_version_to_confirm_install())
    223 
    224         self.mox.UnsetStubs()
    225         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    226         updater.host.get_release_version().MultipleTimes().AndReturn(
    227                                                     '4444.0.0-pgo-generate')
    228         self.mox.ReplayAll()
    229 
    230         self.assertFalse(updater.check_version())
    231         self.assertFalse(updater.check_version_to_confirm_install())
    232 
    233 
    234     def testCheckVersion_5(self):
    235         """Test version check methods work for any build.
    236 
    237         Test two methods used to check version, check_version and
    238         check_version_to_confirm_install, for:
    239         5. chrome-perf build.
    240         update version: lumpy-chrome-perf/R28-3837.0.0-b2996
    241         booted version: 3837.0.0
    242 
    243         """
    244         update_url = ('http://172.22.50.205:8082/update/lumpy-chrome-perf/'
    245                       'R28-4444.0.0-b2996')
    246         updater = autoupdater.ChromiumOSUpdater(
    247                 update_url, host=self.mox.CreateMockAnything())
    248 
    249         self.mox.UnsetStubs()
    250         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    251         updater.host.get_release_version().MultipleTimes().AndReturn(
    252                                                     '4444.0.2013_03_21_1340')
    253         self.mox.ReplayAll()
    254 
    255         self.assertFalse(updater.check_version())
    256         self.assertFalse(updater.check_version_to_confirm_install())
    257 
    258         self.mox.UnsetStubs()
    259         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    260         updater.host.get_release_version().MultipleTimes().AndReturn(
    261                 '4444.0.0-rc7')
    262         self.mox.ReplayAll()
    263 
    264         self.assertFalse(updater.check_version())
    265         self.assertFalse(updater.check_version_to_confirm_install())
    266 
    267         self.mox.UnsetStubs()
    268         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    269         updater.host.get_release_version().MultipleTimes().AndReturn('4444.0.0')
    270         self.mox.ReplayAll()
    271 
    272         self.assertFalse(updater.check_version())
    273         self.assertTrue(updater.check_version_to_confirm_install())
    274 
    275         self.mox.UnsetStubs()
    276         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    277         updater.host.get_release_version().MultipleTimes().AndReturn(
    278                                                     '4444.0.0-pgo-generate')
    279         self.mox.ReplayAll()
    280 
    281         self.assertFalse(updater.check_version())
    282         self.assertFalse(updater.check_version_to_confirm_install())
    283 
    284 
    285     def testCheckVersion_6(self):
    286         """Test version check methods work for any build.
    287 
    288         Test two methods used to check version, check_version and
    289         check_version_to_confirm_install, for:
    290         6. pgo-generate build.
    291         update version: lumpy-release-pgo-generate/R28-3837.0.0-b2996
    292         booted version: 3837.0.0-pgo-generate
    293 
    294         """
    295         update_url = ('http://172.22.50.205:8082/update/lumpy-release-pgo-'
    296                       'generate/R28-4444.0.0-b2996')
    297         updater = autoupdater.ChromiumOSUpdater(
    298                 update_url, host=self.mox.CreateMockAnything())
    299 
    300         self.mox.UnsetStubs()
    301         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    302         updater.host.get_release_version().MultipleTimes().AndReturn(
    303                                                     '4444.0.0-2013_03_21_1340')
    304         self.mox.ReplayAll()
    305 
    306         self.assertFalse(updater.check_version())
    307         self.assertFalse(updater.check_version_to_confirm_install())
    308 
    309         self.mox.UnsetStubs()
    310         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    311         updater.host.get_release_version().MultipleTimes().AndReturn(
    312                 '4444.0.0-rc7')
    313         self.mox.ReplayAll()
    314 
    315         self.assertFalse(updater.check_version())
    316         self.assertFalse(updater.check_version_to_confirm_install())
    317 
    318         self.mox.UnsetStubs()
    319         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    320         updater.host.get_release_version().MultipleTimes().AndReturn('4444.0.0')
    321         self.mox.ReplayAll()
    322 
    323         self.assertFalse(updater.check_version())
    324         self.assertFalse(updater.check_version_to_confirm_install())
    325 
    326         self.mox.UnsetStubs()
    327         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    328         updater.host.get_release_version().MultipleTimes().AndReturn(
    329                                                     '4444.0.0-pgo-generate')
    330         self.mox.ReplayAll()
    331 
    332         self.assertFalse(updater.check_version())
    333         self.assertTrue(updater.check_version_to_confirm_install())
    334 
    335 
    336     def testCheckVersion_7(self):
    337         """Test version check methods work for a test-ap build.
    338 
    339         Test two methods used to check version, check_version and
    340         check_version_to_confirm_install, for:
    341         6. test-ap build.
    342         update version: trybot-stumpy-test-ap/R46-7298.0.0-b23
    343         booted version: 7298.0.0
    344 
    345         """
    346         update_url = ('http://100.107.160.2:8082/update/trybot-stumpy-test-api'
    347                       '/R46-7298.0.0-b23')
    348         updater = autoupdater.ChromiumOSUpdater(
    349                 update_url, host=self.mox.CreateMockAnything())
    350 
    351         self.mox.UnsetStubs()
    352         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    353         updater.host.get_release_version().MultipleTimes().AndReturn(
    354                 '7298.0.2015_07_24_1640')
    355         self.mox.ReplayAll()
    356 
    357         self.assertFalse(updater.check_version())
    358         self.assertTrue(updater.check_version_to_confirm_install())
    359 
    360         self.mox.UnsetStubs()
    361         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    362         updater.host.get_release_version().MultipleTimes().AndReturn(
    363                 '7298.0.2015_07_24_1640')
    364         self.mox.ReplayAll()
    365 
    366         self.assertFalse(updater.check_version())
    367         self.assertTrue(updater.check_version_to_confirm_install())
    368 
    369         self.mox.UnsetStubs()
    370         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    371         updater.host.get_release_version().MultipleTimes().AndReturn('7298.0.0')
    372         self.mox.ReplayAll()
    373 
    374         self.assertFalse(updater.check_version())
    375         self.assertFalse(updater.check_version_to_confirm_install())
    376 
    377         self.mox.UnsetStubs()
    378         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    379         updater.host.get_release_version().MultipleTimes().AndReturn(
    380                 '7298.0.0')
    381         self.mox.ReplayAll()
    382 
    383         self.assertFalse(updater.check_version())
    384         self.assertFalse(updater.check_version_to_confirm_install())
    385 
    386 
    387     def _host_run_for_update(self, cmd, exception=None,
    388                              bad_update_status=False):
    389         """Helper function for AU tests.
    390 
    391         @param host: the test host
    392         @param cmd: the command to be recorded
    393         @param exception: the exception to be recorded, or None
    394         """
    395         if exception:
    396             self.host.run(command=cmd).AndRaise(exception)
    397         else:
    398             result = self.mox.CreateMockAnything()
    399             if bad_update_status:
    400                 # Pick randomly one unexpected status
    401                 result.stdout = 'UPDATE_STATUS_UPDATED_NEED_REBOOT'
    402             else:
    403                 result.stdout = 'UPDATE_STATUS_IDLE'
    404             result.status = 0
    405             self.host.run(command=cmd).AndReturn(result)
    406 
    407 
    408     def testTriggerUpdate(self):
    409         """Tests that we correctly handle updater errors."""
    410         update_url = 'http://server/test/url'
    411         self.host = self.mox.CreateMockAnything()
    412         self.mox.StubOutWithMock(self.host, 'run')
    413         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater,
    414                                  'get_last_update_error')
    415         self.host.hostname = 'test_host'
    416         updater_control_bin = '/usr/bin/update_engine_client'
    417         test_url = 'http://server/test/url'
    418         expected_wait_cmd = ('%s -status | grep CURRENT_OP' %
    419                              updater_control_bin)
    420         expected_cmd = ('%s --check_for_update --omaha_url=%s' %
    421                         (updater_control_bin, test_url))
    422         self.mox.StubOutWithMock(time, "sleep")
    423         UPDATE_ENGINE_RETRY_WAIT_TIME=5
    424 
    425         # Generic SSH Error.
    426         cmd_result_255 = self.mox.CreateMockAnything()
    427         cmd_result_255.exit_status = 255
    428 
    429         # Command Failed Error
    430         cmd_result_1 = self.mox.CreateMockAnything()
    431         cmd_result_1.exit_status = 1
    432 
    433         # Error 37
    434         cmd_result_37 = self.mox.CreateMockAnything()
    435         cmd_result_37.exit_status = 37
    436 
    437         updater = autoupdater.ChromiumOSUpdater(update_url, host=self.host)
    438 
    439         # (SUCCESS) Expect one wait command and one status command.
    440         self._host_run_for_update(expected_wait_cmd)
    441         self._host_run_for_update(expected_cmd)
    442 
    443         # (SUCCESS) Test with one retry to wait for update-engine.
    444         self._host_run_for_update(expected_wait_cmd, exception=
    445                 error.AutoservRunError('non-zero status', cmd_result_1))
    446         time.sleep(UPDATE_ENGINE_RETRY_WAIT_TIME)
    447         self._host_run_for_update(expected_wait_cmd)
    448         self._host_run_for_update(expected_cmd)
    449 
    450         # (SUCCESS) One-time SSH timeout, then success on retry.
    451         self._host_run_for_update(expected_wait_cmd)
    452         self._host_run_for_update(expected_cmd, exception=
    453                 error.AutoservSSHTimeout('ssh timed out', cmd_result_255))
    454         self._host_run_for_update(expected_cmd)
    455 
    456         # (SUCCESS) One-time ERROR 37, then success.
    457         self._host_run_for_update(expected_wait_cmd)
    458         self._host_run_for_update(expected_cmd, exception=
    459                 error.AutoservRunError('ERROR_CODE=37', cmd_result_37))
    460         self._host_run_for_update(expected_cmd)
    461 
    462         # (FAILURE) Bad status of update engine.
    463         self._host_run_for_update(expected_wait_cmd)
    464         self._host_run_for_update(expected_cmd, bad_update_status=True,
    465                                   exception=error.InstallError(
    466                                       'host is not in installable state'))
    467 
    468         # (FAILURE) Two-time SSH timeout.
    469         self._host_run_for_update(expected_wait_cmd)
    470         self._host_run_for_update(expected_cmd, exception=
    471                 error.AutoservSSHTimeout('ssh timed out', cmd_result_255))
    472         self._host_run_for_update(expected_cmd, exception=
    473                 error.AutoservSSHTimeout('ssh timed out', cmd_result_255))
    474 
    475         # (FAILURE) SSH Permission Error
    476         self._host_run_for_update(expected_wait_cmd)
    477         self._host_run_for_update(expected_cmd, exception=
    478                 error.AutoservSshPermissionDeniedError('no permission',
    479                                                        cmd_result_255))
    480 
    481         # (FAILURE) Other ssh failure
    482         self._host_run_for_update(expected_wait_cmd)
    483         self._host_run_for_update(expected_cmd, exception=
    484                 error.AutoservSshPermissionDeniedError('no permission',
    485                                                        cmd_result_255))
    486         # (FAILURE) Other error
    487         self._host_run_for_update(expected_wait_cmd)
    488         self._host_run_for_update(expected_cmd, exception=
    489                 error.AutoservRunError("unknown error", cmd_result_1))
    490 
    491         self.mox.ReplayAll()
    492 
    493         # Expect success
    494         updater.trigger_update()
    495         updater.trigger_update()
    496         updater.trigger_update()
    497         updater.trigger_update()
    498 
    499         # Expect errors as listed above
    500         self.assertRaises(autoupdater.RootFSUpdateError, updater.trigger_update)
    501         self.assertRaises(autoupdater.RootFSUpdateError, updater.trigger_update)
    502         self.assertRaises(autoupdater.RootFSUpdateError, updater.trigger_update)
    503         self.assertRaises(autoupdater.RootFSUpdateError, updater.trigger_update)
    504         self.assertRaises(autoupdater.RootFSUpdateError, updater.trigger_update)
    505 
    506         self.mox.VerifyAll()
    507 
    508 
    509     def testUpdateStateful(self):
    510         """Tests that we call the stateful update script with the correct args.
    511         """
    512         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater, '_run')
    513         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater,
    514                                  'get_stateful_update_script')
    515         update_url = ('http://172.22.50.205:8082/update/lumpy-chrome-perf/'
    516                       'R28-4444.0.0-b2996')
    517         static_update_url = ('http://172.22.50.205:8082/static/'
    518                              'lumpy-chrome-perf/R28-4444.0.0-b2996')
    519 
    520         # Test with clobber=False.
    521         autoupdater.ChromiumOSUpdater.get_stateful_update_script().AndReturn(
    522                 autoupdater.ChromiumOSUpdater.REMOTE_STATEFUL_UPDATE_PATH)
    523         autoupdater.ChromiumOSUpdater._run(
    524                 mox.And(
    525                         mox.StrContains(
    526                                 autoupdater.ChromiumOSUpdater.
    527                                 REMOTE_STATEFUL_UPDATE_PATH),
    528                         mox.StrContains(static_update_url),
    529                         mox.Not(mox.StrContains('--stateful_change=clean'))),
    530                 timeout=mox.IgnoreArg())
    531 
    532         self.mox.ReplayAll()
    533         updater = autoupdater.ChromiumOSUpdater(update_url)
    534         updater.update_stateful(clobber=False)
    535         self.mox.VerifyAll()
    536 
    537         # Test with clobber=True.
    538         self.mox.ResetAll()
    539         autoupdater.ChromiumOSUpdater.get_stateful_update_script().AndReturn(
    540                 autoupdater.ChromiumOSUpdater.REMOTE_STATEFUL_UPDATE_PATH)
    541         autoupdater.ChromiumOSUpdater._run(
    542                 mox.And(
    543                         mox.StrContains(
    544                                 autoupdater.ChromiumOSUpdater.
    545                                 REMOTE_STATEFUL_UPDATE_PATH),
    546                         mox.StrContains(static_update_url),
    547                         mox.StrContains('--stateful_change=clean')),
    548                 timeout=mox.IgnoreArg())
    549         self.mox.ReplayAll()
    550         updater = autoupdater.ChromiumOSUpdater(update_url)
    551         updater.update_stateful(clobber=True)
    552         self.mox.VerifyAll()
    553 
    554 
    555     def testGetStatefulUpdateScript(self):
    556         """ Test that get_stateful_update_script look for stateful_update.
    557 
    558         Check get_stateful_update_script is trying hard to find
    559         stateful_update and assert if it can't.
    560 
    561         """
    562         update_url = ('http://172.22.50.205:8082/update/lumpy-chrome-perf/'
    563                       'R28-4444.0.0-b2996')
    564         script_loc = os.path.join(autoupdater.STATEFUL_UPDATE_PATH,
    565                                   autoupdater.STATEFUL_UPDATE_SCRIPT)
    566         self.god = mock.mock_god()
    567         self.god.stub_function(os.path, 'exists')
    568         host = self.mox.CreateMockAnything()
    569         updater = autoupdater.ChromiumOSUpdater(update_url, host=host)
    570         os.path.exists.expect_call(script_loc).and_return(False)
    571         host.path_exists('/usr/local/bin/stateful_update').AndReturn(False)
    572 
    573         self.mox.ReplayAll()
    574         # No existing files, no URL, we should assert.
    575         self.assertRaises(
    576                 autoupdater.ChromiumOSError,
    577                 updater.get_stateful_update_script)
    578         self.mox.VerifyAll()
    579 
    580         # No existing files, but stateful URL, we will try.
    581         self.mox.ResetAll()
    582         os.path.exists.expect_call(script_loc).and_return(True)
    583         host.send_file(
    584                 script_loc,
    585                 '/tmp/stateful_update', delete_dest=True).AndReturn(True)
    586         self.mox.ReplayAll()
    587         self.assertEqual(
    588                 updater.get_stateful_update_script(),
    589                 '/tmp/stateful_update')
    590         self.mox.VerifyAll()
    591 
    592 
    593     def testRollbackRootfs(self):
    594         """Tests that we correctly rollback the rootfs when requested."""
    595         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater, '_run')
    596         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater,
    597                                  '_verify_update_completed')
    598         host = self.mox.CreateMockAnything()
    599         update_url = 'http://server/test/url'
    600         host.hostname = 'test_host'
    601 
    602         can_rollback_cmd = ('/usr/bin/update_engine_client --can_rollback')
    603         rollback_cmd = ('/usr/bin/update_engine_client --rollback '
    604                         '--follow')
    605 
    606         updater = autoupdater.ChromiumOSUpdater(update_url, host=host)
    607 
    608         # Return an old build which shouldn't call can_rollback.
    609         updater.host.get_release_version().AndReturn('1234.0.0')
    610         autoupdater.ChromiumOSUpdater._run(rollback_cmd)
    611         autoupdater.ChromiumOSUpdater._verify_update_completed()
    612 
    613         self.mox.ReplayAll()
    614         updater.rollback_rootfs(powerwash=True)
    615         self.mox.VerifyAll()
    616 
    617         self.mox.ResetAll()
    618         cmd_result_1 = self.mox.CreateMockAnything()
    619         cmd_result_1.exit_status = 1
    620 
    621         # Rollback but can_rollback says we can't -- return an error.
    622         updater.host.get_release_version().AndReturn('5775.0.0')
    623         autoupdater.ChromiumOSUpdater._run(can_rollback_cmd).AndRaise(
    624                 error.AutoservRunError('can_rollback failed', cmd_result_1))
    625         self.mox.ReplayAll()
    626         self.assertRaises(autoupdater.RootFSUpdateError,
    627                           updater.rollback_rootfs, True)
    628         self.mox.VerifyAll()
    629 
    630         self.mox.ResetAll()
    631         # Rollback >= version blacklisted.
    632         updater.host.get_release_version().AndReturn('5775.0.0')
    633         autoupdater.ChromiumOSUpdater._run(can_rollback_cmd)
    634         autoupdater.ChromiumOSUpdater._run(rollback_cmd)
    635         autoupdater.ChromiumOSUpdater._verify_update_completed()
    636         self.mox.ReplayAll()
    637         updater.rollback_rootfs(powerwash=True)
    638         self.mox.VerifyAll()
    639 
    640 
    641 if __name__ == '__main__':
    642   unittest.main()
    643