comparison toolfactory/ToolFactory_tester.xml @ 6:efefe43f23c8 draft default tip

Uploaded
author fubar
date Fri, 30 Apr 2021 02:10:32 +0000
parents 2a46da701dde
children
comparison
equal deleted inserted replaced
5:e2c8c2fa192d 6:efefe43f23c8
8 <stdio> 8 <stdio>
9 <exit_code range="1:" level="fatal"/> 9 <exit_code range="1:" level="fatal"/>
10 </stdio> 10 </stdio>
11 <version_command><![CDATA[echo "1"]]></version_command> 11 <version_command><![CDATA[echo "1"]]></version_command>
12 <command><![CDATA[ 12 <command><![CDATA[
13 mkdir 'TF_run_report';
13 python 14 python
14 $runme 15 $runme
15 --in_tool_archive 16 --in_tool_archive
16 $in_tool_archive 17 $in_tool_archive
17 --new_tested_tool_archive 18 --new_tested_tool_archive
18 $new_tested_tool_archive 19 $new_tested_tool_archive
19 --galaxy_root 20 --galaxy_root
20 "$galaxyroot" 21 "$__root_dir__"
21 > 22 >
22 $tf_archive_tester_log; 23 "TF_run_report/${in_tool_archive.name}_test_log.txt"
23 ]]></command> 24 ]]></command>
24 <configfiles> 25 <configfiles>
25 <configfile name="runme"><![CDATA[#raw 26 <configfile name="runme"><![CDATA[#raw
26 27
27 # see https://github.com/fubar2/toolfactory 28 # see https://github.com/fubar2/toolfactory
59 def timenow(): 60 def timenow():
60 """return current time as a string""" 61 """return current time as a string"""
61 return time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(time.time())) 62 return time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(time.time()))
62 63
63 class ToolTester(): 64 class ToolTester():
64 # requires highly insecure docker settings - like write to tool_conf.xml and to tools !
65 # if in a container possibly not so courageous.
66 # Fine on your own laptop but security red flag for most production instances
67 # uncompress passed tar, run planemo and rebuild a new tarball with tests 65 # uncompress passed tar, run planemo and rebuild a new tarball with tests
68 66
69 def __init__(self, args=None, in_tool_archive='/galaxy-central/tools/newtool/newtool_toolshed.gz', new_tool_archive=None): 67 def __init__(self, args=None, in_tool_archive='/galaxy-central/tools/newtool/newtool_toolshed.gz', new_tool_archive=None):
70 self.args = args 68 self.args = args
71 self.new_tool_archive = new_tool_archive 69 self.new_tool_archive = new_tool_archive
95 self.moveRunOutputs() 93 self.moveRunOutputs()
96 self.makeToolTar() 94 self.makeToolTar()
97 95
98 def call_planemo(self,xmlpath,ourdir): 96 def call_planemo(self,xmlpath,ourdir):
99 penv = os.environ 97 penv = os.environ
100 #penv['HOME'] = os.path.join(self.args.galaxy_root,'planemo') 98 penv['HOME'] = os.path.join(self.args.galaxy_root,'planemo')
101 #penv["GALAXY_VIRTUAL_ENV"] = os.path.join(penv['HOME'],'.planemo','gx_venv_3.9') 99 newpath = f"{penv['HOME']}:{penv['PATH']}"
100 penv['PATH'] = newpath
101 penv["GALAXY_VIRTUAL_ENV"] = os.path.join(self.args.galaxy_root,'.venv')
102 penv["PIP_CACHE_DIR"] = os.path.join(self.args.galaxy_root,'pipcache') 102 penv["PIP_CACHE_DIR"] = os.path.join(self.args.galaxy_root,'pipcache')
103 toolfile = os.path.split(xmlpath)[1] 103 toolfile = os.path.split(xmlpath)[1]
104 tool_name = self.tool_name 104 tool_name = self.tool_name
105 tool_test_output = f"{tool_name}_planemo_test_report.html" 105 tool_test_output = f"{tool_name}_planemo_test_report.html"
106 cll = [ 106 cll = [
107 "planemo", 107 "planemo",
108 "test", 108 "test",
109 "--biocontainers", 109 "--no_cleanup",
110 "--test_data",
111 os.path.abspath(ourdir),
110 "--test_output", 112 "--test_output",
111 os.path.abspath(tool_test_output), 113 os.path.abspath(self.tool_test_output),
112 "--galaxy_root", 114 "--galaxy_root",
113 self.args.galaxy_root, 115 self.args.galaxy_root,
114 "--update_test_data", 116 "--update_test_data",
115 os.path.abspath(xmlpath), 117 os.path.abspath(xmlpath),
116 ] 118 ]
117 print(cll) 119 print(cll)
118 p = subprocess.run( 120 p = subprocess.run(
119 cll, 121 cll,
120 #capture_output=True, 122 #capture_output=True,
121 encoding='utf8', 123 encoding='utf8',
124 cwd = os.path.abspath(self.tool_name),
122 env = penv, 125 env = penv,
123 shell=False, 126 shell=False,
124 ) 127 )
125 return p 128 return p
126 129
128 """write xmls and input samples into place""" 131 """write xmls and input samples into place"""
129 for xreal in self.ourxmls: 132 for xreal in self.ourxmls:
130 x = os.path.split(xreal)[1] 133 x = os.path.split(xreal)[1]
131 xout = os.path.join(self.tooloutdir,x) 134 xout = os.path.join(self.tooloutdir,x)
132 shutil.copyfile(xreal, xout) 135 shutil.copyfile(xreal, xout)
133 # for p in self.infiles:
134 # pth = p["name"]
135 # dest = os.path.join(self.testdir, "%s_sample" % p["infilename"])
136 # shutil.copyfile(pth, dest)
137 # dest = os.path.join(self.repdir, "%s_sample" % p["infilename"])
138 # shutil.copyfile(pth, dest)
139 136
140 def makeToolTar(self): 137 def makeToolTar(self):
141 """move outputs into test-data and prepare the tarball""" 138 """move outputs into test-data and prepare the tarball"""
142 excludeme = "_planemo_test_report.html" 139 excludeme = "_planemo_test_report.html"
143 140
172 dest = os.path.join(self.repdir, newname) 169 dest = os.path.join(self.repdir, newname)
173 src = os.path.join(self.tooloutdir, entry.name) 170 src = os.path.join(self.tooloutdir, entry.name)
174 shutil.copyfile(src, dest) 171 shutil.copyfile(src, dest)
175 with os.scandir('.') as outs: 172 with os.scandir('.') as outs:
176 for entry in outs: 173 for entry in outs:
177 if not entry.is_file(): 174 if not entry.is_file() or entry.name == "conda_activate.log":
178 continue 175 continue
179 if "." in entry.name: 176 if "." in entry.name:
180 _, ext = os.path.splitext(entry.name) 177 _, ext = os.path.splitext(entry.name)
181 if ext in [".yml", ".xml", ".yaml"]: 178 if ext in [".yml", ".xml", ".yaml"]:
182 newname = f"{entry.name.replace('.','_')}.txt" 179 newname = f"{entry.name.replace('.','_')}.txt"
210 207
211 208
212 def update_tests(self,ourdir): 209 def update_tests(self,ourdir):
213 for xmlf in self.ourxmls: 210 for xmlf in self.ourxmls:
214 capture = self.call_planemo(xmlf,ourdir) 211 capture = self.call_planemo(xmlf,ourdir)
215 #sys.stderr.write('%s, stdout=%s, stderr=%s' % (xmlf, capture.stdout, capture.stdout))
216 #print('%s, stdout=%s, stderr=%s' % (capture.stdout, capture.stdout,xmlf))
217 212
218 def main(): 213 def main():
219 """ 214 """
220 This is a Galaxy wrapper. 215 This is a Galaxy wrapper.
221 It expects to be called by a special purpose tool.xml 216 It expects to be called by a special purpose tool.xml
237 #end raw]]></configfile> 232 #end raw]]></configfile>
238 </configfiles> 233 </configfiles>
239 <inputs> 234 <inputs>
240 <param name="new_tool_name" value="" type="hidden"/> 235 <param name="new_tool_name" value="" type="hidden"/>
241 <param name="in_tool_archive" type="data" optional="false" label="Select a no_test tarfile to test and update for a toolshed" help="" format="toolshed.gz" multiple="false"/> 236 <param name="in_tool_archive" type="data" optional="false" label="Select a no_test tarfile to test and update for a toolshed" help="" format="toolshed.gz" multiple="false"/>
242 <param name="galaxyroot" type="text" value="/home/ross/gal21" label="Galaxy root for planemo to use - MUST be made available in the Galaxy job runner configuration" help=""/>
243 </inputs> 237 </inputs>
244 <outputs> 238 <outputs>
245 <data name="new_tested_tool_archive" format="toolshed.gz" label="${in_tool_archive.name.split('_')[0]}_tested_toolshed.gz" hidden="false"/> 239 <data name="new_tested_tool_archive" format="toolshed.gz" label="${in_tool_archive.name.split('_')[0]}_tested_toolshed.gz" hidden="false"/>
246 <data name="tf_archive_tester_log" format="txt" label="${in_tool_archive.name}_test_log" hidden="false"/>
247 <collection name="TF_run_report" type="list" label="${in_tool_archive.name} test Run reports"> 240 <collection name="TF_run_report" type="list" label="${in_tool_archive.name} test Run reports">
248 <discover_datasets pattern="__name_and_ext__" directory="TF_run_report" visible="false"/> 241 <discover_datasets pattern="__name_and_ext__" directory="TF_run_report" visible="false"/>
249 </collection> 242 </collection>
250 </outputs> 243 </outputs>
251 <tests> 244 <tests>
252 <test> 245 <test>
253 <output name="new_tested_tool_archive" value="new_tested_tool_archive_sample" compare="sim_size" delta_frac="0.5"/> 246 <output name="new_tested_tool_archive" value="new_tested_tool_archive_sample" compare="sim_size" delta_frac="0.5"/>
254 <output name="tf_archive_tester_log" value="tf_archive_tester_log_sample" compare="sim_size" delta_frac="0.1"/>
255 <param name="in_tool_archive" value="in_tool_archive_sample"/> 247 <param name="in_tool_archive" value="in_tool_archive_sample"/>
256 <param name="galaxyroot" value="/home/ross/gal21"/>
257 <output_collection name="TF_run_report"/> 248 <output_collection name="TF_run_report"/>
258 </test> 249 </test>
259 </tests> 250 </tests>
260 <help><![CDATA[ 251 <help><![CDATA[
261 252
262 **What it Does** 253 **What it Does**
263 254
264 ------ 255 ------
265 256
266 Script:: 257 Script::
258
259 # see https://github.com/fubar2/toolfactory
260 #
261 # copyright ross lazarus (ross stop lazarus at gmail stop com) May 2012
262 #
263 # all rights reserved
264 # Licensed under the LGPL
265 # suggestions for improvement and bug fixes welcome at
266 # https://github.com/fubar2/toolfactory
267 267
268 import argparse 268 import argparse
269 import copy 269 import copy
270 import os 270 import os
271 import subprocess 271 import subprocess
273 import sys 273 import sys
274 import tarfile 274 import tarfile
275 import tempfile 275 import tempfile
276 import time 276 import time
277 import xml.etree.ElementTree as ET 277 import xml.etree.ElementTree as ET
278
279
278 myversion = "V2.2 April 2021" 280 myversion = "V2.2 April 2021"
279 verbose = True 281 verbose = True
280 debug = True 282 debug = True
281 toolFactoryURL = "https://github.com/fubar2/toolfactory" 283 toolFactoryURL = "https://github.com/fubar2/toolfactory"
284
282 def timenow(): 285 def timenow():
283 """return current time as a string""" 286 """return current time as a string"""
284 return time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(time.time())) 287 return time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(time.time()))
285 288
286 class ToolTester(): 289 class ToolTester():
287 # requires highly insecure docker settings - like write to tool_conf.xml and to tools !
288 # if in a container possibly not so courageous.
289 # Fine on your own laptop but security red flag for most production instances
290 # uncompress passed tar, run planemo and rebuild a new tarball with tests 290 # uncompress passed tar, run planemo and rebuild a new tarball with tests
291
291 def __init__(self, args=None, in_tool_archive='/galaxy-central/tools/newtool/newtool_toolshed.gz', new_tool_archive=None): 292 def __init__(self, args=None, in_tool_archive='/galaxy-central/tools/newtool/newtool_toolshed.gz', new_tool_archive=None):
292 self.args = args 293 self.args = args
293 self.new_tool_archive = new_tool_archive 294 self.new_tool_archive = new_tool_archive
294 assert tarfile.is_tarfile(in_tool_archive) 295 assert tarfile.is_tarfile(in_tool_archive)
295 # this is not going to go well with arbitrary names. 296 # this is not going to go well with arbitrary names.
296 tff = tarfile.open(in_tool_archive, "r:*") 297 tff = tarfile.open(in_tool_archive, "r:*")
297 flist = tff.getnames() 298 flist = tff.getnames()
298 ourdir = os.path.commonpath(flist) # eg pyrevpos 299 ourdir = os.path.commonpath(flist) # eg pyrevpos
299 self.tool_name = ourdir 300 self.tool_name = ourdir
300 ourxmls = [x for x in flist if x.lower().endswith('.xml') and os.path.split(x)[0] == ourdir] 301 ourxmls = [x for x in flist if x.lower().endswith('.xml') and os.path.split(x)[0] == ourdir]
301 # planemo_test/planemo_test.xml
302 assert len(ourxmls) > 0 302 assert len(ourxmls) > 0
303 self.ourxmls = ourxmls # [os.path.join(tool_path,x) for x in ourxmls] 303 self.ourxmls = ourxmls # [os.path.join(tool_path,x) for x in ourxmls]
304 res = tff.extractall() 304 res = tff.extractall()
305 self.update_tests(ourdir) 305 self.update_tests(ourdir)
306 tff.close() 306 tff.close()
317 self.moveRunOutputs() 317 self.moveRunOutputs()
318 self.makeToolTar() 318 self.makeToolTar()
319 319
320 def call_planemo(self,xmlpath,ourdir): 320 def call_planemo(self,xmlpath,ourdir):
321 penv = os.environ 321 penv = os.environ
322 penv['HOME'] = '/home/ross/galaxy-release_21.01' 322 penv["PIP_CACHE_DIR"] = os.path.join(self.args.galaxy_root,'pipcache')
323 toolfile = os.path.split(xmlpath)[1] 323 toolfile = os.path.split(xmlpath)[1]
324 tool_name = self.tool_name 324 tool_name = self.tool_name
325 tool_test_output = f"{tool_name}_planemo_test_report.html" 325 tool_test_output = f"{tool_name}_planemo_test_report.html"
326 cll = [ 326 cll = [
327 "planemo", 327 "planemo",
328 "test", 328 "test",
329 "--biocontainers",
329 "--test_output", 330 "--test_output",
330 os.path.abspath(tool_test_output), 331 os.path.abspath(tool_test_output),
331 "--galaxy_root", 332 "--galaxy_root",
332 self.args.galaxy_root, 333 self.args.galaxy_root,
333 "--update_test_data", 334 "--update_test_data",
334 os.path.abspath(xmlpath), 335 os.path.abspath(xmlpath),
335 ] 336 ]
336 print(cll) 337 print(cll)
337 p = subprocess.run( 338 p = subprocess.run(
338 cll, 339 cll,
339 capture_output=True, 340 #capture_output=True,
340 encoding='utf8', 341 encoding='utf8',
341 env = penv, 342 env = penv,
342 shell=False, 343 shell=False,
343 ) 344 )
344 return p 345 return p
347 """write xmls and input samples into place""" 348 """write xmls and input samples into place"""
348 for xreal in self.ourxmls: 349 for xreal in self.ourxmls:
349 x = os.path.split(xreal)[1] 350 x = os.path.split(xreal)[1]
350 xout = os.path.join(self.tooloutdir,x) 351 xout = os.path.join(self.tooloutdir,x)
351 shutil.copyfile(xreal, xout) 352 shutil.copyfile(xreal, xout)
352 # for p in self.infiles:
353 # pth = p["name"]
354 # dest = os.path.join(self.testdir, "%s_sample" % p["infilename"])
355 # shutil.copyfile(pth, dest)
356 # dest = os.path.join(self.repdir, "%s_sample" % p["infilename"])
357 # shutil.copyfile(pth, dest)
358 353
359 def makeToolTar(self): 354 def makeToolTar(self):
360 """move outputs into test-data and prepare the tarball""" 355 """move outputs into test-data and prepare the tarball"""
361 excludeme = "_planemo_test_report.html" 356 excludeme = "_planemo_test_report.html"
357
362 def exclude_function(tarinfo): 358 def exclude_function(tarinfo):
363 filename = tarinfo.name 359 filename = tarinfo.name
364 return None if filename.endswith(excludeme) else tarinfo 360 return None if filename.endswith(excludeme) else tarinfo
361
365 newtar = 'new_%s_toolshed.gz' % self.tool_name 362 newtar = 'new_%s_toolshed.gz' % self.tool_name
366 ttf = tarfile.open(newtar, "w:gz") 363 ttf = tarfile.open(newtar, "w:gz")
367 ttf.add(name=self.tooloutdir, 364 ttf.add(name=self.tool_name,
368 arcname=self.tool_name, 365 arcname=self.tool_name,
369 filter=exclude_function) 366 filter=exclude_function)
370 ttf.close() 367 ttf.close()
371 shutil.copyfile(newtar, self.new_tool_archive) 368 shutil.copyfile(newtar, self.new_tool_archive)
372 369
423 newname = f"{entry.name}.txt" 420 newname = f"{entry.name}.txt"
424 dest = os.path.join(self.repdir, newname) 421 dest = os.path.join(self.repdir, newname)
425 src = os.path.join(self.testdir, entry.name) 422 src = os.path.join(self.testdir, entry.name)
426 shutil.copyfile(src, dest) 423 shutil.copyfile(src, dest)
427 424
425
428 def update_tests(self,ourdir): 426 def update_tests(self,ourdir):
429 for xmlf in self.ourxmls: 427 for xmlf in self.ourxmls:
430 capture = self.call_planemo(xmlf,ourdir) 428 capture = self.call_planemo(xmlf,ourdir)
431 #sys.stderr.write('%s, stdout=%s, stderr=%s' % (xmlf, capture.stdout, capture.stdout))
432 print('%s, stdout=%s, stderr=%s' % (capture.stdout, capture.stdout,xmlf))
433 429
434 def main(): 430 def main():
435 """ 431 """
436 This is a Galaxy wrapper. 432 This is a Galaxy wrapper.
437 It expects to be called by a special purpose tool.xml 433 It expects to be called by a special purpose tool.xml
434
438 """ 435 """
439 parser = argparse.ArgumentParser() 436 parser = argparse.ArgumentParser()
440 a = parser.add_argument 437 a = parser.add_argument
441 a("--in_tool_archive", default=None) 438 a("--in_tool_archive", default=None)
442 a("--new_tested_tool_archive", default=None) 439 a("--new_tested_tool_archive", default=None)
443 a("--galaxy_root", default="/home/ross/gal21/") 440 a("--galaxy_root", default="/home/ross/gal21/")
444 args = parser.parse_args() 441 args = parser.parse_args()
445 print('Hello from',os.getcwd()) 442 print('Hello from',os.getcwd())
446 tt = ToolTester(args=args, in_tool_archive=args.in_tool_archive, new_tool_archive=args.new_tested_tool_archive) 443 tt = ToolTester(args=args, in_tool_archive=args.in_tool_archive, new_tool_archive=args.new_tested_tool_archive)
444
447 if __name__ == "__main__": 445 if __name__ == "__main__":
448 main() 446 main()
447
449 448
450 ]]></help> 449 ]]></help>
451 <citations> 450 <citations>
452 <citation type="doi">10.1093/bioinformatics/bts573</citation> 451 <citation type="doi">10.1093/bioinformatics/bts573</citation>
453 </citations> 452 </citations>