24
24
from concurrent .futures import ThreadPoolExecutor
25
25
from typing import Any , Dict , List , Text
26
26
27
+ from cwltest .utils import compare , CompareFail
28
+
27
29
_logger = logging .getLogger ("cwltest" )
28
30
_logger .addHandler (logging .StreamHandler ())
29
31
_logger .setLevel (logging .INFO )
30
32
31
33
UNSUPPORTED_FEATURE = 33
32
34
RUNTIME = sys .version_info .major
33
35
34
- class CompareFail (Exception ):
35
-
36
- @classmethod
37
- def format (cls , expected , actual , cause = None ):
38
- # type: (Any, Any, Any) -> CompareFail
39
- message = u"expected: %s\n got: %s" % (
40
- json .dumps (expected , indent = 4 , sort_keys = True ),
41
- json .dumps (actual , indent = 4 , sort_keys = True ))
42
- if cause :
43
- message += u"\n caused by: %s" % cause
44
- return cls (message )
45
-
46
36
47
37
class TestResult (object ):
48
38
@@ -69,100 +59,9 @@ def create_test_case(self, test):
69
59
return case
70
60
71
61
72
- def compare_file (expected , actual ):
73
- # type: (Dict[str,Any], Dict[str,Any]) -> None
74
- if "path" in expected :
75
- comp = "path"
76
- if "path" not in actual :
77
- actual ["path" ] = actual ["location" ]
78
- else :
79
- comp = "location"
80
- if expected [comp ] != "Any" and (not (actual [comp ].endswith ("/" + expected [comp ]) or
81
- ("/" not in actual [comp ] and expected [comp ] == actual [comp ]))):
82
- raise CompareFail .format (expected , actual , u"%s does not end with %s" % (actual [comp ], expected [comp ]))
83
-
84
- check_keys = set (expected .keys ()) - {'path' , 'location' }
85
-
86
- for k in check_keys :
87
- try :
88
- compare (expected .get (k ), actual .get (k ))
89
- except CompareFail as e :
90
- raise CompareFail .format (expected , actual , u"field '%s' failed comparison: %s" % (
91
- k , str (e )
92
- ))
93
-
94
-
95
- def compare_directory (expected , actual ):
96
- # type: (Dict[str,Any], Dict[str,Any]) -> None
97
- if actual .get ("class" ) != 'Directory' :
98
- raise CompareFail .format (expected , actual , u"expected object with a class 'Directory'" )
99
- if "listing" not in actual :
100
- raise CompareFail .format (expected , actual , u"'listing' is mandatory field in Directory object" )
101
- for i in expected ["listing" ]:
102
- found = False
103
- for j in actual ["listing" ]:
104
- try :
105
- compare (i , j )
106
- found = True
107
- break
108
- except CompareFail :
109
- pass
110
- if not found :
111
- raise CompareFail .format (expected , actual , u"%s not found" % json .dumps (i , indent = 4 , sort_keys = True ))
112
-
113
-
114
- def compare_dict (expected , actual ):
115
- # type: (Dict[str,Any], Dict[str,Any]) -> None
116
- for c in expected :
117
- try :
118
- compare (expected [c ], actual .get (c ))
119
- except CompareFail as e :
120
- raise CompareFail .format (expected , actual , u"failed comparison for key '%s': %s" % (c , e ))
121
- extra_keys = set (actual .keys ()).difference (list (expected .keys ()))
122
- for k in extra_keys :
123
- if actual [k ] is not None :
124
- raise CompareFail .format (expected , actual , u"unexpected key '%s'" % k )
125
-
126
-
127
- def compare (expected , actual ): # type: (Any, Any) -> None
128
- if expected == "Any" :
129
- return
130
- if expected is not None and actual is None :
131
- raise CompareFail .format (expected , actual )
132
-
133
- try :
134
- if isinstance (expected , dict ):
135
- if not isinstance (actual , dict ):
136
- raise CompareFail .format (expected , actual )
137
-
138
- if expected .get ("class" ) == "File" :
139
- compare_file (expected , actual )
140
- elif expected .get ("class" ) == "Directory" :
141
- compare_directory (expected , actual )
142
- else :
143
- compare_dict (expected , actual )
144
-
145
- elif isinstance (expected , list ):
146
- if not isinstance (actual , list ):
147
- raise CompareFail .format (expected , actual )
148
-
149
- if len (expected ) != len (actual ):
150
- raise CompareFail .format (expected , actual , u"lengths don't match" )
151
- for c in range (0 , len (expected )):
152
- try :
153
- compare (expected [c ], actual [c ])
154
- except CompareFail as e :
155
- raise CompareFail .format (expected , actual , e )
156
- else :
157
- if expected != actual :
158
- raise CompareFail .format (expected , actual )
159
-
160
- except Exception as e :
161
- raise CompareFail (str (e ))
162
-
163
-
164
62
templock = threading .Lock ()
165
63
64
+
166
65
def run_test (args , i , tests ): # type: (argparse.Namespace, int, List[Dict[str, str]]) -> TestResult
167
66
global templock
168
67
@@ -240,17 +139,17 @@ def run_test(args, i, tests): # type: (argparse.Namespace, int, List[Dict[str,
240
139
fail_message = ''
241
140
242
141
if t .get ("should_fail" , False ):
243
- _logger .warn (u"""Test failed: %s""" , " " .join ([pipes .quote (tc ) for tc in test_command ]))
244
- _logger .warn (t .get ("doc" ))
245
- _logger .warn (u"Returned zero but it should be non-zero" )
142
+ _logger .warning (u"""Test failed: %s""" , " " .join ([pipes .quote (tc ) for tc in test_command ]))
143
+ _logger .warning (t .get ("doc" ))
144
+ _logger .warning (u"Returned zero but it should be non-zero" )
246
145
return TestResult (1 , outstr , outerr , duration , args .classname )
247
146
248
147
try :
249
148
compare (t .get ("output" ), out )
250
149
except CompareFail as ex :
251
- _logger .warn (u"""Test failed: %s""" , " " .join ([pipes .quote (tc ) for tc in test_command ]))
252
- _logger .warn (t .get ("doc" ))
253
- _logger .warn (u"Compare failure %s" , ex )
150
+ _logger .warning (u"""Test failed: %s""" , " " .join ([pipes .quote (tc ) for tc in test_command ]))
151
+ _logger .warning (t .get ("doc" ))
152
+ _logger .warning (u"Compare failure %s" , ex )
254
153
fail_message = str (ex )
255
154
256
155
if outdir :
@@ -260,6 +159,8 @@ def run_test(args, i, tests): # type: (argparse.Namespace, int, List[Dict[str,
260
159
261
160
262
161
def main (): # type: () -> int
162
+ _logger .handlers .pop () # prints log messages twice without this line
163
+
263
164
parser = argparse .ArgumentParser (description = 'Compliance tests for cwltool' )
264
165
parser .add_argument ("--test" , type = str , help = "YAML file describing test cases" , required = True )
265
166
parser .add_argument ("--basedir" , type = str , help = "Basedir to use for tests" , default = "." )
@@ -358,10 +259,10 @@ def main(): # type: () -> int
358
259
_logger .info ("All tests passed" )
359
260
return 0
360
261
elif failures == 0 and unsupported > 0 :
361
- _logger .warn ("%i tests passed, %i unsupported features" , total - unsupported , unsupported )
262
+ _logger .warning ("%i tests passed, %i unsupported features" , total - unsupported , unsupported )
362
263
return 0
363
264
else :
364
- _logger .warn ("%i tests passed, %i failures, %i unsupported features" , total - (failures + unsupported ), failures , unsupported )
265
+ _logger .warning ("%i tests passed, %i failures, %i unsupported features" , total - (failures + unsupported ), failures , unsupported )
365
266
return 1
366
267
367
268
0 commit comments