1# Copyright 2018 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 5import logging 6import time 7import urlparse 8 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.common_lib import utils 11from autotest_lib.client.cros.update_engine import update_engine_test as uet 12 13class autoupdate_DisconnectReconnectNetwork(uet.UpdateEngineTest): 14 """ 15 Tests removing network for a couple minutes. 16 17 This test will be used in conjunction with 18 autoupdate_ForcedOOBEUpdate.interrupt and autoupdate_Interruptions. 19 20 """ 21 version = 1 22 23 # Sometimes when network is disabled update_engine progress will move a 24 # little. To prevent false positives we fail only for > 1.5% movement. 25 _ACCEPTED_MOVEMENT = 0.015 26 27 def _has_progress_stopped(self): 28 """Checks that the update_engine progress has stopped moving.""" 29 before = self._get_update_engine_status()[self._PROGRESS] 30 for i in range(0, 10): 31 if before != self._get_update_engine_status()[self._PROGRESS]: 32 return False 33 time.sleep(1) 34 return True 35 36 37 def run_once(self, update_url, time_without_network=120): 38 if self._is_update_finished_downloading(): 39 raise error.TestFail('The update has already finished before we ' 40 'can disconnect network.') 41 self._update_server = urlparse.urlparse(update_url).hostname 42 self._disable_internet() 43 44 # Check that we are offline. 45 result = utils.ping(self._update_server, deadline=5, timeout=5) 46 if result != 2: 47 raise error.TestFail('Ping succeeded even though we were offline.') 48 49 # We are seeing update_engine progress move a very tiny amount 50 # after disconnecting network so wait for it to stop moving. 51 utils.poll_for_condition(lambda: self._has_progress_stopped, 52 desc='Waiting for update progress to stop.') 53 54 # Get the update progress as the network is down 55 progress_before = float(self._get_update_engine_status()[ 56 self._PROGRESS]) 57 58 seconds = 1 59 while seconds < time_without_network: 60 logging.info(self._get_update_engine_status()) 61 time.sleep(1) 62 seconds += 1 63 64 progress_after = float(self._get_update_engine_status()[ 65 self._PROGRESS]) 66 67 if progress_before != progress_after: 68 if progress_before < progress_after: 69 if progress_after - progress_before > self._ACCEPTED_MOVEMENT: 70 raise error.TestFail('The update continued while the ' 71 'network was supposedly disabled. ' 72 'Before: %f, After: %f' % ( 73 progress_before, progress_after)) 74 else: 75 logging.warning('The update progress moved slightly while ' 76 'network was off.') 77 elif self._is_update_finished_downloading(): 78 raise error.TestFail('The update finished while the network ' 79 'was disabled. Before: %f, After: %f' % 80 (progress_before, progress_after)) 81 else: 82 raise error.TestFail('The update appears to have restarted. ' 83 'Before: %f, After: %f' % (progress_before, 84 progress_after))