1010import math
1111import subprocess
1212import shutil
13-
13+ import hashlib
1414TATUM_ROOT = os .path .dirname (os .path .dirname (os .path .abspath (__file__ )))
1515
1616
1717tests = {
1818 'basic' : [os .path .join (TATUM_ROOT , 'test' , 'basic' )],
19- 'mcnc20' : ["http://www.eecg.utoronto.ca/~kmurray/tatum/golden_results/mcnc20_tatum_golden.tar.gz" ],
20- #'vtr': [
21-
22- #],
23- #'titan_other': [
24-
25- #],
26- #'titan': [
27-
28- #],
19+ 'mcnc20' : ["http://www.eecg.utoronto.ca/~kmurray/tatum/golden_results/mcnc20_tatum_golden.tar" ],
20+ 'vtr' : ["http://www.eecg.utoronto.ca/~kmurray/tatum/golden_results/vtr_tatum_golden.tar" ],
21+ 'titan_other' : ["http://www.eecg.utoronto.ca/~kmurray/tatum/golden_results/titan_other_tatum_golden.tar" ],
22+ 'titan23' : ["http://www.eecg.utoronto.ca/~kmurray/tatum/golden_results/titan23_tatum_golden.tar" ],
2923 #'tau15_unit_delay': [
3024
3125 #],
@@ -68,6 +62,11 @@ def parse_args():
6862 default = False ,
6963 action = 'store_true' )
7064
65+ parser .add_argument ("-f" , "--force" ,
66+ help = "Force download even if test files already found" ,
67+ default = False ,
68+ action = 'store_true' )
69+
7170 return parser .parse_args ()
7271
7372def main ():
@@ -83,7 +82,7 @@ def main():
8382 for test_url in tests [test_name ]:
8483 work_dir = tempfile .mkdtemp (prefix = "tatum_reg_test" )
8584 try :
86- test_files = download_extract_test (args , work_dir , test_url )
85+ test_files = download_extract_test (args , test_name , test_url )
8786 num_failures += run_test (args , work_dir , test_name , test_files )
8887 finally :
8988 if not args .debug :
@@ -123,16 +122,28 @@ def run_single_test(args, work_dir, test_file):
123122 if args .tatum_nworkers :
124123 cmd += ['--num_workers' , str (args .tatum_nworkers )]
125124
126- cmd += [test_file ]
127125
128126 print (" {}" .format (test_file ), end = '' )
129127
130- if args .debug :
131- print ()
132- print (" cmd: {} log: {}" .format (' ' .join (cmd ), log ))
128+ if test_file .endswith (".xz" ):
129+
130+ cmd += ["-" ] #Read from stdin
131+
132+ cmd_str = "xzcat {} | {} > {}" .format (test_file , " " .join (cmd ), log )
133+
134+ if args .debug :
135+ print (cmd_str )
136+
137+ retcode = os .system (cmd_str )
138+ else :
139+ cmd += [test_file ] #Read file directly
133140
134- with open (log , 'w' ) as outfile :
135- retcode = subprocess .call (cmd , stdout = outfile , stderr = outfile )
141+ if args .debug :
142+ print ()
143+ print (" cmd: {} log: {}" .format (' ' .join (cmd ), log ))
144+
145+ with open (log , 'w' ) as outfile :
146+ retcode = subprocess .call (cmd , stdout = outfile , stderr = outfile )
136147
137148 if retcode == 0 :
138149 print (" PASSED" )
@@ -147,35 +158,53 @@ def run_single_test(args, work_dir, test_file):
147158
148159 return num_failed
149160
150- def download_extract_test (args , work_dir , test_url ):
161+ def download_extract_test (args , test_name , test_url ):
151162
152163 test_files = []
153164
154- if '. tar' in test_url :
165+ if 'tar' in test_url :
155166 #A tar file of benchmark files
156- benchmark_tar = os .path .join (work_dir , os .path .basename (test_url ))
167+ benchmark_tar = os .path .join (os . path . join ( TATUM_ROOT , os .path .basename (test_url ) ))
157168
158- get_url (test_url , benchmark_tar )
169+ new_tar = get_url (args , test_url , benchmark_tar )
170+
171+ test_files_dir = os .path .join (TATUM_ROOT , "test" )
172+
173+ if new_tar or args .force :
174+
175+ print ("Extracting test files to {}" .format (test_files_dir ))
176+ with tarfile .TarFile .open (benchmark_tar , mode = "r|*" ) as tar_file :
177+ tar_file .extractall (path = test_files_dir )
178+ else :
179+ print ("Skipping file extraction" .format (test_files_dir ))
159180
160- with tarfile .TarFile .open (benchmark_tar , mode = "r|*" ) as tar_file :
161- tar_file .extractall (path = work_dir )
162181
163- test_files += glob .glob ("{}/*.tatum" .format (work_dir ))
164- test_files += glob .glob ("{}/*/*.tatum" .format (work_dir ))
182+ test_files += glob .glob ("{}/{}/*.tatum*" .format (test_files_dir , test_name ))
165183 else :
166184 #A directory of benchmark files
167185
168186 test_files += glob .glob ("{}/*.tatum" .format (test_url ))
169- test_files += glob .glob ("{}/*/*.tatum" .format (test_url ))
170187
171188 return test_files
172189
173- def get_url (url , filename ):
190+ def get_url (args , url , filename ):
191+ if not args .force and os .path .exists (filename ):
192+ print ("Found existing file {}, checking if hash matches" .format (filename ))
193+ file_matches = check_hash_match (args , url , filename )
194+
195+ if file_matches :
196+ print ("Existing file {} matches, skipping download" .format (filename ))
197+ return False
198+ else :
199+ print ("Existing file {} contents differ, re-downloading" .format (filename ))
200+
174201 if '://' in url :
175202 download_url (url , filename )
176203 else :
177204 shutl .copytree (url , filename )
178205
206+ return True
207+
179208def download_url (url , filename ):
180209 """
181210 Downloads the specifed url to filename
@@ -191,9 +220,39 @@ def download_progress_callback(block_num, block_size, expected_size):
191220 progress_increment = int (math .ceil (total_blocks / 100 ))
192221
193222 if block_num % progress_increment == 0 :
194- print ("." , end = '' , flush = False )
223+ print ("." , end = '' , flush = True )
195224 if block_num * block_size >= expected_size :
196225 print ("" )
197226
227+ def check_hash_match (args , url , filename ):
228+ checksum_url = url + ".sha256"
229+ try :
230+ web_hash = urllib .request .urlopen (checksum_url ).read ()
231+ except urllib .error .HTTPError as e :
232+ print ("Failed to find expected SHA256 checksum at {} (reason '{}')" .format (checksum_url , e ))
233+ return False
234+
235+ local_hash = hash_file (filename )
236+
237+ web_digest_bytes = web_hash .split ()[0 ]
238+ local_digest_bytes = str .encode (local_hash )
239+
240+ if web_digest_bytes == local_digest_bytes :
241+ return True
242+
243+ return False
244+
245+ def hash_file (filepath ):
246+ BUF_SIZE = 65536
247+ sha256 = hashlib .sha256 ()
248+ with open (filepath , "rb" ) as f :
249+ while True :
250+ data = f .read (BUF_SIZE )
251+ if not data :
252+ break
253+ sha256 .update (data )
254+
255+ return sha256 .hexdigest ()
256+
198257if __name__ == "__main__" :
199258 main ()
0 commit comments