#!/usr/bin/env python3 import os import sys import stat import shutil import random import subprocess def build(algo_dir, template_dir): # create a new directory for the build build_dir = None while build_dir is None: r = "%09d" % random.randint(0, 999999999) d = os.path.join("build", r) if not os.path.isdir(d): build_dir = d print("Building in %s" % build_dir) # copy all the files from the submitted algorithm into the build directory shutil.copytree(algo_dir, build_dir) # remove the test vectors generator if it is there c = os.path.join(build_dir, "genkat_aead.c") if os.path.exists(c): os.remove(c) # find all c and h files, since they will be added to the makefile hfiles = [] cfiles = [] for r, d, f in os.walk(build_dir): for file in f: if file.endswith(".c"): cfiles.append(file) elif file.endswith(".h"): hfiles.append(file) # copy all the files from the template directory into the build directory for f in os.listdir(template_dir): dst = os.path.join(build_dir, f) src = os.path.join(template_dir, f) if os.path.isfile(src) or os.path.islink(src): shutil.copy2(src, dst) elif os.path.isdir(src): shutil.copytree(src, dst) else: raise Exception("I don't know what %s is" % src) # prepare the environmental variables for the makefile env = os.environ env['SRC_FILES'] = ' '.join(cfiles) env['HDR_FILES'] = ' '.join(hfiles) # enter the directory and execute the makefile wd = os.getcwd() os.chdir(build_dir) try: if os.path.isfile('./configure'): p = subprocess.Popen(["./configure"]) p.wait() assert p.returncode == 0 p = subprocess.Popen(['make']) p.wait() assert p.returncode == 0 finally: sys.stdout.flush() sys.stderr.flush() os.chdir(wd) # if execution arrives here, the build was successful return build_dir # Find test vectors in directory or one of the parent directories def find_test_vectors(d): kat = None while True: if d == '': raise Exception("Test vector not found") for f in os.listdir(d): if f.startswith("LWC_AEAD_KAT_") and f.endswith(".txt"): if kat is not None: raise Exception("Multiple test vectors?") kat = f if kat is None: d = os.path.split(d)[0] else: break kat = os.path.join(d, kat) return kat def main(argv): submissions_dir = "all-lwc-submission-files" template_dir = "templates/linux" if len(argv) > 1: template_dir = argv[1] print("Using template %s" % template_dir) subs = os.listdir(submissions_dir) # get all the submissions by looking for files named "api.h" files = [] for submission in subs: implementations_dir = os.path.join(submissions_dir, submission, "Implementations", "crypto_aead") if not os.path.isdir(implementations_dir): continue if "NOT ACCEPTED" in implementations_dir: continue print() print("### %s ###" % submission) c = 0 # r=root, d=directories, f = files for r, d, f in os.walk(implementations_dir): for file in f: if file == "api.h": f = os.path.join(r, file) d = os.path.split(f)[0] assert os.path.isdir(d) print(d) t = find_test_vectors(d) print(t) files.append((t, d)) c += 1 if c == 0: raise Exception("No implementations found") # For testing, we only do the first 1 #files = files[:1] # Clear the build directory as it is a leftover from the previous execution if os.path.isdir('build'): shutil.rmtree('build') os.mkdir('build') print() # Write a script that executes all the tests one after the other test_script_path = os.path.join("build", "test_all.sh") with open(test_script_path, 'w') as test_script: test_script.write("#!/bin/sh\n") test_script.write("mkdir -p logs\n") test_script.write("mkdir -p measurements\n") for t, d in files: print() print(d) try: b = build(d, template_dir) test_script.write("echo \"TESTING %s\"\n" % d) test_script.write("./test.py %s %s 2> %s | tee %s\n" % t, os.path.join(b, 'test'), os.path.join(b, 'test_stderr.log'), os.path.join(b, 'test_stdout.log')) #./test.py all-lwc-submission-files/tinyjambu/Implementations/crypto_aead/tinyjambu192/LWC_AEAD_KAT_192_96.txt build/731759111/test 2> build/731759111/test_stderr.log | tee build/731759111/test_stdout.log print("COMPILATION SUCCESS FOR %s" % d) except Exception: print("COMPILATION FAILED FOR %s" % d) st = os.stat(test_script_path) os.chmod(test_script_path, st.st_mode | stat.S_IEXEC) print() print() print("Now execute ' %s ' to start the test" % test_script_path) if __name__ == "__main__": sys.exit(main(sys.argv))