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 unittest
      8 
      9 import common
     10 
     11 import autoupdater
     12 from autotest_lib.client.common_lib import error
     13 
     14 class TestAutoUpdater(mox.MoxTestBase):
     15     """Test autoupdater module."""
     16 
     17 
     18     def testParseBuildFromUpdateUrlwithUpdate(self):
     19         """Test that we properly parse the build from an update_url."""
     20         update_url = ('http://172.22.50.205:8082/update/lumpy-release/'
     21                       'R27-3837.0.0')
     22         expected_value = 'lumpy-release/R27-3837.0.0'
     23         self.assertEqual(autoupdater.url_to_image_name(update_url),
     24                          expected_value)
     25 
     26 
     27     def testCheckVersion_1(self):
     28         """Test version check methods work for any build.
     29 
     30         Test two methods used to check version, check_version and
     31         check_version_to_confirm_install, for:
     32         1. trybot paladin build.
     33         update version: trybot-lumpy-paladin/R27-3837.0.0-b123
     34         booted version: 3837.0.2013_03_21_1340
     35 
     36         """
     37         update_url = ('http://172.22.50.205:8082/update/trybot-lumpy-paladin/'
     38                       'R27-1111.0.0-b123')
     39         updater = autoupdater.ChromiumOSUpdater(
     40                 update_url, host=self.mox.CreateMockAnything())
     41 
     42         self.mox.UnsetStubs()
     43         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     44         updater.host.get_release_version().MultipleTimes().AndReturn(
     45                                                     '1111.0.2013_03_21_1340')
     46         self.mox.ReplayAll()
     47 
     48         self.assertFalse(updater.check_version())
     49         self.assertTrue(updater.check_version_to_confirm_install())
     50 
     51         self.mox.UnsetStubs()
     52         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     53         updater.host.get_release_version().MultipleTimes().AndReturn(
     54                 '1111.0.0-rc1')
     55         self.mox.ReplayAll()
     56 
     57         self.assertFalse(updater.check_version())
     58         self.assertFalse(updater.check_version_to_confirm_install())
     59 
     60         self.mox.UnsetStubs()
     61         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     62         updater.host.get_release_version().MultipleTimes().AndReturn('1111.0.0')
     63         self.mox.ReplayAll()
     64 
     65         self.assertFalse(updater.check_version())
     66         self.assertFalse(updater.check_version_to_confirm_install())
     67 
     68         self.mox.UnsetStubs()
     69         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     70         updater.host.get_release_version().MultipleTimes().AndReturn(
     71                                                     '4444.0.0-pgo-generate')
     72         self.mox.ReplayAll()
     73 
     74         self.assertFalse(updater.check_version())
     75         self.assertFalse(updater.check_version_to_confirm_install())
     76 
     77 
     78     def testCheckVersion_2(self):
     79         """Test version check methods work for any build.
     80 
     81         Test two methods used to check version, check_version and
     82         check_version_to_confirm_install, for:
     83         2. trybot release build.
     84         update version: trybot-lumpy-release/R27-3837.0.0-b456
     85         booted version: 3837.0.0
     86 
     87         """
     88         update_url = ('http://172.22.50.205:8082/update/trybot-lumpy-release/'
     89                       'R27-2222.0.0-b456')
     90         updater = autoupdater.ChromiumOSUpdater(
     91                 update_url, host=self.mox.CreateMockAnything())
     92 
     93         self.mox.UnsetStubs()
     94         self.mox.StubOutWithMock(updater.host, 'get_release_version')
     95         updater.host.get_release_version().MultipleTimes().AndReturn(
     96                                                     '2222.0.2013_03_21_1340')
     97         self.mox.ReplayAll()
     98 
     99         self.assertFalse(updater.check_version())
    100         self.assertFalse(updater.check_version_to_confirm_install())
    101 
    102         self.mox.UnsetStubs()
    103         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    104         updater.host.get_release_version().MultipleTimes().AndReturn(
    105                 '2222.0.0-rc1')
    106         self.mox.ReplayAll()
    107 
    108         self.assertFalse(updater.check_version())
    109         self.assertFalse(updater.check_version_to_confirm_install())
    110 
    111         self.mox.UnsetStubs()
    112         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    113         updater.host.get_release_version().MultipleTimes().AndReturn('2222.0.0')
    114         self.mox.ReplayAll()
    115 
    116         self.assertFalse(updater.check_version())
    117         self.assertTrue(updater.check_version_to_confirm_install())
    118 
    119         self.mox.UnsetStubs()
    120         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    121         updater.host.get_release_version().MultipleTimes().AndReturn(
    122                                                     '4444.0.0-pgo-generate')
    123         self.mox.ReplayAll()
    124 
    125         self.assertFalse(updater.check_version())
    126         self.assertFalse(updater.check_version_to_confirm_install())
    127 
    128 
    129     def testCheckVersion_3(self):
    130         """Test version check methods work for any build.
    131 
    132         Test two methods used to check version, check_version and
    133         check_version_to_confirm_install, for:
    134         3. buildbot official release build.
    135         update version: lumpy-release/R27-3837.0.0
    136         booted version: 3837.0.0
    137 
    138         """
    139         update_url = ('http://172.22.50.205:8082/update/lumpy-release/'
    140                       'R27-3333.0.0')
    141         updater = autoupdater.ChromiumOSUpdater(
    142                 update_url, host=self.mox.CreateMockAnything())
    143 
    144         self.mox.UnsetStubs()
    145         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    146         updater.host.get_release_version().MultipleTimes().AndReturn(
    147                                                     '3333.0.2013_03_21_1340')
    148         self.mox.ReplayAll()
    149 
    150         self.assertFalse(updater.check_version())
    151         self.assertFalse(updater.check_version_to_confirm_install())
    152 
    153         self.mox.UnsetStubs()
    154         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    155         updater.host.get_release_version().MultipleTimes().AndReturn(
    156                 '3333.0.0-rc1')
    157         self.mox.ReplayAll()
    158 
    159         self.assertFalse(updater.check_version())
    160         self.assertFalse(updater.check_version_to_confirm_install())
    161 
    162         self.mox.UnsetStubs()
    163         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    164         updater.host.get_release_version().MultipleTimes().AndReturn('3333.0.0')
    165         self.mox.ReplayAll()
    166 
    167         self.assertTrue(updater.check_version())
    168         self.assertTrue(updater.check_version_to_confirm_install())
    169 
    170         self.mox.UnsetStubs()
    171         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    172         updater.host.get_release_version().MultipleTimes().AndReturn(
    173                                                     '4444.0.0-pgo-generate')
    174         self.mox.ReplayAll()
    175 
    176         self.assertFalse(updater.check_version())
    177         self.assertFalse(updater.check_version_to_confirm_install())
    178 
    179 
    180     def testCheckVersion_4(self):
    181         """Test version check methods work for any build.
    182 
    183         Test two methods used to check version, check_version and
    184         check_version_to_confirm_install, for:
    185         4. non-official paladin rc build.
    186         update version: lumpy-paladin/R27-3837.0.0-rc7
    187         booted version: 3837.0.0-rc7
    188 
    189         """
    190         update_url = ('http://172.22.50.205:8082/update/lumpy-paladin/'
    191                       'R27-4444.0.0-rc7')
    192         updater = autoupdater.ChromiumOSUpdater(
    193                 update_url, host=self.mox.CreateMockAnything())
    194 
    195         self.mox.UnsetStubs()
    196         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    197         updater.host.get_release_version().MultipleTimes().AndReturn(
    198                                                     '4444.0.2013_03_21_1340')
    199         self.mox.ReplayAll()
    200 
    201         self.assertFalse(updater.check_version())
    202         self.assertFalse(updater.check_version_to_confirm_install())
    203 
    204         self.mox.UnsetStubs()
    205         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    206         updater.host.get_release_version().MultipleTimes().AndReturn(
    207                 '4444.0.0-rc7')
    208         self.mox.ReplayAll()
    209 
    210         self.assertTrue(updater.check_version())
    211         self.assertTrue(updater.check_version_to_confirm_install())
    212 
    213         self.mox.UnsetStubs()
    214         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    215         updater.host.get_release_version().MultipleTimes().AndReturn('4444.0.0')
    216         self.mox.ReplayAll()
    217 
    218         self.assertFalse(updater.check_version())
    219         self.assertFalse(updater.check_version_to_confirm_install())
    220 
    221         self.mox.UnsetStubs()
    222         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    223         updater.host.get_release_version().MultipleTimes().AndReturn(
    224                                                     '4444.0.0-pgo-generate')
    225         self.mox.ReplayAll()
    226 
    227         self.assertFalse(updater.check_version())
    228         self.assertFalse(updater.check_version_to_confirm_install())
    229 
    230 
    231     def testCheckVersion_5(self):
    232         """Test version check methods work for any build.
    233 
    234         Test two methods used to check version, check_version and
    235         check_version_to_confirm_install, for:
    236         5. chrome-perf build.
    237         update version: lumpy-chrome-perf/R28-3837.0.0-b2996
    238         booted version: 3837.0.0
    239 
    240         """
    241         update_url = ('http://172.22.50.205:8082/update/lumpy-chrome-perf/'
    242                       'R28-4444.0.0-b2996')
    243         updater = autoupdater.ChromiumOSUpdater(
    244                 update_url, host=self.mox.CreateMockAnything())
    245 
    246         self.mox.UnsetStubs()
    247         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    248         updater.host.get_release_version().MultipleTimes().AndReturn(
    249                                                     '4444.0.2013_03_21_1340')
    250         self.mox.ReplayAll()
    251 
    252         self.assertFalse(updater.check_version())
    253         self.assertFalse(updater.check_version_to_confirm_install())
    254 
    255         self.mox.UnsetStubs()
    256         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    257         updater.host.get_release_version().MultipleTimes().AndReturn(
    258                 '4444.0.0-rc7')
    259         self.mox.ReplayAll()
    260 
    261         self.assertFalse(updater.check_version())
    262         self.assertFalse(updater.check_version_to_confirm_install())
    263 
    264         self.mox.UnsetStubs()
    265         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    266         updater.host.get_release_version().MultipleTimes().AndReturn('4444.0.0')
    267         self.mox.ReplayAll()
    268 
    269         self.assertFalse(updater.check_version())
    270         self.assertTrue(updater.check_version_to_confirm_install())
    271 
    272         self.mox.UnsetStubs()
    273         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    274         updater.host.get_release_version().MultipleTimes().AndReturn(
    275                                                     '4444.0.0-pgo-generate')
    276         self.mox.ReplayAll()
    277 
    278         self.assertFalse(updater.check_version())
    279         self.assertFalse(updater.check_version_to_confirm_install())
    280 
    281 
    282     def testCheckVersion_6(self):
    283         """Test version check methods work for any build.
    284 
    285         Test two methods used to check version, check_version and
    286         check_version_to_confirm_install, for:
    287         6. pgo-generate build.
    288         update version: lumpy-release-pgo-generate/R28-3837.0.0-b2996
    289         booted version: 3837.0.0-pgo-generate
    290 
    291         """
    292         update_url = ('http://172.22.50.205:8082/update/lumpy-release-pgo-'
    293                       'generate/R28-4444.0.0-b2996')
    294         updater = autoupdater.ChromiumOSUpdater(
    295                 update_url, host=self.mox.CreateMockAnything())
    296 
    297         self.mox.UnsetStubs()
    298         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    299         updater.host.get_release_version().MultipleTimes().AndReturn(
    300                                                     '4444.0.0-2013_03_21_1340')
    301         self.mox.ReplayAll()
    302 
    303         self.assertFalse(updater.check_version())
    304         self.assertFalse(updater.check_version_to_confirm_install())
    305 
    306         self.mox.UnsetStubs()
    307         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    308         updater.host.get_release_version().MultipleTimes().AndReturn(
    309                 '4444.0.0-rc7')
    310         self.mox.ReplayAll()
    311 
    312         self.assertFalse(updater.check_version())
    313         self.assertFalse(updater.check_version_to_confirm_install())
    314 
    315         self.mox.UnsetStubs()
    316         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    317         updater.host.get_release_version().MultipleTimes().AndReturn('4444.0.0')
    318         self.mox.ReplayAll()
    319 
    320         self.assertFalse(updater.check_version())
    321         self.assertFalse(updater.check_version_to_confirm_install())
    322 
    323         self.mox.UnsetStubs()
    324         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    325         updater.host.get_release_version().MultipleTimes().AndReturn(
    326                                                     '4444.0.0-pgo-generate')
    327         self.mox.ReplayAll()
    328 
    329         self.assertFalse(updater.check_version())
    330         self.assertTrue(updater.check_version_to_confirm_install())
    331 
    332 
    333     def testCheckVersion_7(self):
    334         """Test version check methods work for a test-ap build.
    335 
    336         Test two methods used to check version, check_version and
    337         check_version_to_confirm_install, for:
    338         6. test-ap build.
    339         update version: trybot-stumpy-test-ap/R46-7298.0.0-b23
    340         booted version: 7298.0.0
    341 
    342         """
    343         update_url = ('http://100.107.160.2:8082/update/trybot-stumpy-test-api'
    344                       '/R46-7298.0.0-b23')
    345         updater = autoupdater.ChromiumOSUpdater(
    346                 update_url, host=self.mox.CreateMockAnything())
    347 
    348         self.mox.UnsetStubs()
    349         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    350         updater.host.get_release_version().MultipleTimes().AndReturn(
    351                 '7298.0.2015_07_24_1640')
    352         self.mox.ReplayAll()
    353 
    354         self.assertFalse(updater.check_version())
    355         self.assertTrue(updater.check_version_to_confirm_install())
    356 
    357         self.mox.UnsetStubs()
    358         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    359         updater.host.get_release_version().MultipleTimes().AndReturn(
    360                 '7298.0.2015_07_24_1640')
    361         self.mox.ReplayAll()
    362 
    363         self.assertFalse(updater.check_version())
    364         self.assertTrue(updater.check_version_to_confirm_install())
    365 
    366         self.mox.UnsetStubs()
    367         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    368         updater.host.get_release_version().MultipleTimes().AndReturn('7298.0.0')
    369         self.mox.ReplayAll()
    370 
    371         self.assertFalse(updater.check_version())
    372         self.assertFalse(updater.check_version_to_confirm_install())
    373 
    374         self.mox.UnsetStubs()
    375         self.mox.StubOutWithMock(updater.host, 'get_release_version')
    376         updater.host.get_release_version().MultipleTimes().AndReturn(
    377                 '7298.0.0')
    378         self.mox.ReplayAll()
    379 
    380         self.assertFalse(updater.check_version())
    381         self.assertFalse(updater.check_version_to_confirm_install())
    382 
    383 
    384     def testTriggerUpdate(self):
    385         """Tests that we correctly handle updater errors."""
    386         update_url = 'http://server/test/url'
    387         host = self.mox.CreateMockAnything()
    388         self.mox.StubOutWithMock(host, 'run')
    389         host.hostname = 'test_host'
    390 
    391         expected_cmd = ('/usr/bin/update_engine_client --check_for_update '
    392                         '--omaha_url=http://server/test/url')
    393 
    394         updater = autoupdater.ChromiumOSUpdater(update_url, host=host)
    395 
    396         # Test with success.
    397         host.run(expected_cmd)
    398 
    399         # SSH Timeout
    400         host.run(expected_cmd).AndRaise(
    401                 error.AutoservSSHTimeout("ssh timed out", 255))
    402 
    403         # SSH Permission Error
    404         host.run(expected_cmd).AndRaise(
    405                 error.AutoservSshPermissionDeniedError("ssh timed out", 255))
    406 
    407         # Command Failed Error
    408         cmd_result_1 = self.mox.CreateMockAnything()
    409         cmd_result_1.exit_status = 1
    410 
    411         host.run(expected_cmd).AndRaise(
    412                 error.AutoservRunError("ssh timed out", cmd_result_1))
    413 
    414         # Generic SSH Error (maybe)
    415         cmd_result_255 = self.mox.CreateMockAnything()
    416         cmd_result_255.exit_status = 255
    417 
    418         host.run(expected_cmd).AndRaise(
    419                 error.AutoservRunError("Sometimes SSH specific result.",
    420                                        cmd_result_255))
    421 
    422         self.mox.ReplayAll()
    423 
    424         # Verify Success.
    425         updater.trigger_update()
    426 
    427         # Verify each type of error listed above.
    428         self.assertRaises(autoupdater.RootFSUpdateError,
    429                           updater.trigger_update)
    430         self.assertRaises(autoupdater.RootFSUpdateError,
    431                           updater.trigger_update)
    432         self.assertRaises(autoupdater.RootFSUpdateError,
    433                           updater.trigger_update)
    434         self.assertRaises(autoupdater.RootFSUpdateError,
    435                           updater.trigger_update)
    436 
    437         self.mox.VerifyAll()
    438 
    439 
    440     def testUpdateStateful(self):
    441         """Tests that we call the stateful update script with the correct args.
    442         """
    443         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater, '_run')
    444         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater,
    445                                  'get_stateful_update_script')
    446         update_url = ('http://172.22.50.205:8082/update/lumpy-chrome-perf/'
    447                       'R28-4444.0.0-b2996')
    448         static_update_url = ('http://172.22.50.205:8082/static/'
    449                              'lumpy-chrome-perf/R28-4444.0.0-b2996')
    450 
    451         # Test with clobber=False.
    452         autoupdater.ChromiumOSUpdater.get_stateful_update_script().AndReturn(
    453                 autoupdater.ChromiumOSUpdater.REMOTE_STATEUL_UPDATE_PATH)
    454         autoupdater.ChromiumOSUpdater._run(
    455                 mox.And(
    456                         mox.StrContains(
    457                                 autoupdater.ChromiumOSUpdater.
    458                                 REMOTE_STATEUL_UPDATE_PATH),
    459                         mox.StrContains(static_update_url),
    460                         mox.Not(mox.StrContains('--stateful_change=clean'))),
    461                 timeout=mox.IgnoreArg())
    462 
    463         self.mox.ReplayAll()
    464         updater = autoupdater.ChromiumOSUpdater(update_url)
    465         updater.update_stateful(clobber=False)
    466         self.mox.VerifyAll()
    467 
    468         # Test with clobber=True.
    469         self.mox.ResetAll()
    470         autoupdater.ChromiumOSUpdater.get_stateful_update_script().AndReturn(
    471                 autoupdater.ChromiumOSUpdater.REMOTE_STATEUL_UPDATE_PATH)
    472         autoupdater.ChromiumOSUpdater._run(
    473                 mox.And(
    474                         mox.StrContains(
    475                                 autoupdater.ChromiumOSUpdater.
    476                                 REMOTE_STATEUL_UPDATE_PATH),
    477                         mox.StrContains(static_update_url),
    478                         mox.StrContains('--stateful_change=clean')),
    479                 timeout=mox.IgnoreArg())
    480         self.mox.ReplayAll()
    481         updater = autoupdater.ChromiumOSUpdater(update_url)
    482         updater.update_stateful(clobber=True)
    483         self.mox.VerifyAll()
    484 
    485 
    486     def testRollbackRootfs(self):
    487         """Tests that we correctly rollback the rootfs when requested."""
    488         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater, '_run')
    489         self.mox.StubOutWithMock(autoupdater.ChromiumOSUpdater,
    490                                  '_verify_update_completed')
    491         host = self.mox.CreateMockAnything()
    492         update_url = 'http://server/test/url'
    493         host.hostname = 'test_host'
    494 
    495         can_rollback_cmd = ('/usr/bin/update_engine_client --can_rollback')
    496         rollback_cmd = ('/usr/bin/update_engine_client --rollback '
    497                         '--follow')
    498 
    499         updater = autoupdater.ChromiumOSUpdater(update_url, host=host)
    500 
    501         # Return an old build which shouldn't call can_rollback.
    502         updater.host.get_release_version().AndReturn('1234.0.0')
    503         autoupdater.ChromiumOSUpdater._run(rollback_cmd)
    504         autoupdater.ChromiumOSUpdater._verify_update_completed()
    505 
    506         self.mox.ReplayAll()
    507         updater.rollback_rootfs(powerwash=True)
    508         self.mox.VerifyAll()
    509 
    510         self.mox.ResetAll()
    511         cmd_result_1 = self.mox.CreateMockAnything()
    512         cmd_result_1.exit_status = 1
    513 
    514         # Rollback but can_rollback says we can't -- return an error.
    515         updater.host.get_release_version().AndReturn('5775.0.0')
    516         autoupdater.ChromiumOSUpdater._run(can_rollback_cmd).AndRaise(
    517                 error.AutoservRunError('can_rollback failed', cmd_result_1))
    518         self.mox.ReplayAll()
    519         self.assertRaises(autoupdater.RootFSUpdateError,
    520                           updater.rollback_rootfs, True)
    521         self.mox.VerifyAll()
    522 
    523         self.mox.ResetAll()
    524         # Rollback >= version blacklisted.
    525         updater.host.get_release_version().AndReturn('5775.0.0')
    526         autoupdater.ChromiumOSUpdater._run(can_rollback_cmd)
    527         autoupdater.ChromiumOSUpdater._run(rollback_cmd)
    528         autoupdater.ChromiumOSUpdater._verify_update_completed()
    529         self.mox.ReplayAll()
    530         updater.rollback_rootfs(powerwash=True)
    531         self.mox.VerifyAll()
    532 
    533 
    534 if __name__ == '__main__':
    535   unittest.main()
    536