2019-02-26 04:28:37 +00:00
|
|
|
"""
|
|
|
|
Checks that every .c and .h file in an implementation is present as a
|
|
|
|
dependency of that scheme's Makefile.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import pqclean
|
|
|
|
import helpers
|
|
|
|
import glob
|
2019-02-26 04:42:48 +00:00
|
|
|
import datetime
|
2019-02-26 04:28:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_makefile_dependencies():
|
|
|
|
for scheme in pqclean.Scheme.all_schemes():
|
|
|
|
for implementation in scheme.implementations:
|
2019-02-27 14:27:41 +00:00
|
|
|
# initial build - want to have *all* files in place at beginning
|
2019-03-01 12:18:41 +00:00
|
|
|
helpers.make('clean', working_dir=implementation.path())
|
|
|
|
helpers.make(working_dir=implementation.path())
|
2019-02-26 04:28:37 +00:00
|
|
|
# test case for each candidate file
|
|
|
|
cfiles = glob.glob(os.path.join(implementation.path(), '*.c'))
|
|
|
|
hfiles = glob.glob(os.path.join(implementation.path(), '*.h'))
|
2019-03-04 15:56:05 +00:00
|
|
|
for file in (cfiles + hfiles):
|
2019-03-01 12:18:41 +00:00
|
|
|
yield (check_makefile_dependencies, implementation, file)
|
2019-02-27 14:27:41 +00:00
|
|
|
|
2019-02-26 04:28:37 +00:00
|
|
|
|
2019-03-04 15:56:05 +00:00
|
|
|
def touch(time, *files):
|
|
|
|
if not files:
|
|
|
|
raise Exception("Please specify the files to update")
|
|
|
|
if os.name == 'nt':
|
|
|
|
formatstring = "Get-Date -year %Y -month %m -day %d -hour %H -minute %M -second %S"
|
|
|
|
time = time.strftime(formatstring)
|
|
|
|
commands = []
|
|
|
|
for file in files:
|
|
|
|
commands.append('(ls {}).LastWriteTime = {}'.format(file, time))
|
|
|
|
|
|
|
|
helpers.run_subprocess(['powershell', '; '.join(commands)])
|
|
|
|
else:
|
|
|
|
formatstring = "%Y%m%d%H%M.%S"
|
|
|
|
time = time.strftime(formatstring)
|
|
|
|
helpers.run_subprocess(['touch', '-t', time, *files])
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
2019-03-01 12:18:41 +00:00
|
|
|
def check_makefile_dependencies(implementation, file):
|
2019-03-04 15:56:05 +00:00
|
|
|
cfiles = implementation.cfiles()
|
|
|
|
hfiles = implementation.hfiles()
|
|
|
|
ofiles = implementation.ofiles()
|
2019-02-26 04:28:37 +00:00
|
|
|
|
|
|
|
libfile = os.path.join(implementation.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
|
2019-03-04 15:56:05 +00:00
|
|
|
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, *hfiles)
|
|
|
|
touch(ago10, *ofiles)
|
|
|
|
touch(ago5, libfile)
|
2019-02-26 04:28:37 +00:00
|
|
|
|
2019-02-27 14:29:20 +00:00
|
|
|
# Sanity check: the scheme is up to date
|
2019-03-04 15:56:05 +00:00
|
|
|
make_check(implementation.path())
|
2019-02-27 14:29:20 +00:00
|
|
|
|
2019-02-26 04:28:37 +00:00
|
|
|
# touch the candidate .c / .h file
|
2019-03-04 15:56:05 +00:00
|
|
|
touch(now, file)
|
2019-02-26 04:28:37 +00:00
|
|
|
|
2019-02-27 14:27:41 +00:00
|
|
|
# check if it needs to be rebuilt using make -q
|
2019-03-04 15:56:05 +00:00
|
|
|
make_check(implementation.path(), expect_error=True)
|
2019-02-26 04:28:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
try:
|
|
|
|
import nose2
|
|
|
|
nose2.main()
|
|
|
|
except ImportError:
|
|
|
|
import nose
|
|
|
|
nose.runmodule()
|