32b066036d
* Fix a bunch of issues in SPHINCS+ on Windows * Fix testing makefile dependencies by fixing times of common files (affected Windows testing mainly)
104 lignes
3.5 KiB
Python
104 lignes
3.5 KiB
Python
"""
|
|
Checks that every .c and .h file in an implementation is present as a
|
|
dependency of that scheme's Makefile.
|
|
"""
|
|
|
|
import datetime
|
|
import glob
|
|
import os
|
|
|
|
import pytest
|
|
|
|
import helpers
|
|
import pqclean
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'implementation,test_dir,impl_path, init, destr',
|
|
[(impl,
|
|
*helpers.isolate_test_files(impl.path(), 'test_makefile_deps_'))
|
|
for impl in pqclean.Scheme.all_supported_implementations()],
|
|
ids=[str(impl) for impl in pqclean.Scheme.all_supported_implementations()],
|
|
)
|
|
@helpers.filtered_test
|
|
def test_makefile_dependencies(implementation, impl_path, test_dir,
|
|
init, destr):
|
|
init()
|
|
# initial build - want to have *all* files in place at beginning
|
|
helpers.make('clean', working_dir=impl_path)
|
|
helpers.make(working_dir=impl_path)
|
|
# test case for each candidate file
|
|
cfiles = glob.glob(os.path.join(impl_path, '*.c'))
|
|
sfiles = glob.glob(os.path.join(impl_path, '*.[sS]'))
|
|
incfiles = glob.glob(os.path.join(impl_path, '*.inc'))
|
|
hfiles = glob.glob(os.path.join(impl_path, '*.h'))
|
|
try:
|
|
for file in (cfiles + hfiles + sfiles + incfiles):
|
|
check_makefile_dependencies(implementation, impl_path, file)
|
|
except Exception as e:
|
|
print("Affected file: {}".format(file))
|
|
raise e
|
|
finally:
|
|
destr()
|
|
|
|
|
|
def touch(time, *files):
|
|
for path in files:
|
|
times = (time.timestamp(), time.timestamp())
|
|
os.utime(path, times)
|
|
|
|
|
|
def make_check(path, expect_error=False):
|
|
makeflag = '-q' if os.name != 'nt' else '/Q'
|
|
expected_returncode = 0
|
|
if expect_error:
|
|
expected_returncode = 1 if os.name != 'nt' else 255
|
|
helpers.make(makeflag, working_dir=path,
|
|
expected_returncode=expected_returncode)
|
|
|
|
|
|
def check_makefile_dependencies(implementation, impl_path, file):
|
|
cfiles = glob.glob(os.path.join(impl_path, '*.c'))
|
|
sfiles = glob.glob(os.path.join(impl_path, '*.[sS]'))
|
|
hfiles = glob.glob(os.path.join(impl_path, '*.h'))
|
|
incfiles = glob.glob(os.path.join(impl_path, '*.inc'))
|
|
o_ext = '*.o' if os.name != 'nt' else '*.obj'
|
|
ofiles = glob.glob(os.path.join(impl_path, o_ext))
|
|
|
|
# handle dependency files: these also need to be set correctly
|
|
commondir = os.path.join(impl_path, '..', '..', '..', 'common')
|
|
cfiles += glob.glob(os.path.join(commondir, '*.c'))
|
|
cfiles += glob.glob(os.path.join(commondir, '**', '*.c'))
|
|
hfiles += glob.glob(os.path.join(commondir, '*.h'))
|
|
hfiles += glob.glob(os.path.join(commondir, '**', '*.h'))
|
|
incfiles.append(os.path.join(commondir, 'keccak4x', 'KeccakP-1600-unrolling.macros'))
|
|
ofiles += glob.glob(os.path.join(commondir, o_ext))
|
|
ofiles += glob.glob(os.path.join(commondir, '**', o_ext))
|
|
|
|
libfile = os.path.join(impl_path, implementation.libname())
|
|
|
|
# modification time-based calculations is tricky on a sub-second basis
|
|
# so we reset all the modification times to a known and "sensible" order
|
|
now = datetime.datetime.now() - datetime.timedelta(seconds=10)
|
|
ago15 = now - datetime.timedelta(minutes=15)
|
|
ago10 = now - datetime.timedelta(minutes=10)
|
|
ago5 = now - datetime.timedelta(minutes=5)
|
|
|
|
touch(ago15, *cfiles, *sfiles, *hfiles, *incfiles)
|
|
touch(ago10, *ofiles)
|
|
touch(ago5, libfile)
|
|
|
|
# Sanity check: the scheme is up to date
|
|
make_check(impl_path)
|
|
|
|
# touch the candidate .c / .h file
|
|
touch(now, file)
|
|
|
|
# check if it needs to be rebuilt using make -q
|
|
make_check(impl_path, expect_error=True)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
pytest.main(sys.argv)
|