sushy/sushy/tests/unit/resources/system/test_bios.py

449 lines
20 KiB
Python

# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import datetime
from http import client as http_client
import json
from unittest import mock
from dateutil import parser
from sushy import exceptions
from sushy.resources import constants as res_cons
from sushy.resources.registry import attribute_registry
from sushy.resources.registry import message_registry
from sushy.resources import settings
from sushy.resources.system import bios
from sushy.tests.unit import base
class BiosTestCase(base.TestCase):
def setUp(self):
super(BiosTestCase, self).setUp()
self.conn = mock.Mock()
with open('sushy/tests/unit/json_samples/bios.json') as f:
self.bios_json = json.load(f)
with open('sushy/tests/unit/json_samples/bios_settings.json') as f:
self.bios_settings_json = json.load(f)
self.conn.get.return_value.json.side_effect = [
self.bios_json,
self.bios_settings_json,
self.bios_settings_json]
registries = {}
conn = mock.Mock()
with open('sushy/tests/unit/json_samples/message_registry.json') as f:
conn.get.return_value.json.return_value = json.load(f)
msg_reg = message_registry.MessageRegistry(
conn, '/redfish/v1/Registries/Test',
redfish_version='1.0.2')
registries['Test.1.0'] = msg_reg
with open('sushy/tests/unit/json_samples/'
'bios_attribute_registry.json') as f:
conn.get.return_value.json.return_value = json.load(f)
self.bios_reg = attribute_registry.AttributeRegistry(
conn, '/redfish/v1/Registries/BiosRegistryTest',
redfish_version='1.0.2')
registries['BiosRegistry.1.0'] = self.bios_reg
self.sys_bios = bios.Bios(
self.conn, '/redfish/v1/Systems/437XR1138R2/BIOS',
registries=registries,
redfish_version='1.0.2')
def test__parse_attributes(self):
self.sys_bios._parse_attributes(self.bios_json)
self.assertEqual('1.0.2', self.sys_bios.redfish_version)
self.assertEqual('BIOS', self.sys_bios.identity)
self.assertEqual('BIOS Configuration Current Settings',
self.sys_bios.name)
self.assertIsNone(self.sys_bios.description)
self.assertEqual('BiosAttributeRegistryP89.v1_0_0',
self.sys_bios._attribute_registry)
self.assertEqual('', self.sys_bios.attributes['AdminPhone'])
self.assertEqual('Uefi', self.sys_bios.attributes['BootMode'])
self.assertEqual(0, self.sys_bios.attributes['ProcCoreDisable'])
self.assertEqual([res_cons.ApplyTime.ON_RESET,
res_cons.ApplyTime.IN_MAINTENANCE_WINDOW_ON_RESET],
self.sys_bios.supported_apply_times)
self.assertEqual(600, self.sys_bios.maintenance_window
.maintenance_window_duration_in_seconds)
self.assertEqual(parser.parse('2020-09-01T04:30:00-06:00'),
self.sys_bios.maintenance_window
.maintenance_window_start_time)
# testing here if settings subfield parsed by checking ETag,
# other settings fields tested in specific settings test
self.assertEqual('9234ac83b9700123cc32',
self.sys_bios._settings._etag)
self.assertEqual('(404) 555-1212',
self.sys_bios.pending_attributes['AdminPhone'])
self.assertEqual(settings.UPDATE_FAILURE,
self.sys_bios.update_status.status)
def test__parse_attributes_return(self):
attributes = self.sys_bios._parse_attributes(self.bios_json)
# Test that various types are returned correctly
self.assertEqual('BIOS Configuration Current Settings',
attributes.get('name'))
self.assertEqual({'AdminPhone': '',
'BootMode': 'Uefi',
'EmbeddedSata': 'Raid',
'NicBoot1': 'NetworkBoot',
'NicBoot2': 'Disabled',
'PowerProfile': 'MaxPerf',
'ProcCoreDisable': 0,
'ProcHyperthreading': 'Enabled',
'ProcTurboMode': 'Enabled',
'UsbControl': 'UsbEnabled'},
attributes.get('attributes'))
self.assertEqual({'maintenance_window_duration_in_seconds': 600,
'maintenance_window_start_time':
parser.parse('2020-09-01T04:30:00-06:00')},
attributes.get('maintenance_window'))
def test_set_attribute_apply_time(self):
self.conn.get.return_value.json.side_effect = [
self.bios_json,
self.bios_json]
self.sys_bios.set_attribute(
'ProcTurboMode', 'Disabled',
res_cons.ApplyTime.IN_MAINTENANCE_WINDOW_ON_RESET,
datetime.datetime(2020, 9, 1, 4, 30, 0),
600)
self.sys_bios._conn.patch.assert_called_once_with(
'/redfish/v1/Systems/437XR1138R2/BIOS/Settings',
data={'Attributes': {'ProcTurboMode': 'Disabled'},
'@Redfish.SettingsApplyTime': {
'@odata.type': '#Settings.v1_0_0.PreferredApplyTime',
'ApplyTime': 'InMaintenanceWindowOnReset',
'MaintenanceWindowStartTime': '2020-09-01T04:30:00',
'MaintenanceWindowDurationInSeconds': 600}},
etag='9234ac83b9700123cc32')
def test_set_attribute_on_refresh(self):
self.conn.get.return_value.json.side_effect = [
self.bios_settings_json,
self.bios_json,
self.bios_settings_json]
self.conn.get.reset_mock()
# make it to instantiate pending attributes
self.sys_bios.pending_attributes
self.assertTrue(self.conn.get.called)
self.conn.get.reset_mock()
self.sys_bios.pending_attributes
self.assertFalse(self.conn.get.called)
self.sys_bios.set_attribute('ProcTurboMode', 'Disabled')
# make it to refresh pending attributes on next retrieval
self.sys_bios.pending_attributes
self.assertTrue(self.conn.get.called)
def test_set_attributes(self):
self.conn.get.return_value.json.side_effect = [
self.bios_json]
self.sys_bios.set_attributes(
{'ProcTurboMode': 'Disabled', 'UsbControl': 'UsbDisabled'},
res_cons.ApplyTime.AT_MAINTENANCE_WINDOW_START,
datetime.datetime(2020, 9, 1, 4, 30, 0),
600)
self.sys_bios._conn.patch.assert_called_once_with(
'/redfish/v1/Systems/437XR1138R2/BIOS/Settings',
data={'Attributes': {'ProcTurboMode': 'Disabled',
'UsbControl': 'UsbDisabled'},
'@Redfish.SettingsApplyTime': {
'@odata.type': '#Settings.v1_0_0.PreferredApplyTime',
'ApplyTime': 'AtMaintenanceWindowStart',
'MaintenanceWindowStartTime': '2020-09-01T04:30:00',
'MaintenanceWindowDurationInSeconds': 600}},
etag='9234ac83b9700123cc32')
def test_set_attributes_on_refresh(self):
self.conn.get.return_value.json.side_effect = [
self.bios_settings_json,
self.bios_json,
self.bios_settings_json]
self.conn.get.reset_mock()
# make it to instantiate pending attributes
self.sys_bios.pending_attributes
self.assertTrue(self.conn.get.called)
self.conn.get.reset_mock()
self.sys_bios.pending_attributes
self.assertFalse(self.conn.get.called)
self.sys_bios.set_attributes({'ProcTurboMode': 'Disabled',
'UsbControl': 'UsbDisabled'})
# make it to refresh pending attributes on next retrieval
self.sys_bios.pending_attributes
self.assertTrue(self.conn.get.called)
def test_apply_time_settings(self):
self.conn.get.reset_mock()
apply_time_settings = self.sys_bios.apply_time_settings
self.assertIsNotNone(apply_time_settings)
self.assertEqual('OnReset', apply_time_settings.apply_time)
self.assertEqual(['OnReset', 'Immediate', 'AtMaintenanceWindowStart',
'InMaintenanceWindowOnReset'],
apply_time_settings.apply_time_allowable_values)
self.assertEqual(parser.parse('2017-05-03T23:12:37-05:00'),
apply_time_settings.maintenance_window_start_time)
self.assertEqual(600, apply_time_settings.
maintenance_window_duration_in_seconds)
def test__get_reset_bios_action_element(self):
value = self.sys_bios._get_reset_bios_action_element()
self.assertEqual('/redfish/v1/Systems/437XR1138R2/BIOS/Actions/'
'Bios.ResetBios',
value.target_uri)
def test_reset_bios_missing_action(self):
self.sys_bios._actions.reset_bios = None
self.assertRaisesRegex(
exceptions.MissingActionError, '#Bios.ResetBios',
self.sys_bios.reset_bios)
def test__parse_attributes_missing_reset_bios_target(self):
self.sys_bios.json['Actions']['#Bios.ResetBios'].pop(
'target')
self.assertRaisesRegex(
exceptions.MissingAttributeError,
'attribute Actions/#Bios.ResetBios/target',
self.sys_bios._parse_attributes, self.bios_json)
def test_reset_bios(self):
self.sys_bios.reset_bios()
self.sys_bios._conn.post.assert_called_once_with(
'/redfish/v1/Systems/437XR1138R2/BIOS/Actions/Bios.ResetBios')
def test_reset_bios_handle_http_error_415(self):
target_uri = (
'/redfish/v1/Systems/437XR1138R2/BIOS/Actions/Bios.ResetBios')
self.conn.post.side_effect = [exceptions.HTTPError(
method='POST', url=target_uri, response=mock.MagicMock(
status_code=http_client.UNSUPPORTED_MEDIA_TYPE)), '200']
post_calls = [
mock.call(target_uri), mock.call(target_uri, data={})]
self.sys_bios.reset_bios()
self.sys_bios._conn.post.assert_has_calls(post_calls)
def test_reset_bios_handle_http_error_400(self):
target_uri = (
'/redfish/v1/Systems/437XR1138R2/BIOS/Actions/Bios.ResetBios')
self.conn.post.side_effect = [exceptions.HTTPError(
method='POST', url=target_uri, response=mock.MagicMock(
status_code=http_client.BAD_REQUEST)), '200']
post_calls = [
mock.call(target_uri), mock.call(target_uri, data={})]
self.sys_bios.reset_bios()
self.sys_bios._conn.post.assert_has_calls(post_calls)
def test_reset_bios_handle_http_error_405(self):
target_uri = (
'/redfish/v1/Systems/437XR1138R2/BIOS/Actions/Bios.ResetBios')
self.conn.post.side_effect = exceptions.HTTPError(
method='POST', url=target_uri, response=mock.MagicMock(
status_code=http_client.METHOD_NOT_ALLOWED))
self.assertRaises(
exceptions.HTTPError,
self.sys_bios.reset_bios)
self.sys_bios._conn.post.assert_called_once_with(target_uri)
def test__get_change_password_element(self):
value = self.sys_bios._get_change_password_element()
self.assertEqual("/redfish/v1/Systems/437XR1138R2/BIOS/Actions/"
"Bios.ChangePassword",
value.target_uri)
def test_change_password_missing_action(self):
self.sys_bios._actions.change_password = None
self.assertRaisesRegex(
exceptions.MissingActionError, '#Bios.ChangePassword',
self.sys_bios.change_password, 'newpassword',
'oldpassword',
'adminpassword')
def test__parse_attributes_missing_change_password_target(self):
self.sys_bios.json['Actions']['#Bios.ChangePassword'].pop(
'target')
self.assertRaisesRegex(
exceptions.MissingAttributeError,
'attribute Actions/#Bios.ChangePassword/target',
self.sys_bios._parse_attributes, self.bios_json)
def test_change_password(self):
self.sys_bios.change_password('newpassword',
'oldpassword',
'adminpassword')
self.sys_bios._conn.post.assert_called_once_with(
'/redfish/v1/Systems/437XR1138R2/BIOS/Actions/Bios.ChangePassword',
data={'OldPassword': 'oldpassword',
'NewPassword': 'newpassword',
'PasswordName': 'adminpassword'})
def test_get_attribute_registry(self):
registry = self.sys_bios.get_attribute_registry()
self.assertEqual(registry.name, 'BIOS Attribute Registry')
self.assertEqual(registry.description, 'This is a test of BIOS '
'Attribute Registry')
self.assertEqual(registry.registry_entries.attributes[0].name,
'SystemModelName')
self.assertEqual(registry.registry_entries.attributes[0].display_name,
'System Model Name')
self.assertEqual(registry.registry_entries.attributes[0].immutable,
True)
self.assertEqual(registry.registry_entries.attributes[0].read_only,
True)
self.assertEqual(registry.registry_entries.attributes[0].
attribute_type, 'String')
self.assertEqual(registry.registry_entries.attributes[1].name,
'ProcVirtualization')
self.assertEqual(registry.registry_entries.attributes[1].display_name,
'Virtualization Technology')
self.assertEqual(registry.registry_entries.attributes[1].immutable,
False)
self.assertEqual(registry.registry_entries.attributes[1].read_only,
False)
self.assertEqual(registry.registry_entries.attributes[1].
reset_required, True)
self.assertEqual(registry.registry_entries.attributes[1].
attribute_type, 'Enumeration')
self.assertEqual(registry.registry_entries.attributes[1].
allowable_values,
[{'ValueDisplayName': 'Enabled',
'ValueName': 'Enabled'},
{'ValueDisplayName': 'Disabled',
'ValueName': 'Disabled'}])
def test_get_attribute_registry_by_key(self):
# This is seen on some SuperMicro hardware
self.sys_bios._registries[self.bios_reg.identity] = self.bios_reg
self.bios_reg.identity = 'I.dont.match'
registry = self.sys_bios.get_attribute_registry()
self.assertIsNotNone(registry)
self.assertEqual(registry.name, 'BIOS Attribute Registry')
def test_get_attribute_registry_no_lang(self):
registry = self.sys_bios.get_attribute_registry(language='zh')
self.assertIsNone(registry)
def test_get_attribute_registry_not_found(self):
self.sys_bios._attribute_registry = "Unknown"
registry = self.sys_bios.get_attribute_registry()
self.assertIsNone(registry)
class BiosZTTestCase(base.TestCase):
def setUp(self):
super(BiosZTTestCase, self).setUp()
self.conn = mock.Mock()
with open('sushy/tests/unit/json_samples/bios_zt.json') as f:
self.bios_json = json.load(f)
# NOTE(iurygregory): ZT Hardware doesn't have Settings for Bios.
self.conn.get.return_value.json.side_effect = [self.bios_json]
registries = {}
conn = mock.Mock()
# Note(iurygregory): reuse message registry for now.
with open('sushy/tests/unit/json_samples/message_registry.json') as f:
conn.get.return_value.json.return_value = json.load(f)
msg_reg = message_registry.MessageRegistry(
conn, '/redfish/v1/Registries/Test',
redfish_version='1.0.2')
registries['Test.1.0'] = msg_reg
with open('sushy/tests/unit/json_samples/'
'bios_attribute_registry_zthardware.json') as f:
conn.get.return_value.json.return_value = json.load(f)
self.bios_reg = attribute_registry.AttributeRegistry(
conn,
'/redfish/v1/Registries/BiosAttributeRegistryProt0.208.208.0',
redfish_version='1.3.1')
registries['BiosAttributeRegistryProt0.208.208.0'] = self.bios_reg
self.sys_bios = bios.Bios(
self.conn, '/redfish/v1/Systems/Self/Bios',
registries=registries,
redfish_version='1.0.2')
def test__parse_attributes(self):
self.sys_bios._parse_attributes(self.bios_json)
self.assertEqual('1.0.2', self.sys_bios.redfish_version)
self.assertEqual('Bios', self.sys_bios.identity)
self.assertEqual('Current BIOS Settings',
self.sys_bios.name)
self.assertEqual(self.sys_bios.description,
'Current BIOS Settings')
self.assertEqual('BiosAttributeRegistryProt0.208.208.0',
self.sys_bios._attribute_registry)
def test_get_attribute_registry_no_lang(self):
registry = self.sys_bios.get_attribute_registry(language='zh')
self.assertIsNone(registry)
def test_get_attribute_registry(self):
registry = self.sys_bios.get_attribute_registry(language="en")
registry2 = self.sys_bios.get_attribute_registry(language="en-US")
self.assertEqual(registry.name, 'Prot0 BIOS Attribute Registry')
self.assertEqual(registry.description, 'This registry defines a '
'representation of BIOS Attribute instances')
self.assertEqual(registry.language, 'en-US')
self.assertEqual(registry.registry_entries.attributes[0].name,
'TCG003')
self.assertEqual(registry.registry_entries.attributes[0].display_name,
'TPM SUPPORT')
self.assertEqual(registry.registry_entries.attributes[0].read_only,
False)
self.assertEqual(registry.registry_entries.attributes[0].
attribute_type, 'Enumeration')
self.assertEqual(registry.name, registry2.name)
self.assertEqual(registry.description, registry2.description)
self.assertEqual(registry.language, registry2.language)
self.assertEqual(registry.registry_entries.attributes[0].name,
registry2.registry_entries.attributes[0].name)
self.assertEqual(registry.registry_entries.attributes[0].display_name,
registry2.registry_entries.attributes[0].display_name)
self.assertEqual(registry.registry_entries.attributes[0].read_only,
registry2.registry_entries.attributes[0].read_only)
self.assertEqual(registry.registry_entries.attributes[0].
attribute_type,
registry2.registry_entries.attributes[0].
attribute_type)