2424from concurrent .futures import ThreadPoolExecutor
2525from typing import Any , Dict , List , Text
2626
27+ from cwltest .utils import compare , CompareFail
28+
2729_logger = logging .getLogger ("cwltest" )
2830_logger .addHandler (logging .StreamHandler ())
2931_logger .setLevel (logging .INFO )
3032
3133UNSUPPORTED_FEATURE = 33
3234RUNTIME = sys .version_info .major
3335
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-
4636
4737class TestResult (object ):
4838
@@ -69,100 +59,9 @@ def create_test_case(self, test):
6959 return case
7060
7161
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-
16462templock = threading .Lock ()
16563
64+
16665def run_test (args , i , tests ): # type: (argparse.Namespace, int, List[Dict[str, str]]) -> TestResult
16766 global templock
16867
@@ -240,17 +139,17 @@ def run_test(args, i, tests): # type: (argparse.Namespace, int, List[Dict[str,
240139 fail_message = ''
241140
242141 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" )
246145 return TestResult (1 , outstr , outerr , duration , args .classname )
247146
248147 try :
249148 compare (t .get ("output" ), out )
250149 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 )
254153 fail_message = str (ex )
255154
256155 if outdir :
@@ -260,6 +159,8 @@ def run_test(args, i, tests): # type: (argparse.Namespace, int, List[Dict[str,
260159
261160
262161def main (): # type: () -> int
162+ _logger .handlers .pop () # prints log messages twice without this line
163+
263164 parser = argparse .ArgumentParser (description = 'Compliance tests for cwltool' )
264165 parser .add_argument ("--test" , type = str , help = "YAML file describing test cases" , required = True )
265166 parser .add_argument ("--basedir" , type = str , help = "Basedir to use for tests" , default = "." )
@@ -358,10 +259,10 @@ def main(): # type: () -> int
358259 _logger .info ("All tests passed" )
359260 return 0
360261 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 )
362263 return 0
363264 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 )
365266 return 1
366267
367268
0 commit comments