Skip to content

Commit

Permalink
Added new usecases, test profiles, double reporting, test fix
Browse files Browse the repository at this point in the history
Logic for usecases and test profiles provided for consistent testing.

Removed line that doubled all counts at the end of run.

Modify requirement unittest to pass.

Signed-off-by: Tomas <[email protected]>
  • Loading branch information
tomasg2012 committed Nov 12, 2024
1 parent 396543b commit fd3f8b6
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 8 deletions.
35 changes: 33 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,27 @@ 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:
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": {}
}
}
]
}
}
}
23 changes: 23 additions & 0 deletions test-profiles/UseCaseType_PortProtocol.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"SchemaDefinition": "RedfishInteroperabilityProfile.v1_5_0",
"ProfileName": "UseCaseType_PortProtocol",
"ProfileVersion": "1.0.0",
"Purpose": "Test for UseCaseType 'PortProtocol'. Should pass one test for each PortMetrics in public-acd.",
"Resources": {
"Sensor": {
"UseCases": [
{
"UseCaseTitle": "Port Metrics",
"UseCaseType": "PortProtocol",
"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 fd3f8b6

Please sign in to comment.