11"""Parse verification outputs."""
22
33import re
4+ import glob
5+ import os
46
57def verification_parser (filename , threshold ):
8+
9+ # function should be given a threshold value for each sub test
10+ (directory , _ ) = os .path .split (filename )
11+ # how many additional tests are run with tweaks to this configuration
12+ num_exps = len (glob .glob (directory + '/input.*' ))+ 1
13+
14+ # check that the correct number of values for `threshold` have been given
15+ if len (threshold ) != num_exps :
16+ # some if statements to deal with grammar
17+ if len (threshold )== 1 :
18+ error_message = '{0} value given for threshold, ' .format (len (threshold ))
19+ else :
20+ error_message = '{0} values given for threshold, ' .format (len (threshold ))
21+
22+ if num_exps == 1 :
23+ error_message = error_message + 'but {0} subtest found.' .format (num_exps )
24+ else :
25+ error_message = error_message + 'but {0} subtests found.' .format (num_exps )
26+
27+ raise ValueError (error_message )
28+
29+ # open the testreport output to assess pass/fail
630 with open (filename ) as f :
731 lines = f .readlines ()
832
@@ -16,23 +40,38 @@ def verification_parser(filename, threshold):
1640 # but set to false to catch next matches.
1741 first_match = False
1842 else :
19- test_results = lines [i + 2 ]
20-
21- # split test_results into a list with values for each number.
22- # this uses spaces and the < > characters to separate the numbers.
23- test_results = re .split ('[ ><]' ,test_results )
24- # ignore the Genmake, depend, make, and run checks, as well as
25- # the "pass" or "fail" and test name at the end of the line
26- test_results = test_results [4 :- 3 ]
27- # convert to floats
28- dp_similarity = []
29- for i , x in enumerate (test_results ):
30- try :
31- dp_similarity .append (float (x ))
32- except ValueError :
33- pass
34-
35- assert all (elements > threshold for elements in dp_similarity )
43+ # save the line number where the output is found
44+ output_line = i
45+ break
46+
47+ # loop through each of the subexperiments:
48+ for j in xrange (len (threshold )):
49+ test_results = lines [output_line + 2 + j ]
50+
51+ # split test_results into a list with values for each number.
52+ # this uses spaces and the < > characters to separate the numbers.
53+ test_results = re .split ('[ ><]' ,test_results )
54+ # ignore the Genmake, depend, make, and run checks, as well as
55+ # the "pass" or "fail" and test name at the end of the line
56+ test_results = test_results [4 :- 3 ]
57+ # convert to floats
58+ dp_similarity = []
59+ for i , x in enumerate (test_results ):
60+ try :
61+ dp_similarity .append (float (x ))
62+ except ValueError :
63+ pass
64+
65+
66+ if len (dp_similarity ) >= 17 :
67+ # this means that the test wasn't an offline advection test.
68+ # Remove the means of u and v since they are constrained
69+ # to ~0 by domain geometry and can cause the test to fail
70+ # when it shouldn't.
71+ del dp_similarity [15 ]
72+ del dp_similarity [11 ]
73+
74+ assert all (elements >= threshold [j ] for elements in dp_similarity )
3675
3776if __name__ == '__main__' :
3877
@@ -43,8 +82,8 @@ def verification_parser(filename, threshold):
4382 parser .add_argument ('-filename' , type = str ,
4483 help = 'path to output file from the verification test' )
4584
46- parser .add_argument ('-threshold' , type = int , default = 15 ,
47- help = 'number of decimal places of similarity required for test to pass' )
85+ parser .add_argument ('-threshold' ,nargs = '+' , type = int , default = 15 ,
86+ help = 'number of decimal places of similarity required for test to pass. Requires a value for each sub test. Separate values with a space. ' )
4887
4988 args = parser .parse_args ()
5089
0 commit comments