17
17
18
18
class sEnum (Enum ):
19
19
FAIL = 'FAIL'
20
+ NOPASS = 'NO PASS'
20
21
PASS = 'PASS'
21
22
WARN = 'WARN'
23
+ OK = 'OK'
22
24
23
25
24
26
class msgInterop :
@@ -27,11 +29,74 @@ def __init__(self, name, profile_entry, expected, actual, success):
27
29
self .entry = profile_entry
28
30
self .expected = expected
29
31
self .actual = actual
32
+ self .ignore = False
30
33
if isinstance (success , bool ):
31
34
self .success = sEnum .PASS if success else sEnum .FAIL
32
35
else :
33
36
self .success = success
34
- self .parent = None
37
+ self .parent_results = None
38
+
39
+ def validateComparisonAnyOfAllOf (profile_entry , property_path = "Unspecified" ):
40
+ """
41
+ Gather comparison information after processing all Resources on system
42
+ """
43
+ all_msgs = []
44
+ for key in profile_entry :
45
+ property_profile = profile_entry [key ]
46
+ my_compare = property_profile .get ('Comparison' , 'AnyOf' )
47
+
48
+ if property_profile .get ('Values' ) and my_compare in ['AnyOf' , 'AllOf' ]:
49
+ my_msgs = property_profile .get ('_msgs' , [])
50
+ my_values , expected_values = [m .actual for m in my_msgs ], property_profile ['Values' ]
51
+
52
+ my_logger .info ('Validating {} Comparison for {} : {}' .format (my_compare , property_path , key ))
53
+ my_logger .info (" {}, Expecting {}" .format (my_values , expected_values ))
54
+
55
+ if not len (my_msgs ) and property_profile .get ('ReadRequirement' , 'Mandatory' ) != 'Mandatory' :
56
+ continue
57
+
58
+ msg_name = 'Comparison.{}.{}' .format (property_path , key )
59
+
60
+ top_msg = msgInterop (msg_name , my_compare , expected_values , my_values , False )
61
+ all_msgs .append (top_msg )
62
+
63
+ # NOPASS by default, if the check fails but the value is still in the array
64
+ # OK if passing, FAIL if check fails and value is not in array
65
+ for msg in my_msgs :
66
+ msg .ignore = False
67
+ msg .success = sEnum .NOPASS
68
+ msg .expected = '{} {} ({})' .format (msg .expected , expected_values , "Across All Resources" )
69
+
70
+ if my_compare == 'AnyOf' :
71
+ if any ([x in my_values for x in expected_values ]):
72
+ my_logger .info (' PASS' )
73
+ top_msg .success = sEnum .PASS
74
+ for msg in my_msgs :
75
+ msg .success = sEnum .OK
76
+ if msg .actual in expected_values :
77
+ msg .success = sEnum .PASS
78
+ else :
79
+ my_logger .info (' FAIL' )
80
+ for msg in my_msgs :
81
+ msg .success = sEnum .FAIL
82
+
83
+ if my_compare == 'AllOf' :
84
+ if all ([x in my_values for x in expected_values ]):
85
+ my_logger .info (' PASS' )
86
+ top_msg .success = sEnum .PASS
87
+ for msg in my_msgs :
88
+ msg .success = sEnum .OK
89
+ else :
90
+ my_logger .info (' FAIL' )
91
+ for msg in my_msgs :
92
+ if msg .actual not in expected_values :
93
+ msg .success = sEnum .FAIL
94
+
95
+ if property_profile .get ('PropertyRequirements' ):
96
+ new_msgs = validateComparisonAnyOfAllOf (property_profile .get ('PropertyRequirements' ), '.' .join ([property_path , key ]))
97
+ all_msgs .extend (new_msgs )
98
+
99
+ return all_msgs
35
100
36
101
37
102
def validateRequirement (profile_entry , rf_payload_item = None , conditional = False , parent_object_tuple = None ):
@@ -158,6 +223,9 @@ def checkComparison(val, compareType, target):
158
223
paramPass = False
159
224
if compareType is None :
160
225
my_logger .error ('CompareType not available in payload' )
226
+
227
+ # NOTE: In our current usage, AnyOf and AllOf in this context is only for ConditionalRequirements -> CompareProperty
228
+ # Which checks if a particular property inside of this instance applies
161
229
if compareType == "AnyOf" :
162
230
for item in vallist :
163
231
paramPass = item in target
@@ -374,14 +442,6 @@ def validatePropertyRequirement(propResourceObj, profile_entry, rf_payload_tuple
374
442
my_logger .error ("MinCount failed" )
375
443
msgs .append (msg )
376
444
msg .name = itemname + '.' + msg .name
377
- for k , v in profile_entry .get ('PropertyRequirements' , {}).items ():
378
- # default to AnyOf if Comparison is not present but Values is
379
- comparisonValue = v .get ("Comparison" , "AnyOf" ) if v .get ("Values" ) is not None else None
380
- if comparisonValue in ["AllOf" , "AnyOf" ]:
381
- msg , success = (checkComparison ([val .get (k , 'DNE' ) for val in rf_payload_item ],
382
- comparisonValue , v ["Values" ]))
383
- msgs .append (msg )
384
- msg .name = itemname + '.' + msg .name
385
445
cnt = 0
386
446
for item in rf_payload_item :
387
447
listmsgs , listcounts = validatePropertyRequirement (
@@ -405,6 +465,7 @@ def validatePropertyRequirement(propResourceObj, profile_entry, rf_payload_tuple
405
465
msg .name = itemname + '.' + msg .name
406
466
if not success :
407
467
my_logger .error ("WriteRequirement failed" )
468
+
408
469
if "MinSupportValues" in profile_entry :
409
470
msg , success = validateSupportedValues (
410
471
profile_entry ["MinSupportValues" ],
@@ -413,14 +474,25 @@ def validatePropertyRequirement(propResourceObj, profile_entry, rf_payload_tuple
413
474
msg .name = itemname + '.' + msg .name
414
475
if not success :
415
476
my_logger .error ("MinSupportValues failed" )
416
- if "Comparison" in profile_entry and not chkCondition and \
417
- profile_entry ["Comparison" ] not in ["AnyOf" , "AllOf" ]:
418
- msg , success = checkComparison (rf_payload_item ,
419
- profile_entry ["Comparison" ], profile_entry .get ("Values" ,[]))
477
+
478
+ if "Values" in profile_entry and not chkCondition :
479
+ # Default to AnyOf
480
+ # NOTE: chkCondition seems to skip this if a ConditionalRequirement is met, this may be unnecessary
481
+
482
+ my_compare = profile_entry .get ("Comparison" , "AnyOf" )
483
+ msg , success = checkComparison (rf_payload_item , my_compare , profile_entry .get ("Values" , []))
420
484
msgs .append (msg )
421
485
msg .name = itemname + '.' + msg .name
422
- if not success :
486
+
487
+ # Embed test results into profile, going forward seems to be the quick option outside of making a proper test object
488
+ if my_compare in ['AnyOf' , 'AllOf' ]:
489
+ msg .ignore = True
490
+ if not profile_entry .get ('_msgs' ):
491
+ profile_entry ['_msgs' ] = []
492
+ profile_entry ['_msgs' ].append (msg )
493
+ elif not success :
423
494
my_logger .error ("Comparison failed" )
495
+
424
496
if "PropertyRequirements" in profile_entry :
425
497
innerDict = profile_entry ["PropertyRequirements" ]
426
498
if isinstance (rf_payload_item , dict ):
@@ -593,7 +665,7 @@ def validateInteropResource(propResourceObj, interop_profile, rf_payload):
593
665
my_logger .info ('Skipping UpdateResource' )
594
666
pass
595
667
596
- for item in msgs :
668
+ for item in [ item for item in msgs if not item . ignore ] :
597
669
if item .success == sEnum .WARN :
598
670
counts ['warn' ] += 1
599
671
elif item .success == sEnum .PASS :
0 commit comments