blob: 3519dbebf59736292790573631e54f05c173842f [file] [log] [blame] [edit]
#!/usr/bin/env python3
# pylint: disable=protected-access
#
# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for gooftool module."""
from collections import namedtuple
import logging
import os
from tempfile import NamedTemporaryFile
import time
import unittest
from unittest import mock
from cros.factory.device import info
from cros.factory.gooftool.bmpblk import unpack_bmpblock
from cros.factory.gooftool.common import Shell
from cros.factory.gooftool import core
from cros.factory.gooftool.core import CrosConfigIdentity
from cros.factory.gooftool.core import IdentitySourceEnum
from cros.factory.gooftool.management_engine import GetFLMSTR
from cros.factory.gooftool.management_engine import GetFLMSTRError
from cros.factory.gooftool.management_engine import ManagementEngineError
from cros.factory.gooftool.management_engine import SKU
from cros.factory.gooftool import vpd_utils
from cros.factory.test.utils import model_sku_utils
from cros.factory.unittest_utils import label_utils
from cros.factory.utils import pygpt
from cros.factory.utils import sys_utils
from cros.factory.utils.type_utils import Error
from cros.factory.utils.type_utils import Obj
from cros.factory.external.chromeos_cli import flashrom
from cros.factory.external.chromeos_cli import futility
from cros.factory.external.chromeos_cli.gsctool import FeatureManagementFlags
from cros.factory.external.chromeos_cli import ifdtool
from cros.factory.external.chromeos_cli import vpd
_TEST_DATA_PATH = os.path.join(os.path.dirname(__file__), 'testdata')
# A stub for stdout
StubStdout = namedtuple('StubStdout', ['stdout'])
class MockMainFirmware:
"""Mock main firmware object."""
def __init__(self, image=None):
self.GetFileName = lambda *args, **kwargs: 'firmware'
self.Write = lambda filename: filename == 'firmware'
self.GetFirmwareImage = lambda: image
class MockIfdtool:
def __init__(self, flmstr):
self._flmstr = flmstr
def Dump(self):
output = ''
for idx, value in self._flmstr.items():
output += f'FLMSTR{idx}: 0x{value:08x} (Host CPU/BIOS)\n'
return output
class MockIntelMainFirmware(MockMainFirmware):
"""Mock Intel's firmware image object."""
def __init__(self, flmstr, image=None):
super().__init__(image)
self.DumpDescriptor = MockIfdtool(flmstr).Dump
class MockFirmwareImage:
"""Mock firmware image object."""
def __init__(self, section_map):
self.has_section = lambda name: name in section_map
self.get_section = lambda name: section_map[name]
class MockFile:
"""Mock file object."""
def __init__(self):
self.name = 'filename'
self.read = lambda: 'read_results'
def __enter__(self):
return self
def __exit__(self, filetype, value, traceback):
pass
class MockPath(os.PathLike):
def __fspath__(self):
return 'mock_path'
def __enter__(self):
return self
def __exit__(self, filetype, value, traceback):
pass
class MockME:
FW_NO_ME = {
'RO_SECTION': b''
}
FW_ME_READ_LOCKED = {
ifdtool.IntelLayout.ME.value: b'\xff' * 1024
}
FW_ME_READ_UNLOCKED = {
ifdtool.IntelLayout.ME.value: b'\x55' * 1024
}
DESCRIPTOR_UNLOCKED = {
1: 0xffffffff,
2: 0xffffffff,
3: 0xffffffff,
5: 0xffffffff,
}
def GetMockedCBMEM(self, sku_flag, mode='NO', fw_table='OK',
wp_ro_enabled='YES', ro_wp_vals=('0x1000', '0x14FFFF')):
output = (f'ME: HFSTS3 : 0x{sku_flag:08x}\n'
f'ME: Manufacturing Mode : {mode}\n'
f'ME: FW Partition Table : {fw_table}\n'
f'ME: WP for RO is enabled : {wp_ro_enabled}\n')
if ro_wp_vals:
output += (f'ME: RO write protection scope - '
f'Start={ro_wp_vals[0]}, End={ro_wp_vals[1]}\n')
return Obj(success=True, stdout=output)
class UtilTest(unittest.TestCase):
"""Unit test for core.Util."""
def setUp(self):
self._util = core.Util()
# Mock out small wrapper functions that do not need unittests.
self._util.shell = mock.Mock(Shell)
# yapf: disable
self._util._IsDeviceFixed = mock.Mock() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._util.FindScript = mock.Mock() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def testGetPrimaryDevicePath(self):
"""Test for GetPrimaryDevice."""
# yapf: disable
self._util._IsDeviceFixed.return_value = True # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._util.shell.return_value = StubStdout('/dev/sda') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertEqual('/dev/sda', self._util.GetPrimaryDevicePath())
self.assertEqual('/dev/sda1', self._util.GetPrimaryDevicePath(1))
self.assertEqual('/dev/sda2', self._util.GetPrimaryDevicePath(2))
# also test thin callers
self.assertEqual('/dev/sda5', self._util.GetReleaseRootPartitionPath())
self.assertEqual('/dev/sda4', self._util.GetReleaseKernelPartitionPath())
# yapf: disable
self._util.shell.assert_any_call('rootdev -s -d') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._util._IsDeviceFixed.assert_any_call('sda') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def testGetPrimaryDevicePathNotFixed(self):
"""Test for GetPrimaryDevice when multiple primary devices are found."""
# yapf: disable
self._util._IsDeviceFixed.return_value = False # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._util.shell.return_value = StubStdout('/dev/sda') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaises(Error, self._util.GetPrimaryDevicePath)
# yapf: disable
self._util.shell.assert_any_call('rootdev -s -d') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._util._IsDeviceFixed.assert_any_call('sda') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def testFindRunScript(self):
stub_result = lambda: None
# yapf: disable
stub_result.success = True # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._util.FindScript.return_value = 'script' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._util.shell.return_value = stub_result # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._util.FindAndRunScript('script')
# yapf: disable
self._util.shell.assert_called_with('script') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._util.FindAndRunScript('script', None)
# yapf: disable
self._util.shell.assert_called_with('script') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._util.FindAndRunScript('script', ['a'])
# yapf: disable
self._util.shell.assert_called_with('script a') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._util.FindAndRunScript('script', ['a', 'b'])
# yapf: disable
self._util.shell.assert_called_with('script a b') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._util.FindAndRunScript('script', ['a', 'b'], ['c=d'])
# yapf: disable
self._util.shell.assert_called_with('c=d script a b') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._util.FindAndRunScript('script', None, ['c=d'])
# yapf: disable
self._util.shell.assert_called_with('c=d script') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
class GooftoolTest(unittest.TestCase):
"""Unit test for Gooftool."""
_SIMPLE_MODEL_SKU_CONFIG_REBRAND = {
'custom_type': 'rebrand',
'fw_config': '90913',
}
_SIMPLE_MODEL_SKU_CONFIG_CUSTOM_LABEL = {
'custom_type': 'custom_label',
'fw_config': '90913',
}
def setUp(self):
self._gooftool = core.Gooftool(
hwid_version=3, project='chromebook', hwdb_path=_TEST_DATA_PATH)
self._gooftool._util = mock.Mock(core.Util)
self._gooftool._util.shell = mock.Mock(Shell)
self._gooftool._util.GetTestImageBoardName = mock.Mock()
self._gooftool.futility = mock.Mock(futility.Futility)
self._gooftool._flashrom = mock.Mock(flashrom)
self._gooftool._ifdtool = mock.Mock(ifdtool)
self._gooftool._unpack_bmpblock = mock.Mock(unpack_bmpblock)
self._gooftool.vpd = mock.Mock(self._gooftool.vpd)
self._gooftool._named_temporary_file = mock.Mock(NamedTemporaryFile)
self._gooftool._cros_config = mock.Mock(self._gooftool._cros_config)
self._gooftool._cros_config.GetCustomLabelTag.return_value = (True,
'unittest')
self._gooftool._cros_config.GetModelName.return_value = 'unittest'
self._gooftool._cros_config.GetFirmwareImageName.return_value = 'unittest'
self._gooftool._gsctool = mock.Mock(self._gooftool._gsctool)
self._gooftool._gsctool.GetFeatureManagementFlags.return_value = (
FeatureManagementFlags(False, 0))
def testLoadHWIDDatabase(self):
db = self._gooftool.db # Shouldn't raise any exception.
# Assure loading DB multiple times is prevented.
self.assertIs(self._gooftool.db, db)
@mock.patch.object(sys_utils, 'MountPartition', autospec=True)
@mock.patch.object(pygpt, 'GPT', autospec=True)
def testVerifyKey(self, mock_pygpt, mock_mount):
# yapf: disable
self._gooftool._util.GetReleaseKernelPathFromRootPartition.return_value = '/dev/zero' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._gooftool._flashrom.LoadMainFirmware.side_effect = [
MockMainFirmware(),
MockMainFirmware(
MockFirmwareImage({
'GBB': b'GBB',
'FW_MAIN_A': b'MA',
'FW_MAIN_B': b'MB',
'VBLOCK_A': b'VA',
'VBLOCK_B': b'VB'
}))
]
# TODO(hungte) Improve unit test scope.
def fake_tmpexc(_message, _command, _fail_message=None, regex=None):
return 'FAKE_MATCH' if regex else None
class FakeGPT:
def LoadFromFile(self):
gpt = mock.Mock()
gpt.IsLastPartition = mock.Mock(return_value=True)
return gpt
mock_mount.return_value = MockPath()
mock_pygpt.return_value = FakeGPT()
self._gooftool.VerifyKeys('/dev/null', _tmpexec=fake_tmpexc)
self._gooftool._flashrom.LoadMainFirmware.assert_called()
def testVerifySystemTime(self):
# yapf: disable
self._gooftool._util.GetReleaseRootPartitionPath.return_value = 'root' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.return_value = Obj( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
stdout='Filesystem created: Mon Jan 25 16:13:18 2016\n',
success=True)
bad_system_time = time.mktime(time.strptime('Sun Jan 24 15:00:00 2016'))
good_system_time = time.mktime(time.strptime('Tue Jan 26 15:00:00 2016'))
self._gooftool.VerifySystemTime(system_time=good_system_time)
self.assertRaises(Error, self._gooftool.VerifySystemTime,
release_rootfs='root', system_time=bad_system_time)
# yapf: disable
self._gooftool._util.GetReleaseRootPartitionPath.assert_called() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.assert_called_with('dumpe2fs -h root') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def testVerifyRootFs(self):
fake_attrs = {'test': 'value'}
# yapf: disable
self._gooftool._util.GetPartitionDevice.return_value = 'root' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetCgptAttributes.return_value = fake_attrs # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.SetCgptAttributes.return_value = None # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._gooftool.VerifyRootFs('root3')
# yapf: disable
self._gooftool._util.GetPartitionDevice.assert_called_once_with('root3') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetCgptAttributes.assert_called_once_with('root') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.InvokeChromeOSPostInstall.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'root3')
# yapf: disable
self._gooftool._util.SetCgptAttributes.assert_called_once_with(fake_attrs, # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'root')
def testVerifyTPM(self):
# It's correct tpm manager status.
# yapf: disable
self._gooftool._util.GetTPMManagerStatus.return_value = { # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'is_enabled': 'true',
'is_owned': 'false',
'is_owner_password_present': 'false'
}
# Should pass w/ correct tpm sysfs status + correct tpm manager status.
self._gooftool.VerifyTPM()
def testVerifyTPMWrongManagerStatus(self):
# It's wrong tpm manager status, the correct should be:
# is_enabled = true, is_owned = false, is_owner_password_present = false
# yapf: disable
self._gooftool._util.GetTPMManagerStatus.return_value = { # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'is_enabled': 'false',
'is_owned': 'false',
'is_owner_password_present': 'false'
}
# Should raise error w/ wrong tpm manager status.
self.assertRaises(Error, self._gooftool.VerifyTPM)
def testVerifyManagementEngineLockedNoME(self):
# No ME firmware
self._gooftool._ifdtool.LoadIntelMainFirmware.return_value = \
MockIntelMainFirmware(None, MockFirmwareImage(MockME.FW_NO_ME))
self._gooftool.VerifyManagementEngineLocked()
def testVerifyManagementEngineLockedUnknownSKU(self):
self._gooftool._ifdtool.LoadIntelMainFirmware.return_value = \
MockIntelMainFirmware(
MockME.DESCRIPTOR_UNLOCKED,
MockFirmwareImage(MockME.FW_ME_READ_LOCKED))
# Raise since it is an unknown SKU
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(SKU.Unknown.value) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaises(ManagementEngineError,
self._gooftool.VerifyManagementEngineLocked)
def testVerifyManagementEngineLockedConsumerSKU(self):
consumer = SKU.Consumer
board = 'hatch'
# Read locked ME section + locked cbmem + locked descriptor
self._gooftool._ifdtool.LoadIntelMainFirmware.return_value = \
MockIntelMainFirmware(
GetFLMSTR(consumer, board),
MockFirmwareImage(MockME.FW_ME_READ_LOCKED))
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(consumer.value) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetTestImageBoardName.return_value = board # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Pass since everything is fine
self._gooftool.VerifyManagementEngineLocked()
# Read unlocked ME section + locked cbmem + locked descriptor
self._gooftool._ifdtool.LoadIntelMainFirmware.return_value = \
MockIntelMainFirmware(
GetFLMSTR(consumer, board),
MockFirmwareImage(MockME.FW_ME_READ_UNLOCKED))
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(consumer.value) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Raise since the ME section is not 0xff
self.assertRaises(ManagementEngineError,
self._gooftool.VerifyManagementEngineLocked)
# Read locked ME section + locked cbmem + unlocked descriptor
self._gooftool._ifdtool.LoadIntelMainFirmware.return_value = \
MockIntelMainFirmware(
MockME().DESCRIPTOR_UNLOCKED,
MockFirmwareImage(MockME.FW_ME_READ_LOCKED))
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(consumer.value) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Raise since the descriptor is not locked
self.assertRaises(ManagementEngineError,
self._gooftool.VerifyManagementEngineLocked)
def testVerifyManagementEngineLockedLiteSKU(self):
lite = SKU.Lite
board = 'brya'
# Read locked ME section + locked cbmem + locked descriptor
self._gooftool._ifdtool.LoadIntelMainFirmware.return_value = \
MockIntelMainFirmware(
GetFLMSTR(lite, board),
MockFirmwareImage(MockME.FW_ME_READ_LOCKED))
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(lite.value) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetTestImageBoardName.return_value = board # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Pass since everything is fine
self._gooftool.VerifyManagementEngineLocked()
# Read locked ME section + locked cbmem with invalid manufacturing mode
# + locked descriptor
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(lite.value, mode='YES') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Raise since Manufacturing Mode is not NO
self.assertRaises(ManagementEngineError,
self._gooftool.VerifyManagementEngineLocked)
# Read locked ME section + locked cbmem with invalid FW partition table
# + locked descriptor
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(lite.value, fw_table='BAD') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Raise since FW Partition Table is not OK
self.assertRaises(ManagementEngineError,
self._gooftool.VerifyManagementEngineLocked)
# Read locked ME section + locked cbmem with WP in RO not enabled
# + locked descriptor
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(lite.value, wp_ro_enabled='NO') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Raise since WP in RO is not YES
self.assertRaises(ManagementEngineError,
self._gooftool.VerifyManagementEngineLocked)
# Read locked ME section + locked cbmem + locked descriptor
# No RO WP scope.
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(lite.value, ro_wp_vals=None) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Raise since there's no RO WP scope.
self.assertRaises(ManagementEngineError,
self._gooftool.VerifyManagementEngineLocked)
# Read unlocked ME section + locked cbmem + locked descriptor
self._gooftool._ifdtool.LoadIntelMainFirmware.return_value = \
MockIntelMainFirmware(
GetFLMSTR(lite, board),
MockFirmwareImage(MockME.FW_ME_READ_UNLOCKED))
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(lite.value) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Pass since we don't check the SI_ME content
self._gooftool.VerifyManagementEngineLocked()
# Read locked ME section + locked cbmem + unlocked descriptor
self._gooftool._ifdtool.LoadIntelMainFirmware.return_value = \
MockIntelMainFirmware(
MockME().DESCRIPTOR_UNLOCKED,
MockFirmwareImage(MockME.FW_ME_READ_LOCKED))
# yapf: disable
self._gooftool._util.shell.return_value = MockME().GetMockedCBMEM(lite.value) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Raise since the descriptor is not locked
self.assertRaises(ManagementEngineError,
self._gooftool.VerifyManagementEngineLocked)
def testGenerateStableDeviceSecretSuccess(self):
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.return_value = '6887.0.0' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.return_value = StubStdout('00' * 32 + '\n') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._gooftool.GenerateStableDeviceSecret()
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.assert_any_call() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'libhwsec_client get_random 32', log=False)
# yapf: disable
self._gooftool.vpd.UpdateData.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
dict(stable_device_secret_DO_NOT_SHARE='00' * 32),
partition=vpd.VPD_READONLY_PARTITION_NAME)
def testGenerateStableDeviceSecretNoOutput(self):
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.return_value = '6887.0.0' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.return_value = StubStdout('') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaisesRegex(Error, 'Error validating device secret',
self._gooftool.GenerateStableDeviceSecret)
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.assert_any_call() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'libhwsec_client get_random 32', log=False)
def testGenerateStableDeviceSecretShortOutput(self):
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.return_value = '6887.0.0' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.return_value = StubStdout('00' * 31) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaisesRegex(Error, 'Error validating device secret',
self._gooftool.GenerateStableDeviceSecret)
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.assert_any_call() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'libhwsec_client get_random 32', log=False)
def testGenerateStableDeviceSecretBadOutput(self):
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.return_value = '6887.0.0' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.return_value = StubStdout('Error!') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaisesRegex(Error, 'Error validating device secret',
self._gooftool.GenerateStableDeviceSecret)
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.assert_any_call() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'libhwsec_client get_random 32', log=False)
def testGenerateStableDeviceSecretBadReleaseImageVersion(self):
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.return_value = '6886.0.0' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaisesRegex(Error, 'Release image version',
self._gooftool.GenerateStableDeviceSecret)
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.assert_any_call() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def testGenerateStableDeviceSecretVPDWriteFailed(self):
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.return_value = '6887.0.0' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.return_value = StubStdout('00' * 32 + '\n') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool.vpd.UpdateData.side_effect = Exception() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaisesRegex(Error, 'Error writing device secret',
self._gooftool.GenerateStableDeviceSecret)
# yapf: disable
self._gooftool._util.GetReleaseImageVersion.assert_any_call() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'libhwsec_client get_random 32', log=False)
# yapf: disable
self._gooftool.vpd.UpdateData.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
dict(stable_device_secret_DO_NOT_SHARE='00' * 32),
partition=vpd.VPD_READONLY_PARTITION_NAME)
def testWriteHWID(self):
self._gooftool._flashrom.LoadMainFirmware.return_value = MockMainFirmware()
self._gooftool.WriteHWID('hwid')
# yapf: disable
self._gooftool.futility.WriteHWID.assert_called_with('firmware', 'hwid') # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._gooftool._flashrom.LoadMainFirmware.assert_called()
def testVerifyWPSwitch(self):
shell_calls = [
mock.call('crossystem wpsw_cur'),
mock.call('ectool flashprotect')]
# 1st call: AP and EC wpsw are enabled.
# yapf: disable
self._gooftool._util.shell.side_effect = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
StubStdout('1'),
StubStdout('Flash protect flags: 0x00000008 wp_gpio_asserted\n'
'Valid flags:...')]
self._gooftool.VerifyWPSwitch()
# yapf: disable
self.assertEqual(self._gooftool._util.shell.call_args_list, shell_calls) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# 2nd call: AP wpsw is disabled.
# yapf: disable
self._gooftool._util.shell.reset_mock() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.side_effect = [StubStdout('0')] # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaises(Error, self._gooftool.VerifyWPSwitch)
# yapf: disable
self.assertEqual(self._gooftool._util.shell.call_args_list, # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
[shell_calls[0]])
# 3st call: AP wpsw is enabled but EC is disabled.
# yapf: disable
self._gooftool._util.shell.reset_mock() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.shell.side_effect = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
StubStdout('1'),
StubStdout('Flash protect flags: 0x00000000\nValid flags:...')]
self.assertRaises(Error, self._gooftool.VerifyWPSwitch)
# yapf: disable
self.assertEqual(self._gooftool._util.shell.call_args_list, shell_calls) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def _SetupVPDMocks(self, ro=None, rw=None):
"""Set up mocks for vpd related tests.
Args:
ro: The dictionary to use for the RO VPD if set.
rw: The dictionary to use for the RW VPD if set.
"""
def GetAllDataSideEffect(*unused_args, **kwargs):
if kwargs['partition'] == vpd.VPD_READONLY_PARTITION_NAME:
return ro
if kwargs['partition'] == vpd.VPD_READWRITE_PARTITION_NAME:
return rw
return None
# yapf: disable
self._gooftool.vpd.GetAllData.side_effect = GetAllDataSideEffect # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def testVerifyReleaseChannel_CanaryChannel(self):
# yapf: disable
self._gooftool._util.GetReleaseImageChannel.return_value = 'canary-channel' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetAllowedReleaseImageChannels.return_value = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'dev', 'beta', 'stable']
self.assertRaisesRegex(Error,
'Release image channel is incorrect: canary-channel',
self._gooftool.VerifyReleaseChannel)
def testVerifyReleaseChannel_DevChannel(self):
# yapf: disable
self._gooftool._util.GetReleaseImageChannel.return_value = 'dev-channel' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetAllowedReleaseImageChannels.return_value = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'dev', 'beta', 'stable']
self._gooftool.VerifyReleaseChannel()
def testVerifyReleaseChannel_DevChannelFailed(self):
# yapf: disable
self._gooftool._util.GetReleaseImageChannel.return_value = 'dev-channel' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetAllowedReleaseImageChannels.return_value = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'dev', 'beta', 'stable']
enforced_channels = ['stable', 'beta']
self.assertRaisesRegex(Error,
'Release image channel is incorrect: dev-channel',
self._gooftool.VerifyReleaseChannel,
enforced_channels)
def testVerifyReleaseChannel_BetaChannel(self):
# yapf: disable
self._gooftool._util.GetReleaseImageChannel.return_value = 'beta-channel' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetAllowedReleaseImageChannels.return_value = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'dev', 'beta', 'stable']
self._gooftool.VerifyReleaseChannel()
def testVerifyReleaseChannel_BetaChannelFailed(self):
# yapf: disable
self._gooftool._util.GetReleaseImageChannel.return_value = 'beta-channel' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetAllowedReleaseImageChannels.return_value = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'dev', 'beta', 'stable']
enforced_channels = ['stable']
self.assertRaisesRegex(Error,
'Release image channel is incorrect: beta-channel',
self._gooftool.VerifyReleaseChannel,
enforced_channels)
def testVerifyReleaseChannel_StableChannel(self):
# yapf: disable
self._gooftool._util.GetReleaseImageChannel.return_value = 'stable-channel' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetAllowedReleaseImageChannels.return_value = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'dev', 'beta', 'stable']
self._gooftool.VerifyReleaseChannel()
def testVerifyReleaseChannel_InvalidEnforcedChannels(self):
# yapf: disable
self._gooftool._util.GetReleaseImageChannel.return_value = 'stable-channel' # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._util.GetAllowedReleaseImageChannels.return_value = [ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'dev', 'beta', 'stable']
enforced_channels = ['canary']
self.assertRaisesRegex(Error,
r'Enforced channels are incorrect: \[\'canary\'\].',
self._gooftool.VerifyReleaseChannel,
enforced_channels)
# TODO (b/212216855)
@label_utils.Informational
def testSetFirmwareBitmapLocalePass(self):
"""Test for a normal process of setting firmware bitmap locale."""
# Stub data from VPD for zh.
self._gooftool._flashrom.LoadMainFirmware.return_value = MockMainFirmware()
self._SetupVPDMocks(ro=dict(region='tw'))
f = MockFile()
f.read = lambda: 'ja\nzh\nen'
image_file = 'firmware'
# yapf: disable
self._gooftool._named_temporary_file.return_value = f # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
shell_calls = [
mock.call(
f'cbfstool {image_file} extract -n locales -f {f.name} -r COREBOOT'
),
# Expect index = 1 for zh is matched.
mock.call('crossystem loc_idx=1')
]
self._gooftool.SetFirmwareBitmapLocale()
self._gooftool._flashrom.LoadMainFirmware.assert_any_call()
# yapf: disable
self.assertEqual(self._gooftool._util.shell.call_args_list, shell_calls) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# TODO (b/212216855)
@label_utils.Informational
def testSetFirmwareBitmapLocaleNoCbfs(self):
"""Test for legacy firmware, which stores locale in bmpblk."""
# Stub data from VPD for zh.
self._gooftool._flashrom.LoadMainFirmware.return_value = MockMainFirmware()
self._SetupVPDMocks(ro=dict(region='tw'))
f = MockFile()
f.read = lambda: ''
image_file = 'firmware'
# yapf: disable
self._gooftool._named_temporary_file.return_value = f # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._unpack_bmpblock.return_value = {'locales': ['ja', 'zh', # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
'en']}
shell_calls = [
mock.call(
f'cbfstool {image_file} extract -n locales -f {f.name} -r COREBOOT'
),
mock.call(f'futility gbb -g --bmpfv={f.name} {image_file}'),
# Expect index = 1 for zh is matched.
mock.call('crossystem loc_idx=1')
]
self._gooftool.SetFirmwareBitmapLocale()
self._gooftool._flashrom.LoadMainFirmware.assert_any_call()
# yapf: disable
self.assertEqual(self._gooftool._util.shell.call_args_list, shell_calls) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self._gooftool._unpack_bmpblock.assert_called_once_with(f.read()) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# TODO (b/212216855)
@label_utils.Informational
def testSetFirmwareBitmapLocaleNoMatch(self):
"""Test for setting firmware bitmap locale without matching default locale.
"""
# Stub data from VPD for en.
self._gooftool._flashrom.LoadMainFirmware.return_value = MockMainFirmware()
self._SetupVPDMocks(ro=dict(region='us'))
f = MockFile()
# Stub for multiple available locales in the firmware bitmap, but missing
# 'en'.
f.read = lambda: 'ja\nzh\nfr'
image_file = 'firmware'
# yapf: disable
self._gooftool._named_temporary_file.return_value = f # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaises(Error, self._gooftool.SetFirmwareBitmapLocale)
self._gooftool._flashrom.LoadMainFirmware.assert_any_call()
# yapf: disable
self._gooftool._util.shell.assert_called_once_with( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
f'cbfstool {image_file} extract -n locales -f {f.name} -r COREBOOT')
def testSetFirmwareBitmapLocaleNoVPD(self):
"""Test for setting firmware bitmap locale without default locale in VPD."""
# VPD has no locale data.
self._gooftool._flashrom.LoadMainFirmware.return_value = MockMainFirmware()
self._SetupVPDMocks(ro={})
self.assertRaises(Error, self._gooftool.SetFirmwareBitmapLocale)
def testGetSystemDetails(self):
"""Test for GetSystemDetails to ensure it returns desired keys."""
self._gooftool._util.sys_interface = mock.Mock()
self._gooftool._util.sys_interface.info = info.SystemInfo()
# yapf: disable
self._gooftool._util.GetSystemInfo.return_value = core.Util.GetSystemInfo( # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._gooftool._util)
system_summary_keys = {
'cbi',
'crosid',
'device',
'factory',
'fw',
'gsc',
'hw',
'image',
'system',
'vpd',
'wp',
'crossystem',
'modem_status',
}
self.assertEqual(system_summary_keys,
set(self._gooftool.GetSystemDetails().keys()))
# yapf: disable
self._gooftool._util.GetSystemInfo.assert_called_once() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
def testGSCWriteFlashInfoWithCustomType(self):
"""Test for custom label field.
Custom label field should only exist in VPD when custom type is custom
label.
"""
model_sku_utils.GetDesignConfig = mock.Mock()
# yapf: disable
self._gooftool.GSCSetBoardId = mock.Mock() # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self._gooftool._util.sys_interface = None
# custom type is 'custom_label' but no custom label field in VPD
config = self._SIMPLE_MODEL_SKU_CONFIG_CUSTOM_LABEL
model_sku_utils.GetDesignConfig.return_value = config
# yapf: disable
self._gooftool.vpd.GetValue.return_value = None # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
self.assertRaisesRegex(
Error, 'This is a custom label device, but custom_label_tag is not set '
'in VPD.', self._gooftool.GSCWriteFlashInfo)
# custom type is rebrand and no custom label field in VPD
config = self._SIMPLE_MODEL_SKU_CONFIG_REBRAND
model_sku_utils.GetDesignConfig.return_value = config
self.assertRaisesRegex(
Error, 'custom_label_tag reported by cros_config and VPD does not '
'match. Have you reboot the device after updating VPD '
'fields?', self._gooftool.GSCWriteFlashInfo)
def testInitialCrosConfigIdentity_KeysAreStrings(self):
isString = [
isinstance(key, str)
for key in CrosConfigIdentity(IdentitySourceEnum.cros_config).keys()
]
self.assertEqual(isString, [True] * len(isString))
def testMatchConfigWithIdentity_X86_Frid(self):
identity = CrosConfigIdentity(IdentitySourceEnum.current_identity)
identity['smbios-name-match'] = 'skolas'
identity['frid'] = 'Google_Skolas'
identity['sku-id'] = 'sku1'
identity['customization-id'] = '1'
identity['custom-label-tag'] = 'custom-label-tag'
identity[vpd_utils.non_inclusive_custom_label_tag_cros_config_key] = 'empty'
configs = [
{
'brand-code': 'zzcr',
'identity': {
'frid': 'Google_Skolas',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 1
}
},
{
'brand-code': 'zzcr',
'identity': {
'frid': 'Google_Skolas',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 2
}
},
{
'brand-code': 'zzcr',
'identity': {
'frid': 'Google_Skolas_Something',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 1
}
},
]
matched_config = self._gooftool._MatchConfigWithIdentity(configs, identity)
self.assertDictEqual(matched_config, configs[0])
def testMatchConfigWithIdentity_extraVPD(self):
identity = CrosConfigIdentity(IdentitySourceEnum.current_identity)
identity['frid'] = 'Google_Skolas'
identity['sku-id'] = 'sku1'
identity['customization-id'] = 'empty'
identity['custom-label-tag'] = 'custom-label-tag'
identity[vpd_utils.non_inclusive_custom_label_tag_cros_config_key] = 'empty'
configs = [
{
'brand-code': 'zzcr',
'identity': {
'frid': 'Google_Skolas',
'sku-id': 1
}
},
]
matched_config = self._gooftool._MatchConfigWithIdentity(configs, identity)
self.assertIsNone(matched_config)
def testMatchConfigWithIdentity_noVPD(self):
identity = CrosConfigIdentity(IdentitySourceEnum.current_identity)
identity['frid'] = 'Google_Skolas'
identity['sku-id'] = 'sku1'
identity['customization-id'] = 'empty'
identity['custom-label-tag'] = 'empty'
identity[vpd_utils.non_inclusive_custom_label_tag_cros_config_key] = 'empty'
configs = [
{
'brand-code': 'zzcr',
'identity': {
'frid': 'Google_Skolas',
'sku-id': 1
}
},
]
matched_config = self._gooftool._MatchConfigWithIdentity(configs, identity)
self.assertDictEqual(matched_config, configs[0])
def testMatchConfigWithIdentity_Arm_Frid(self):
identity = CrosConfigIdentity(IdentitySourceEnum.current_identity)
identity['device-tree-compatible-match'] = \
'google,tentacruelgoogle,corsolamediatek,mt8186'
identity['frid'] = 'Google_Tentacruel'
identity['sku-id'] = '1'
identity['customization-id'] = '1'
identity['custom-label-tag'] = 'custom-label-tag'
identity[vpd_utils.non_inclusive_custom_label_tag_cros_config_key] = 'empty'
configs = [
{
'brand-code': 'zzcr',
'identity': {
'frid': 'Google_Tentacruel',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 1
}
},
{
'brand-code': 'zzcr',
'identity': {
'frid': 'Google_Tentacruel',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 2
}
},
{
'brand-code': 'zzcr',
'identity': {
'frid': 'Google_Tentacruel',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 1
}
},
]
matched_config = self._gooftool._MatchConfigWithIdentity(configs, identity)
self.assertDictEqual(matched_config, configs[0])
def testMatchConfigWithIdentity_Smbios(self):
identity = CrosConfigIdentity(IdentitySourceEnum.current_identity)
identity['smbios-name-match'] = 'Skolas'
identity['frid'] = 'Google_Skolas'
identity['sku-id'] = 'sku1'
identity['customization-id'] = '1'
identity['custom-label-tag'] = 'custom-label-tag'
identity[vpd_utils.non_inclusive_custom_label_tag_cros_config_key] = 'empty'
configs = [
{
'brand-code': 'zzcr',
'identity': {
'smbios-name-match': 'Skolas',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 1
}
},
{
'brand-code': 'zzcr',
'identity': {
'smbios-name-match': 'Skolas',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 2
}
},
{
'brand-code': 'zzcr',
'identity': {
'smbios-name-match': 'Skolas',
'custom-label-tag': 'some-other-tag',
'customization-id': '2',
'sku-id': 1
}
},
]
matched_config = self._gooftool._MatchConfigWithIdentity(configs, identity)
self.assertDictEqual(matched_config, configs[0])
def testMatchConfigWithIdentity_DeviceTree(self):
identity = CrosConfigIdentity(IdentitySourceEnum.current_identity)
identity['device-tree-compatible-match'] = \
'google,tentacruelgoogle,corsolamediatek,mt8186'
identity['frid'] = 'Google_Tentacruel'
identity['sku-id'] = '1'
identity['customization-id'] = '1'
identity['custom-label-tag'] = 'custom-label-tag'
identity[vpd_utils.non_inclusive_custom_label_tag_cros_config_key] = 'empty'
configs = [
{
'brand-code': 'zzcr',
'identity': {
'device-tree-compatible-match': 'google,tentacruel',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 1
}
},
{
'brand-code': 'zzcr',
'identity': {
'device-tree-compatible-match': 'google,tentacruel',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 2
}
},
{
'brand-code': 'zzcr',
'identity': {
'device-tree-compatible-match': 'google,tentacruel',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1',
'sku-id': 1
}
},
]
matched_config = self._gooftool._MatchConfigWithIdentity(configs, identity)
self.assertDictEqual(matched_config, configs[0])
def testMatchConfigWithIdentity_NoSkuId(self):
identity = CrosConfigIdentity(IdentitySourceEnum.current_identity)
identity['smbios-name-match'] = 'Hayato'
identity['frid'] = 'Google_Hayato'
identity['sku-id'] = ''
identity['customization-id'] = '1'
identity['custom-label-tag'] = 'custom-label-tag'
identity[vpd_utils.non_inclusive_custom_label_tag_cros_config_key] = 'empty'
configs = [
{
'brand-code': 'zzcr',
'identity': {
'smbios-name-match': 'Hayato',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1'
}
},
{
'brand-code': 'zzcr',
'identity': {
'smbios-name-match': 'Hayato',
'custom-label-tag': 'some-other-tag',
'customization-id': '2'
}
},
{
'brand-code': 'zzcr',
'identity': {
'smbios-name-match': 'Hayato_something',
'custom-label-tag': 'custom-label-tag',
'customization-id': '1'
}
},
]
matched_config = self._gooftool._MatchConfigWithIdentity(configs, identity)
self.assertDictEqual(matched_config, configs[0])
def testGetFLMSTR_ValidInputs(self):
test_cases = [
(SKU.Consumer, 'hatch', {
1: 0x00200300,
2: 0x00400500,
3: 0x00000000,
5: 0x00000000
}),
(SKU.Lite, 'nissa', {
1: 0x00200700,
2: 0x00400500,
3: 0x00000000,
5: 0x00000000
}),
(SKU.Lite, 'rex', {
1: 0x00220700,
2: 0x00400500,
3: 0x00000000,
5: 0x00000000
}),
]
for sku, board, expected_output in test_cases:
result = GetFLMSTR(sku, board)
self.assertDictEqual(result, expected_output)
def testGetFLMSTR_InvalidSku(self):
with self.assertRaises(GetFLMSTRError):
GetFLMSTR(SKU.Unknown, 'abc')
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
unittest.main()