blob: 121624aa52e5a2d02276788f9f82382ba2358d9b [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for the auto_updater_tranfer module.
The main parts of unittest include:
1. test transfer methods in LocalTransfer.
5. test retrials in LocalTransfer.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
from chromite.lib import auto_updater_transfer
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import partial_mock
from chromite.lib import path_util
from chromite.lib import remote_access
# pylint: disable=protected-access
def CreateLocalTransferInstance(device, **kwargs):
"""Create auto_updater_transfer.LocalTransfer instance.
Args:
device: a remote_access.ChromiumOSDeviceHandler object.
kwargs: contains parameter name and value pairs for any argument accepted
by auto_updater_transfer.LocalTransfer. The values provided through
kwargs will supersede the defaults set within this function.
Returns:
An instance of auto_updater_transfer.LocalTransfer.
"""
default_args = {'payload_dir': '', 'device_payload_dir': '', 'tempdir': '',
'payload_name': '', 'cmd_kwargs': {},
'device_restore_dir': ''}
default_args.update(kwargs)
return auto_updater_transfer.LocalTransfer(device=device, **default_args)
class CrOSLocalTransferPrivateMock(partial_mock.PartialCmdMock):
"""Mock out all transfer functions in auto_updater_transfer.LocalTransfer."""
TARGET = 'chromite.lib.auto_updater_transfer.LocalTransfer'
ATTRS = ('_TransferStatefulUpdate', '_TransferRootfsUpdate',
'_TransferUpdateUtilsPackage', '_GetStatefulUpdateScript',
'_EnsureDeviceDirectory')
def __init__(self):
partial_mock.PartialCmdMock.__init__(self)
def _TransferStatefulUpdate(self, _inst, *_args, **_kwargs):
"""Mock auto_updater_transfer.LocalTransfer._TransferStatefulUpdate."""
def _TransferRootfsUpdate(self, _inst, *_args, **_kwargs):
"""Mock auto_updater_transfer.LocalTransfer._TransferRootfsUpdate."""
def _TransferUpdateUtilsPackage(self, _inst, *_args, **_kwargs):
"""Mock auto_updater_transfer.LocalTransfer._TransferUpdateUtilsPackage."""
def _GetStatefulUpdateScript(self, _inst, *_args, **_kwargs):
"""Mock auto_updater_transfer.LocalTransfer._GetStatefulUpdateScript."""
return True, ''
def _EnsureDeviceDirectory(self, _inst, *_args, **_kwargs):
"""Mock auto_updater_transfer.LocalTransfer._EnsureDeviceDirectory."""
class CrosLocalTransferTest(cros_test_lib.MockTestCase):
"""Test whether LocalTransfer's transfer functions are retried."""
def setUp(self):
"""Mock remote_access.RemoteDevice's functions for update."""
self.PatchObject(remote_access.RemoteDevice, 'work_dir', '')
self.PatchObject(remote_access.RemoteDevice, 'CopyToWorkDir')
self.PatchObject(remote_access.RemoteDevice, 'CopyToDevice')
def testErrorTriggerRetryTransferUpdateUtils(self):
"""Test LocalTransfer._TransferUpdateUtilsPackage() is retried properly."""
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(device)
self.PatchObject(auto_updater_transfer, '_DELAY_SEC_FOR_RETRY', 1)
_MAX_RETRY = self.PatchObject(auto_updater_transfer, '_MAX_RETRY', 1)
transfer_update_utils = self.PatchObject(
auto_updater_transfer.LocalTransfer,
'_TransferUpdateUtilsPackage',
side_effect=cros_build_lib.RunCommandError('fail'))
self.assertRaises(cros_build_lib.RunCommandError,
CrOS_LocalTransfer.TransferUpdateUtilsPackage)
self.assertEqual(transfer_update_utils.call_count, _MAX_RETRY + 1)
def testErrorTriggerRetryTransferStateful(self):
"""Test LocalTransfer._TransferStatefulUpdate() is retried properly."""
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(device)
self.PatchObject(auto_updater_transfer, '_DELAY_SEC_FOR_RETRY', 1)
_MAX_RETRY = self.PatchObject(auto_updater_transfer, '_MAX_RETRY', 2)
transfer_stateful = self.PatchObject(
auto_updater_transfer.LocalTransfer,
'_TransferStatefulUpdate',
side_effect=cros_build_lib.RunCommandError('fail'))
self.assertRaises(cros_build_lib.RunCommandError,
CrOS_LocalTransfer.TransferStatefulUpdate)
self.assertEqual(transfer_stateful.call_count, _MAX_RETRY + 1)
def testErrorTriggerRetryTransferRootfs(self):
"""Test LocalTransfer._TransferRootfsUpdate() is retried properly."""
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(device)
self.PatchObject(auto_updater_transfer, '_DELAY_SEC_FOR_RETRY', 1)
_MAX_RETRY = self.PatchObject(auto_updater_transfer, '_MAX_RETRY', 3)
transfer_rootfs = self.PatchObject(
auto_updater_transfer.LocalTransfer,
'_TransferRootfsUpdate',
side_effect=cros_build_lib.RunCommandError('fail'))
self.assertRaises(cros_build_lib.RunCommandError,
CrOS_LocalTransfer.TransferRootfsUpdate)
self.assertEqual(transfer_rootfs.call_count, _MAX_RETRY + 1)
def testTransferStatefulUpdateNeedsTransfer(self):
"""Test transfer functions for stateful update.
Test whether auto_updater_transfer.LocalTransfer._GetStatefulUpdateScript()
and auto_updater_transfer.LocalTransfer._EnsureDeviceDirectory() are being
called correctly. Test the value if the instance variable
auto_updater_transfer.LocalTransfer._stateful_update_bin is set correctly
when auto_updater_transfer.LocalTransfer._original_payload_dir is set to
None.
"""
self.PatchObject(auto_updater_transfer.LocalTransfer,
'_GetStatefulUpdateScript',
return_value=[False, 'test_stateful_update_bin'])
self.PatchObject(auto_updater_transfer.LocalTransfer,
'_EnsureDeviceDirectory')
self.PatchObject(auto_updater_transfer, 'STATEFUL_FILENAME',
'test_stateful.tgz')
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(device)
CrOS_LocalTransfer._TransferStatefulUpdate()
self.assertTrue(
auto_updater_transfer.LocalTransfer._GetStatefulUpdateScript.called)
self.assertEqual(
CrOS_LocalTransfer._stateful_update_bin, 'test_stateful_update_bin')
self.assertFalse(
auto_updater_transfer.LocalTransfer._EnsureDeviceDirectory.called)
def testTransferStatefulUpdateNoNeedsTransfer(self):
"""Test transfer functions for stateful update.
Test whether auto_updater_transfer.LocalTransfer._GetStatefulUpdateScript()
and auto_updater_transfer.LocalTransfer._EnsureDeviceDirectory() are being
called correctly. Test the value if the instance variable
auto_updater_transfer.LocalTransfer._stateful_update_bin is set correctly
when auto_updater_transfer.LocalTransfer._original_payload_dir is set to
'test_dir'.
"""
self.PatchObject(auto_updater_transfer.LocalTransfer,
'_GetStatefulUpdateScript',
return_value=[True, 'test_stateful_update_bin'])
self.PatchObject(auto_updater_transfer.LocalTransfer,
'_EnsureDeviceDirectory')
self.PatchObject(auto_updater_transfer, 'STATEFUL_FILENAME',
'test_stateful.tgz')
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(
device, original_payload_dir='test_dir')
CrOS_LocalTransfer._TransferStatefulUpdate()
self.assertTrue(
auto_updater_transfer.LocalTransfer._GetStatefulUpdateScript.called)
self.assertEqual(CrOS_LocalTransfer._stateful_update_bin,
'stateful_update')
self.assertTrue(
auto_updater_transfer.LocalTransfer._EnsureDeviceDirectory.called)
def testLocalTransferCheckPayloadsError(self):
"""Test auto_updater_transfer.CheckPayloads with raising exception.
auto_updater_transfer.ChromiumOSTransferError is raised if it does not find
payloads in its path.
"""
self.PatchObject(os.path, 'exists', return_value=False)
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(
device, payload_name='does_not_exist')
self.assertRaises(
auto_updater_transfer.ChromiumOSTransferError,
CrOS_LocalTransfer.CheckPayloads)
def testLocalTransferCheckPayloads(self):
"""Test auto_updater_transfer.CheckPayloads without raising exception.
Test will fail if ChromiumOSTransferError is raised when payload exists.
"""
self.PatchObject(os.path, 'exists', return_value=True)
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(device,
payload_name='exists')
CrOS_LocalTransfer.CheckPayloads()
def testGetStatefulUpdateScriptLocalChroot(self):
"""Test auto_updater_transfer.LocalTransfer._GetStatefulUpdateScript().
Test if method returns correct responses when os.path.exists() is set to
return True for the path returned by the path_util.FromChrootPath() call.
"""
self.PatchObject(path_util, 'FromChrootPath', return_value='test_path')
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(device)
with self.PatchObject(os.path, 'exists', side_effect=[True]):
self.assertTrue(CrOS_LocalTransfer._GetStatefulUpdateScript(),
(True, 'test_path'))
def testGetStatefulUpdateScriptLocalStatefulUpdateFile(self):
"""Test auto_updater_transfer.LocalTransfer._GetStatefulUpdateScript().
Test if method returns correct responses when os.path.exists() is set to
return True for the path returned by the os.path.join() call that joins
_dev_dir and LOCAL_STATEFUL_UPDATE_FILENAME.
"""
self.PatchObject(path_util, 'FromChrootPath', return_value='test_path')
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(device)
with self.PatchObject(os.path, 'exists', side_effect=[False, True]):
self.assertEqual(CrOS_LocalTransfer._GetStatefulUpdateScript(),
(True, 'stateful_update'))
def testGetStatefulUpdateScriptRemoteStatefulUpdatePath(self):
"""Test auto_updater_transfer.LocalTransfer._GetStatefulUpdateScript().
Test if method returns correct responses when os.path.exists() is set to
return False for all its calls and _GetStatefulUpdateScript() is made to
rely on default return values.
"""
self.PatchObject(path_util, 'FromChrootPath', return_value='test_path')
with remote_access.ChromiumOSDeviceHandler('1.1.1.1') as device:
CrOS_LocalTransfer = CreateLocalTransferInstance(device)
with self.PatchObject(os.path, 'exists', side_effect=[False, False]):
self.assertEqual(CrOS_LocalTransfer._GetStatefulUpdateScript(),
(False, '/usr/local/bin/stateful_update'))