| 
1
 | 
     1 #!/usr/bin/python
 | 
| 
 | 
     2 # -*- coding: utf-8 -*-
 | 
| 
 | 
     3 import optparse
 | 
| 
 | 
     4 import sys
 | 
| 
 | 
     5 import difflib
 | 
| 
 | 
     6 import os
 | 
| 
 | 
     7 		
 | 
| 
 | 
     8 
 | 
| 
 | 
     9 class MyParser(optparse.OptionParser):
 | 
| 
 | 
    10 	"""
 | 
| 
 | 
    11 	 From http://stackoverflow.com/questions/1857346/python-optparse-how-to-include-additional-info-in-usage-output
 | 
| 
 | 
    12 	 Provides a better class for displaying formatted help info in epilog() portion of optParse; allows for carriage returns.
 | 
| 
 | 
    13 	"""
 | 
| 
 | 
    14 	def format_epilog(self, formatter):
 | 
| 
 | 
    15 		return self.epilog
 | 
| 
 | 
    16 
 | 
| 
 | 
    17 def stop_err( msg ):
 | 
| 
 | 
    18     sys.stderr.write("%s\n" % msg)
 | 
| 
 | 
    19     sys.exit(1)
 | 
| 
 | 
    20     
 | 
| 
 | 
    21 	
 | 
| 
 | 
    22 def __main__(self):
 | 
| 
 | 
    23 
 | 
| 
 | 
    24 	
 | 
| 
 | 
    25 	"""
 | 
| 
 | 
    26 	(This is run only in context of command line.)
 | 
| 
 | 
    27 	FUTURE: ALLOW GLOB IMPORT OF ALL FILES OF GIVEN SUFFX, each to its own version, initial date taken from file date
 | 
| 
 | 
    28 	FUTURE: ALLOW dates of versions to be adjusted.
 | 
| 
 | 
    29 	""" 
 | 
| 
 | 
    30 	options, args = self.get_command_line()
 | 
| 
 | 
    31 	self.options = options
 | 
| 
 | 
    32 	
 | 
| 
 | 
    33 	if options.test_ids: 
 | 
| 
 | 
    34 		return self.test(options.test_ids)
 | 
| 
 | 
    35 			
 | 
| 
 | 
    36 
 | 
| 
 | 
    37 def get_command_line(self):
 | 
| 
 | 
    38 	"""
 | 
| 
 | 
    39 	*************************** Parse Command Line *****************************
 | 
| 
 | 
    40 	
 | 
| 
 | 
    41 	"""
 | 
| 
 | 
    42 	parser = MyParser(
 | 
| 
 | 
    43 		description = 'Tests a program against given input/output files.',
 | 
| 
 | 
    44 		usage = 'tester.py [program] [input files] [output files] [parameters]',
 | 
| 
 | 
    45 		epilog="""
 | 
| 
 | 
    46 		
 | 
| 
 | 
    47 		    
 | 
| 
 | 
    48 	parser.add_option('-t', '--tests', dest='test_ids', help='Enter "all" or comma-separated id(s) of tests to run.')
 | 
| 
 | 
    49 
 | 
| 
 | 
    50 	return parser.parse_args()
 | 
| 
 | 
    51 
 | 
| 
 | 
    52 
 | 
| 
 | 
    53 
 | 
| 
 | 
    54 def test(self, test_ids):
 | 
| 
 | 
    55 	# Future: read this spec from test-data folder itself?
 | 
| 
 | 
    56 	tests = {
 | 
| 
 | 
    57 		'1': {'input':'a1','outputs':'','options':''}
 | 
| 
 | 
    58 	}
 | 
| 
 | 
    59 	self.test_suite('keydb.py', test_ids, tests, '/tmp/')
 | 
| 
 | 
    60 
 | 
| 
 | 
    61 
 | 
| 
 | 
    62 def test_suite(self, program, test_ids, tests, output_dir):
 | 
| 
 | 
    63 
 | 
| 
 | 
    64 	if test_ids == 'all':
 | 
| 
 | 
    65 		 test_ids = sorted(tests.keys())
 | 
| 
 | 
    66 	else:
 | 
| 
 | 
    67 		 test_ids = test_ids.split(',')
 | 
| 
 | 
    68 
 | 
| 
 | 
    69 	for test_id in test_ids:
 | 
| 
 | 
    70 		if test_id in tests:
 | 
| 
 | 
    71 			test = tests[test_id]
 | 
| 
 | 
    72 			test['program'] = program
 | 
| 
 | 
    73 			test['base_dir'] = base_dir = os.path.dirname(__file__)
 | 
| 
 | 
    74 			executable = os.path.join(base_dir,program)
 | 
| 
 | 
    75 			if not os.path.isfile(executable):
 | 
| 
 | 
    76 				stop_err('\n\tUnable to locate ' + executable)
 | 
| 
 | 
    77 			# Each output file has to be prefixed with the output (usualy /tmp/) folder 
 | 
| 
 | 
    78 			test['tmp_output'] = (' ' + test['outputs']).replace(' ',' ' + output_dir)
 | 
| 
 | 
    79 			# Note: output_dir output files don't get cleaned up after each test.  Should they?!
 | 
| 
 | 
    80 			params = '%(base_dir)s/%(program)s %(base_dir)s/test-data/%(input)s%(tmp_output)s %(options)s' % test
 | 
| 
 | 
    81 			print("Test " + test_id + ': ' + params)
 | 
| 
 | 
    82 			print("................")
 | 
| 
 | 
    83 			os.system(params)
 | 
| 
 | 
    84 			print("................") 
 | 
| 
 | 
    85 			for file in test['outputs'].split(' '):
 | 
| 
 | 
    86 				try:
 | 
| 
 | 
    87 					f1 = open(test['base_dir'] + '/test-data/' + file)
 | 
| 
 | 
    88 					f2 = open(output_dir + file)
 | 
| 
 | 
    89 				except IOError as details:
 | 
| 
 | 
    90 					stop_err('Error in test setup: ' + str(details)+'\n')
 | 
| 
 | 
    91 
 | 
| 
 | 
    92 				#n=[number of context lines
 | 
| 
 | 
    93 				diff = difflib.context_diff(f1.readlines(), f2.readlines(), lineterm='',n=0)
 | 
| 
 | 
    94 				# One Galaxy issue: it doesn't convert entities when user downloads file. 
 | 
| 
 | 
    95 				# BUT IT appears to when generating directly to command line?
 | 
| 
 | 
    96 				print '\nCompare ' + file
 | 
| 
 | 
    97 				print '\n'.join(list(diff))     
 | 
| 
 | 
    98 					
 | 
| 
 | 
    99 		else:
 | 
| 
 | 
   100 			stop_err("\nExpecting one or more test ids from " + str(sorted(tests.keys())))
 | 
| 
 | 
   101 
 | 
| 
 | 
   102 	stop_err("\nTest finished.")
 | 
| 
 | 
   103 	
 | 
| 
 | 
   104 		
 | 
| 
 | 
   105 if __name__ == '__main__':
 | 
| 
 | 
   106 
 | 
| 
 | 
   107 	keydb = KeyDb()
 | 
| 
 | 
   108 	keydb.__main__()
 | 
| 
 | 
   109 
 |