Skip to content

Commit

Permalink
Merge pull request #216 from DMTF/additional-usecase-types
Browse files Browse the repository at this point in the history
Added new usecases, test profiles, double reporting, test fix
  • Loading branch information
mraineri authored Nov 15, 2024
2 parents 396543b + a5c9ea6 commit f2950e1
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 8 deletions.
36 changes: 34 additions & 2 deletions redfish_interop_validator/interop.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,15 @@ def checkInteropURI(r_obj, profile_entry):
my_id, my_uri = r_obj.jsondata.get('Id'), r_obj.uri
return compareRedfishURI(profile_entry, my_uri)

# Expected Type, Key
entry_type_table = {
'ChassisType': ("Chassis", "ChassisType"),
'DriveProtocol': ("Drive", "Protocol"),
'MemoryType': ("Memory", "MemoryType"),
'PortProtocol': ("Port", "PortProtocol"),
'ProcessorType': ("Processor", "ProcessorType"),
}


def validateInteropResource(propResourceObj, interop_profile, rf_payload):
"""
Expand All @@ -783,11 +792,12 @@ def validateInteropResource(propResourceObj, interop_profile, rf_payload):
for use_case in interop_profile['UseCases']:
entry_title = use_case.get("UseCaseTitle", "NoName").replace(' ', '_')
entry_type = use_case.get("UseCaseType", "Normal")
my_parent = propResourceObj.parent
my_logger.debug('UseCase {} {}'.format(entry_title, entry_type))

# Check if we have a valid UseCase
if 'URIs' not in use_case and 'UseCaseKeyProperty' not in use_case and entry_type != 'AbsentResource':
my_logger.error('UseCase does not have URIs or UseCaseKeyProperty...')
if ('URIs' not in use_case) and ('UseCaseKeyProperty' not in use_case) and (entry_type not in ['AbsentResource'] + list(entry_type_table.keys())):
my_logger.error('UseCase does not have URIs or valid UseCase...')

if entry_type == 'AbsentResource':
my_status = rf_payload.get('Status')
Expand All @@ -797,6 +807,28 @@ def validateInteropResource(propResourceObj, interop_profile, rf_payload):
use_case_applies = False
if 'URIs' in use_case:
use_case_applies = use_case_applies and checkInteropURI(propResourceObj, use_case['URIs'])

elif entry_type in entry_type_table:
target_type_found = False
target_type, entry_key = entry_type_table[entry_type]
entry_comparison, entry_values = use_case['UseCaseComparison'], use_case['UseCaseKeyValues']

# Iterate until we find our target type, if not found then use case cannot apply
while my_parent is not None and not target_type_found:
parent_type = getType(my_parent.jsondata.get('@odata.type', 'NoType'))
target_type_found = parent_type == target_type
if not target_type_found:
my_parent = my_parent.parent

if target_type_found:
target_payload = my_parent.jsondata
target_value = target_payload.get(entry_key)

_, use_case_applies = checkComparison(target_payload.get(entry_key, REDFISH_ABSENT), entry_comparison, entry_values)
else:
my_logger.verbose1('Type {} was not found in parent typechain'.format(target_type))
use_case_applies = False


elif 'UseCaseKeyProperty' in use_case:
entry_key, entry_comparison, entry_values = use_case['UseCaseKeyProperty'], use_case['UseCaseComparison'], use_case['UseCaseKeyValues']
Expand Down
5 changes: 2 additions & 3 deletions redfish_interop_validator/validateResource.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def validateSingleURI(URI, profile, uriName='', expectedType=None, expectedSchem
profile_resources = profile_resources.get(SchemaType)
try:
propMessages, propCounts = interop.validateInteropResource(resource_obj, profile_resources, jsondata)
messages = messages.extend(propMessages)
messages.extend(propMessages)
counts.update(propCounts)
my_logger.info('{} of {} tests passed.'.format(counts['pass'] + counts['warn'], counts['totaltests']))
except Exception:
Expand Down Expand Up @@ -312,8 +312,7 @@ def validateURITree(URI, profile, uriName, expectedType=None, expectedSchema=Non
allLinks.add(link.rstrip('/'))

results.update(linkResults)
counts.update(linkCounts)


if not linkSuccess:
continue

Expand Down
20 changes: 20 additions & 0 deletions test-profiles/ChassisType_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "ChassisType5",
"ProfileVersion": "1.0.0",
"Purpose": "Ensures at least one chassis is an 'Enclosure'. This test should pass.",
"Resources": {
"Thermal": {
"PropertyRequirements": {
"Temperatures": {
"PropertyRequirements": {
"PhysicalContext": {
"Comparison": "AllOf",
"Values": [ "Intake", "CPU" ]
}
}
}
}
}
}
}
18 changes: 18 additions & 0 deletions test-profiles/ChassisType_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "ChassisType1",
"ProfileVersion": "1.0.0",
"Purpose": "Ensures at least one chassis is an 'Enclosure'. This test should pass (MultiBladeEncl is an Enclosure).",
"Resources": {
"Chassis": {
"PropertyRequirements": {
"ChassisType": {
"Comparison": "AnyOf",
"Values": [
"Enclosure"
]
}
}
}
}
}
19 changes: 19 additions & 0 deletions test-profiles/ChassisType_3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "ChassisType2",
"ProfileVersion": "1.0.0",
"Purpose": "Ensures at least one chassis is an 'Enclosure' or a 'Rack'. This test should pass (MultiBladeEncl is an Enclosure).",
"Resources": {
"Chassis": {
"PropertyRequirements": {
"ChassisType": {
"Comparison": "AnyOf",
"Values": [
"Enclosure",
"Rack"
]
}
}
}
}
}
19 changes: 19 additions & 0 deletions test-profiles/ChassisType_4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "ChassisType3",
"ProfileVersion": "1.0.0",
"Purpose": "Ensures at least one chassis is an 'Enclosure' and a 'Rack'. This test should fail (there are no 'Rack' chassis).",
"Resources": {
"Chassis": {
"PropertyRequirements": {
"ChassisType": {
"Comparison": "AllOf",
"Values": [
"Enclosure",
"Rack"
]
}
}
}
}
}
19 changes: 19 additions & 0 deletions test-profiles/ChassisType_5.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "ChassisType4",
"ProfileVersion": "1.0.0",
"Purpose": "Ensures at least one chassis is an 'Enclosure' and a 'Blade'. This test should pass.",
"Resources": {
"Chassis": {
"PropertyRequirements": {
"ChassisType": {
"Comparison": "AllOf",
"Values": [
"Enclosure",
"Blade"
]
}
}
}
}
}
18 changes: 18 additions & 0 deletions test-profiles/ChassisType_6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "ChassisType5",
"ProfileVersion": "1.0.0",
"Purpose": "Ensures at least one chassis is an 'Enclosure'. This test should pass.",
"Resources": {
"Chassis": {
"PropertyRequirements": {
"ChassisType": {
"Comparison": "AllOf",
"Values": [
"Enclosure"
]
}
}
}
}
}
23 changes: 23 additions & 0 deletions test-profiles/UseCaseType_ChassisType.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "UseCaseType_ChassisType",
"ProfileVersion": "1.0.0",
"Purpose": "Test for UseCaseType 'ChassisType'. Should pass one test for every Sensor in public-rackmount1.",
"Resources": {
"Sensor": {
"UseCases": [
{
"UseCaseTitle": "Chassis Sensor",
"UseCaseType": "ChassisType",
"UseCaseComparison": "Equal",
"UseCaseKeyValues": [
"RackMount"
],
"PropertyRequirements": {
"PhysicalContext": {}
}
}
]
}
}
}
30 changes: 30 additions & 0 deletions test-profiles/UseCaseType_ProcessorType.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "UseCaseType_PortProtocol",
"ProfileVersion": "1.0.0",
"Purpose": "Test for UseCaseType 'ProcessorType'. Should pass one test for each SubProcessor in public-tower.",
"Resources": {
"Processor": {
"UseCases": [
{
"UseCaseTitle": "Sub Processor",
"UseCaseType": "ProcessorType",
"UseCaseComparison": "Equal",
"UseCaseKeyValues": [
"CPU"
],
"PropertyRequirements": {
"ProcessorType": {
"ReadRequirement": "Mandatory",
"Comparison": "AnyOf",
"Values": [
"Thread",
"Core"
]
}
}
}
]
}
}
}
7 changes: 4 additions & 3 deletions tests/interoptests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ def test_no_test(self):

def test_requirement(self):
entries = ['Mandatory', 'Recommended', 'Mandatory', 'Recommended']
vals = ['Ok', riv.REDFISH_ABSENT, riv.REDFISH_ABSENT, 'Ok']
boolist = [True, True, False, True]
vals = [{}, riv.REDFISH_ABSENT, riv.REDFISH_ABSENT, {}]
boolist = [True, riv.testResultEnum.NA, False, True]
for e, v, b in zip(entries, vals, boolist):
self.assertTrue(riv.validateRequirement(e, v)[1] == b, str(e + ' ' + v))
_msg, result_value = riv.validateRequirement(e, v)
self.assertTrue(result_value == b, str(e + ' ' + str(v)))

def test_mincount(self):
x = 'x'
Expand Down

0 comments on commit f2950e1

Please sign in to comment.