Skip to content

Commit acdd023

Browse files
committed
Fixed verification for causal pathways
1 parent 5f44e91 commit acdd023

File tree

4 files changed

+59
-33
lines changed

4 files changed

+59
-33
lines changed

LDT.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
behaviorGroup.add_argument("--allCPs", action="store_true", help="SetTrue: Test all causal-pathway-specific input message files.")
4141
#
4242
# Output V&V arguments
43-
validationGroup = ap.add_mutually_exclusive_group() # Mutually exclude V&V operations
44-
validationGroup.add_argument("--vignVal", action="store_true", help="SetTrue: Compare output message keys against vignette data library.")
45-
validationGroup.add_argument("--cpVal", action="store_true", help="SetTrue: Compare input and output causal pathway for match.")
43+
verificationGroup = ap.add_mutually_exclusive_group() # Mutually exclude V&V operations
44+
verificationGroup.add_argument("--vignVerify", action="store_true", help="SetTrue: Compare output message keys against vignette data library.")
45+
verificationGroup.add_argument("--cpVerify", action="store_true", help="SetTrue: Compare input and output causal pathway for match.")
4646
#
4747
# CSV payload config arguments
4848
ap.add_argument("--RI", type=int, default=0, help="First row of data to read from CSV.")
@@ -61,7 +61,7 @@
6161
audience = os.environ.get("TARGET_AUDIENCE")
6262
perfPath = args.csv if args.csv != None else os.environ.get("CSVPATH") # Path to performance CSV data
6363
servAccPath = args.servAcc if args.servAcc != None else os.environ.get("SAPATH") # Path to service account file
64-
chkCP = args.cpVal if args.CP != None or args.allCPs else None # Only allow CP check if testing CPs
64+
chkCP = args.cpVerify if args.CP != None or args.allCPs else None # Only allow CP check if testing CPs
6565

6666

6767
#### Logging module configuration ######################################################
@@ -73,8 +73,10 @@
7373
format=printLevel+' %(message)s')
7474
log = logging.getLogger("LeakdownTester") # Start and name logger instance
7575

76+
7677
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
7778

79+
7880
##### Startup Functions ###############################################################
7981
### Handle API endpoint, script behavior, and number of requests to send.
8082
### V 1.4.3+ has integrated readback as configurations are set.
@@ -174,6 +176,9 @@ def calc_total_reqs(behavior):
174176
return totalRequests
175177

176178

179+
180+
181+
177182
#### API Response Handling #########################################################
178183
### These functions print out response output, handle making logs of response output,
179184
### and validate responses against known-good data (vignette specifications)
@@ -199,8 +204,8 @@ def text_back(postReturn):
199204

200205

201206
## Check output message for known-good metadata pairs...
202-
def response_vign_validate(apiReturn, staffID):
203-
log.debug("\tRunning 'response_vign_validate'...")
207+
def response_vign_verify(apiReturn, staffID):
208+
log.debug("\tRunning 'response_vign_verify..")
204209
validKeys = vignAccPairs.get(staffID)
205210
chosenKeys = {
206211
"acceptable_by": apiReturn["selected_candidate"].get("acceptable_by").lower(),
@@ -212,12 +217,12 @@ def response_vign_validate(apiReturn, staffID):
212217

213218
# Check keys and print results
214219
if chosenKeys in validKeys:
215-
log.info(f"VIGNETTE VALIDATION:\tPASS\nValid pairs:")
220+
log.info(f"VIGNETTE VERIFICATION:\tPASS\nValid pairs:")
216221
for formattedValidKey in formattedValidKeys:
217222
log.info(f"\t{formattedValidKey}")
218223
log.info(f"API returned pair:\n\t\t{chosenKeys['acceptable_by'].title()}\t\t{chosenKeys['measure']}\n")
219224
else:
220-
log.info(f"VIGNETTE VALIDATION:\tFAIL\nExpected valid pairs:")
225+
log.info(f"VIGNETTE VERIFICATION:\tFAIL\nExpected valid pairs:")
221226
for formattedValidKey in formattedValidKeys:
222227
log.info(f"\t{formattedValidKey}")
223228
log.info(f"API returned pair:\n\t\t{chosenKeys['acceptable_by'].title()}\t\t{chosenKeys['measure']}\n")
@@ -226,23 +231,28 @@ def response_vign_validate(apiReturn, staffID):
226231

227232

228233
## Check output message against requested Causal Pathway...
229-
def response_CP_validate(apiReturn, causalPathway):
230-
log.debug("\tRunning 'response_CP_validate'...")
234+
def response_CP_verify(apiReturn, causalPathway):
235+
log.debug("\tRunning 'response_CP_verify'...")
231236
try:
232-
assert causalPathway != None, "Causal Pathway passed to validation function is not a string"
237+
assert causalPathway is not None and isinstance(causalPathway, str), "Causal Pathway passed to verification function is not a valid string"
238+
assert apiReturn["selected_candidate"].get("acceptable_by") is not None, "No 'Acceptable By' keys returned by API"
233239
except AssertionError as e:
234240
log.critical("Assertion error: " + str(e))
235241
return
236242

237-
causalPathway = causalPathway.replace("_"," ") # replace underscores of user input with spaces
238-
selectedCP = apiReturn["selected_candidate"].get("acceptable_by").lower()
243+
causalPathway = causalPathway.replace("_", " ") # replace underscores of user input with spaces
244+
selectedCandidate = apiReturn["selected_candidate"]
245+
selectedCPList = selectedCandidate.get("acceptable_by")
239246

240-
# Check for match between selected causal pathway and specified causal pathway
241-
if causalPathway == selectedCP:
242-
log.info(f"CAUSAL PATHWAY VALIDATION:\tPASS\nSpecified Pathway:\t{causalPathway}\nAccepted Pathway:\t{selectedCP}\n")
243-
else:
244-
log.info(f"CAUSAL PATHWAY VALIDATION:\tFAIL\nSpecified Pathway:\t{causalPathway}\nAccepted Pathway:\t{selectedCP}\n")
245-
247+
for selectedCP in selectedCPList:
248+
selectedCP = selectedCP.lower()
249+
if causalPathway == selectedCP:
250+
log.info(f"CAUSAL PATHWAY VERIFICATION:\tPASS\n\t\tSpecified Pathway:\t{causalPathway}\n\t\tAccepted Pathway:\t{selectedCP}")
251+
log.info(f"PFP returns acceptable candidates: {selectedCPList}\n")
252+
break
253+
else:
254+
log.info(f"CAUSAL PATHWAY VERIFICATION:\tFAIL\n\t\tSpecified Pathway:\t{causalPathway}\n\t\tAccepted Pathway:\t{selectedCPList}")
255+
log.info(f"No matching causal pathway found for '{causalPathway}'.\n")
246256

247257

248258
## Save PFP API responses for manual review...
@@ -277,11 +287,11 @@ def handle_response(response, requestID):
277287
if args.respond: # Print output if asked
278288
text_back(apiReturn)
279289

280-
if args.vignVal: # Validate vignette measure/causal pathway pair in output if asked
281-
response_vign_validate(apiReturn, staffID)
290+
if args.vignVerify: # Validate vignette measure/causal pathway pair in output if asked
291+
response_vign_verify(apiReturn, staffID)
282292

283293
if chkCP: # Validate causal pathway output if asked
284-
response_CP_validate(apiReturn, args.CP)
294+
response_CP_verify(apiReturn, args.CP)
285295
# not an ideal way to incorporate which causal pathway we want to assert, but workable
286296

287297
if args.saveResponse: # Save output if asked
@@ -293,6 +303,8 @@ def handle_response(response, requestID):
293303

294304

295305

306+
307+
296308
##### JSON Content Functions ###########################################################
297309
### These functions handle where and how to read in JSON content to make valid post
298310
### requests to the API.
@@ -337,6 +349,9 @@ def csv_jsoner(path):
337349
return jsonedData
338350

339351

352+
353+
354+
340355
#### POST Functions ###################################################################
341356
### Any and all functions that send a post request live here. Protected or unprotected,
342357
### from any content source, and against any of the available API endpoints.
@@ -419,7 +434,7 @@ def repo_test(mode, threadIndex, testIndex, requestID):
419434

420435
for requestIndex, inputID in enumerate(hitlist, start=1):
421436
requestID = f"Thread {threadIndex}, Test {testIndex}, Request {requestIndex}" # add request index to ID
422-
args.CP = inputID # Sneaky way to set current causal pathway from hitlist for validation
437+
args.CP = inputID # Sneaky way to set current causal pathway from hitlist for verification
423438
test_inputfile(mode, inputID, requestID)
424439

425440

@@ -478,6 +493,8 @@ def run_requests(behavior, threadIndex, requestID, barrier):
478493

479494

480495

496+
497+
481498
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
482499

483500
########### Main Script Body ################################

LDT_Addendum.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## Version of the Leakdown Tester
2-
ldtVersion = "2.0.0"
2+
ldtVersion = "2.0.1 Beta"
33

44

55
## JSON content 'header' wrapper section for in-situ payload compilation:

changelog.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
# Leakdown Tester Changelog
2+
## Version 2.0.1
3+
*Released TBD*
4+
5+
**Patch:** Fixed V&V functions with new structure of 'acceptable_by' key
6+
- Restored causal pathway verification with `--cpVerify`
7+
- Iterates through acceptable_by pathways and searches for a match
8+
- *Planned*: Verify against candidate message template links to restore specificity verification
9+
-
10+
211
## Version 2.0.0
312
*Released 8/31/2023*
413

@@ -75,7 +84,7 @@ Added function `post_and_respond`
7584
*Released 8/18/23*
7685

7786
Updated handle_response() function
78-
+ Refactored code to check first for 200 status code response, THEN to pull JSON keys for vignette validation
87+
+ Refactored code to check first for 200 status code response, THEN to pull JSON keys for vignette verification
7988
+ Allows for increased description of bad API responses
8089
+ Refactoring into handle_response eliminates 8 lines of code from script
8190

@@ -124,8 +133,8 @@ Added function `post_and_respond`
124133
Worked on GCP testing functionality
125134
+ Assert statements added to ensure requisite info present before POSTing to GCP
126135

127-
Re-worked vignette validation functionality
128-
+ Clarified language returned by LDT to tell user validation is only against expected vignette content pairings, not validating overall message in some way.
136+
Re-worked vignette verification functionality
137+
+ Clarified language returned by LDT to tell user verification is only against expected vignette content pairings, not validating overall message in some way.
129138

130139
Refactored repo_test function
131140
+ Removed repeat code blocks to allow for implementation of single repo test function
@@ -135,18 +144,18 @@ Added function `post_and_respond`
135144

136145
Changed `LDT_Addendum`
137146
+ Changed from checking persona based keys to staff_number based keys
138-
+ Allows for validation of any successful post request
147+
+ Allows for verification of any successful post request
139148

140-
Changed validation procedure to allow any post request to be validated
141-
+ Implemented validation of post request(s) based on using staff_number to compare against keys vs. using personas
149+
Changed verification procedure to allow any post request to be validated
150+
+ Implemented verification of post request(s) based on using staff_number to compare against keys vs. using personas
142151
+ Successfully tested functionality with both CSV and GitHub input messages
143152

144153
## Version 1.4.0
145154
*Released 8/9/23*
146155

147156
Added `LDT_Addendum.py` to Leakdown Tester folder
148157
+ Functions as a store for large text variables that may need to periodically change without impacting `leakTester.py`
149-
+ Contains validation target values
158+
+ Contains verification target values
150159
+ Contains header and footer of input_message JSON content for CSV payload building
151160

152161
Removed function `assemble_payload`

readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ Format for the below argument specifications:
8484
### Output Verification and Validation arguments
8585
Note: V&V options are mutually exclusive, only one kind of operation can be performed during an LDT run.
8686

87-
`--vignVal`
87+
`--vignVerify`
8888
- Default: None
8989
- SetTrue: Compares output message keys 'measure' and 'acceptable_by' against vignette-validated key pair dictionary.
9090

91-
`--cpVal`
91+
`--cpVerify`
9292
- Default: None
9393
- SetTrue: Compares user-input and API-output message keys 'measure' and 'acceptable_by' pairs for a match.
9494

0 commit comments

Comments
 (0)