55
66import re , copy
77from enum import Enum
8- from collections import Counter
8+ from collections import Counter , OrderedDict
99
1010import logging
1111from redfish_interop_validator .redfish import getNamespaceUnversioned , getType , getNamespace
12- from redfish_interop_validator .traverseInterop import callResourceURI
12+ import redfish_interop_validator .traverseInterop as traverseInterop
1313my_logger = logging .getLogger ()
1414my_logger .setLevel (logging .DEBUG )
1515
16- config = {'WarnRecommended' : False , 'WriteCheck' : False }
16+ config = {'WarnRecommended' : traverseInterop .config .get ('warnrecommended' ),
17+ 'WriteCheck' : traverseInterop .config .get ('writecheck' )}
1718
1819class sEnum (Enum ):
1920 FAIL = 'FAIL'
2021 NOPASS = 'NO PASS'
2122 PASS = 'PASS'
2223 WARN = 'WARN'
2324 OK = 'OK'
25+ NA = 'N/A'
2426
2527REDFISH_ABSENT = 'n/a'
2628
@@ -180,12 +182,31 @@ def findPropItemforString(propObj, itemname):
180182 Finds an appropriate object for an item
181183 """
182184 for prop in propObj .getResourceProperties ():
183- rf_payloadName = prop .name .split (':' )[- 1 ]
185+ if prop .find (':' ) != - 1 :
186+ rf_payloadName = prop .name .split (':' )[- 1 ]
187+ else :
188+ rf_payloadName = prop
184189 if itemname == rf_payloadName :
185190 return prop
186191 return None
187192
188193
194+ def getPropValue (propObj , itemname ):
195+ """
196+ Finds an appropriate object for an item
197+ """
198+ properties = propObj .getResourceProperties ()
199+ for prop in properties :
200+ if prop .find (':' ) != - 1 :
201+ rf_payloadName = prop .name .split (':' )[- 1 ]
202+ if itemname == rf_payloadName :
203+ return prop .name .split (':' )[1 ]
204+ elif itemname == prop :
205+ rf_payloadName = prop
206+ return properties [prop ]
207+ return None
208+
209+
189210def validateWriteRequirement (propObj , profile_entry , itemname ):
190211 """
191212 Validates if a property is WriteRequirement or not
@@ -194,20 +215,48 @@ def validateWriteRequirement(propObj, profile_entry, itemname):
194215 permission = 'Read'
195216 expected = "OData.Permission/ReadWrite" if profile_entry else "Any"
196217 if not config ['WriteCheck' ]:
197- paramPass = True
218+ paramPass = sEnum . NA
198219 return msgInterop ('WriteRequirement' , profile_entry , expected , permission , paramPass ),\
199220 paramPass
200221 if profile_entry :
201222 targetProp = findPropItemforString (propObj , itemname .replace ('#' , '' ))
202- propAttr = None
223+ propVal = None
224+ newAttr = None
225+ changedAttr = None
203226 if targetProp is not None :
204- propAttr = targetProp .propDict .get ('OData.Permissions' )
205- if propAttr is not None :
206- permission = propAttr .get ('EnumMember' , 'Read' )
227+ propVal = getPropValue (propObj , itemname .replace ('#' , '' ))
228+ if propVal is not None :
229+ match propVal :
230+ case str ():
231+ newAttr = propVal + 'a'
232+ case int ():
233+ newAttr = propVal + 1
234+ case float ():
235+ newAttr = propVal + 1.1
236+ case dict ():
237+ newAttr ['Test' ].append ('test1' )
238+ case OrderedDict ():
239+ newAttr ['Test' ].append ('test2' )
240+ # NOTE: Here can be write new attribute to server
241+ # (example in pseudo code)
242+ # if newAttr is not None:
243+ # curl update json message using 'login & password' / 'X-AuthTocken'
244+ # changedAttr == get value of updated Prop from server
245+ # permission = 'Write'
207246 paramPass = permission \
208247 == "OData.Permission/ReadWrite"
248+
209249 else :
210250 paramPass = False
251+
252+ # NOTE: Here can be check if newAttr is the same as the Attr retrived from the server
253+ # (example in pseudo code)
254+ # if changedAttr is not None and changedAttr == newAttr:
255+ # paramPass = True
256+ #
257+ # else:
258+ # paramPass = False
259+
211260 else :
212261 paramPass = True
213262
@@ -249,7 +298,7 @@ def checkComparison(val, compareType, target):
249298 paramPass = len (alltarget ) == len (target )
250299 if compareType == "LinkToResource" :
251300 vallink = val .get ('@odata.id' )
252- success , rf_payload , code , elapsed = callResourceURI (vallink )
301+ success , rf_payload , code , elapsed = traverseInterop . callResourceURI (vallink )
253302 if success :
254303 ourType = rf_payload .get ('@odata.type' )
255304 if ourType is not None :
@@ -595,7 +644,7 @@ def validateActionRequirement(profile_entry, rf_payload_tuple, actionname):
595644 return msgs , counts
596645 if "@Redfish.ActionInfo" in rf_payload_item :
597646 vallink = rf_payload_item ['@Redfish.ActionInfo' ]
598- success , rf_payload_action , code , elapsed = callResourceURI (vallink )
647+ success , rf_payload_action , code , elapsed = traverseInterop . callResourceURI (vallink )
599648 if not success :
600649 rf_payload_action = None
601650
0 commit comments