Clean up tests

Modify the tests to no longer construct the classes multiple times and
to have them make use of the new helpers.make() function.
This commit is contained in:
Thom Wiggers 2019-03-01 13:18:41 +01:00
parent 0bff935662
commit 75be658074
No known key found for this signature in database
GPG Key ID: 001BB0A7CE26E363
10 changed files with 56 additions and 85 deletions

View File

@ -59,6 +59,9 @@ class Scheme:
print("Can't open {}: {}".format(metafile, e)) print("Can't open {}: {}".format(metafile, e))
return None return None
def __repr__(self):
return "<{}({})>".format(self.type.title(), self.name)
class Implementation: class Implementation:
@ -96,7 +99,7 @@ class Implementation:
return "{} implementation of {}".format(self.name, self.scheme.name) return "{} implementation of {}".format(self.name, self.scheme.name)
def __repr__(self): def __repr__(self):
return "<Implementation({}, {})>".format(self.name, self.scheme.name) return "<Implementation({}, {})>".format(self.scheme.name, self.name)
class KEM(Scheme): class KEM(Scheme):

View File

@ -10,20 +10,11 @@ import helpers
def test_compile_lib(): def test_compile_lib():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
yield check_compile_lib, scheme.name, implementation.name yield check_compile_lib, implementation
def check_compile_lib(scheme_name, implementation_name): def check_compile_lib(implementation):
implementation = pqclean.Implementation.by_name( helpers.make(working_dir=implementation.path())
scheme_name, implementation_name)
helpers.run_subprocess(
['make', 'clean'],
implementation.path()
)
helpers.run_subprocess(
['make'],
implementation.path()
)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -15,21 +15,15 @@ def test_dynamic_memory():
for implementation in scheme.implementations: for implementation in scheme.implementations:
# Keep this loop outside, to allow multiple assertions # Keep this loop outside, to allow multiple assertions
for function in ['malloc', 'free', 'realloc', 'calloc']: for function in ['malloc', 'free', 'realloc', 'calloc']:
yield (check_dynamic_memory, yield (check_dynamic_memory, implementation, function)
scheme.name, implementation.name, function)
def check_dynamic_memory(scheme_name, implementation_name, function): def check_dynamic_memory(implementation, function):
implementation = pqclean.Implementation.by_name(
scheme_name, implementation_name)
# 'make' will take care of not rebuilding existing library files # 'make' will take care of not rebuilding existing library files
helpers.run_subprocess( helpers.make(working_dir=implementation.path())
['make'], scheme_name = implementation.scheme.name
implementation.path()
)
out = helpers.run_subprocess( out = helpers.run_subprocess(
['nm', '-g', 'lib{}_{}.a'.format(scheme_name, ['nm', '-g', 'lib{}_{}.a'.format(scheme_name, implementation.name)],
implementation_name)],
implementation.path() implementation.path()
) )
@ -40,6 +34,7 @@ def check_dynamic_memory(scheme_name, implementation_name, function):
raise AssertionError( raise AssertionError(
"Illegal use of dynamic memory function '{}'".format(function)) "Illegal use of dynamic memory function '{}'".format(function))
if __name__ == '__main__': if __name__ == '__main__':
try: try:
import nose2 import nose2

View File

@ -14,32 +14,28 @@ import helpers
def test_functest(): def test_functest():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
yield check_functest, scheme.name, implementation.name yield check_functest, implementation
def test_functest_sanitizers(): def test_functest_sanitizers():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
yield check_functest_sanitizers, scheme.name, implementation.name yield check_functest_sanitizers, implementation
def check_functest(scheme_name, implementation_name): def check_functest(implementation):
implementation = pqclean.Implementation.by_name( helpers.make(TYPE=implementation.scheme.type,
scheme_name, implementation_name) SCHEME=implementation.scheme.name,
IMPLEMENTATION=implementation.name,
working_dir=os.path.join('..', 'test'))
helpers.run_subprocess( helpers.run_subprocess(
['make', ['./functest_{}_{}'.format(implementation.scheme.name,
'TYPE={}'.format(implementation.scheme.type), implementation.name)],
'SCHEME={}'.format(scheme_name),
'IMPLEMENTATION={}'.format(implementation_name)],
os.path.join('..', 'test')
)
helpers.run_subprocess(
['./functest_{}_{}'.format(scheme_name, implementation_name)],
os.path.join('..', 'bin'), os.path.join('..', 'bin'),
) )
def check_functest_sanitizers(scheme_name, implementation_name): def check_functest_sanitizers(implementation):
env = None env = None
if platform.machine() == 'ppc' and os.environ.get('CC', 'gcc') == 'clang': if platform.machine() == 'ppc' and os.environ.get('CC', 'gcc') == 'clang':
raise unittest.SkipTest() raise unittest.SkipTest()
@ -47,25 +43,24 @@ def check_functest_sanitizers(scheme_name, implementation_name):
env = {'ASAN_OPTIONS': 'detect_leaks=0'} env = {'ASAN_OPTIONS': 'detect_leaks=0'}
else: else:
print("Supported platform: {}".format(platform.machine())) print("Supported platform: {}".format(platform.machine()))
implementation = pqclean.Implementation.by_name(
scheme_name, implementation_name)
helpers.make('clean-scheme', 'functest', helpers.make('clean-scheme', 'functest',
TYPE=implementation.scheme.type, TYPE=implementation.scheme.type,
SCHEME=scheme_name, SCHEME=implementation.scheme.name,
IMPLEMENTATION=implementation_name, IMPLEMENTATION=implementation.name,
EXTRAFLAGS='-fsanitize=address,undefined', EXTRAFLAGS='-fsanitize=address,undefined',
working_dir=os.path.join('..', 'test'), working_dir=os.path.join('..', 'test'),
env=env) env=env)
helpers.run_subprocess( helpers.run_subprocess(
['./functest_{}_{}'.format(scheme_name, implementation_name)], ['./functest_{}_{}'.format(implementation.scheme.name,
implementation.name)],
os.path.join('..', 'bin'), os.path.join('..', 'bin'),
env=env, env=env,
) )
# Remove files with ASAN library compiled in # Remove files with ASAN library compiled in
helpers.make('clean-scheme', helpers.make('clean-scheme',
TYPE=implementation.scheme.type, TYPE=implementation.scheme.type,
SCHEME=scheme_name, SCHEME=implementation.scheme.name,
IMPLEMENTATION=implementation_name, IMPLEMENTATION=implementation.name,
working_dir=os.path.join('..', 'test')) working_dir=os.path.join('..', 'test'))

View File

@ -10,12 +10,10 @@ import pqclean
def test_license(): def test_license():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
yield check_license, scheme.name, implementation.name yield check_license, implementation
def check_license(scheme_name, implementation_name): def check_license(implementation):
implementation = pqclean.Implementation.by_name(
scheme_name, implementation_name)
p1 = os.path.join(implementation.path(), 'LICENSE') p1 = os.path.join(implementation.path(), 'LICENSE')
p2 = os.path.join(implementation.path(), 'LICENSE.txt') p2 = os.path.join(implementation.path(), 'LICENSE.txt')
assert(os.path.isfile(p1) or os.path.isfile(p2)) assert(os.path.isfile(p1) or os.path.isfile(p2))

View File

@ -14,20 +14,16 @@ def test_makefile_dependencies():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
# initial build - want to have *all* files in place at beginning # initial build - want to have *all* files in place at beginning
helpers.run_subprocess(['make', 'clean'], implementation.path()) helpers.make('clean', working_dir=implementation.path())
helpers.run_subprocess(['make'], implementation.path()) helpers.make(working_dir=implementation.path())
# test case for each candidate file # test case for each candidate file
cfiles = glob.glob(os.path.join(implementation.path(), '*.c')) cfiles = glob.glob(os.path.join(implementation.path(), '*.c'))
hfiles = glob.glob(os.path.join(implementation.path(), '*.h')) hfiles = glob.glob(os.path.join(implementation.path(), '*.h'))
for file in cfiles + hfiles: for file in cfiles + hfiles:
yield (check_makefile_dependencies, scheme.name, yield (check_makefile_dependencies, implementation, file)
implementation.name, file)
def check_makefile_dependencies(scheme_name, implementation_name, file): def check_makefile_dependencies(implementation, file):
implementation = pqclean.Implementation.by_name(scheme_name,
implementation_name)
cfiles = glob.glob(os.path.join(implementation.path(), '*.c')) cfiles = glob.glob(os.path.join(implementation.path(), '*.c'))
hfiles = glob.glob(os.path.join(implementation.path(), '*.h')) hfiles = glob.glob(os.path.join(implementation.path(), '*.h'))
ofiles = glob.glob(os.path.join(implementation.path(), '*.o')) ofiles = glob.glob(os.path.join(implementation.path(), '*.o'))

View File

@ -9,11 +9,10 @@ import pqclean
def test_metadata(): def test_metadata():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
yield check_metadata, scheme.name yield check_metadata, scheme
def check_metadata(scheme_name): def check_metadata(scheme):
scheme = pqclean.Scheme.by_name(scheme_name)
metadata = scheme.metadata() metadata = scheme.metadata()
specification = EXPECTED_FIELDS.items() specification = EXPECTED_FIELDS.items()

View File

@ -4,17 +4,15 @@ Checks that no implementation makes use of symbolic links.
import os import os
import pqclean import pqclean
import sys
def test_no_symlinks(): def test_no_symlinks():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
yield check_no_symlinks, scheme.name, implementation.name yield check_no_symlinks, implementation
def check_no_symlinks(scheme_name, implementation_name): def check_no_symlinks(implementation):
implementation = pqclean.Implementation.by_name(
scheme_name, implementation_name)
for file in os.listdir(implementation.path()): for file in os.listdir(implementation.path()):
fpath = os.path.join(implementation.path(), file) fpath = os.path.join(implementation.path(), file)
if os.path.islink(fpath): if os.path.islink(fpath):

View File

@ -14,18 +14,14 @@ def test_symbol_namespace():
raise unittest.SkipTest() raise unittest.SkipTest()
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
yield check_symbol_namespace, scheme.name, implementation.name yield check_symbol_namespace, implementation
def check_symbol_namespace(scheme_name, implementation_name): def check_symbol_namespace(implementation):
implementation = pqclean.Implementation.by_name( helpers.make(working_dir=implementation.path())
scheme_name, implementation_name)
helpers.run_subprocess(
['make'],
implementation.path()
)
out = helpers.run_subprocess( out = helpers.run_subprocess(
['nm', '-g', 'lib{}_{}.a'.format(scheme_name, implementation_name)], ['nm', '-g', 'lib{}_{}.a'.format(implementation.scheme.name,
implementation.name)],
implementation.path() implementation.path()
) )

View File

@ -7,26 +7,26 @@ import hashlib
import os import os
import pqclean import pqclean
import helpers import helpers
import subprocess
def test_testvectors(): def test_testvectors():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
yield check_vectors, scheme.name, implementation.name yield check_vectors, implementation
def check_vectors(scheme_name, implementation_name):
scheme = pqclean.Scheme.by_name(scheme_name) def check_vectors(implementation):
implementation = pqclean.Implementation.by_name(scheme_name, implementation_name) helpers.make(TYPE=implementation.scheme.type,
helpers.run_subprocess( SCHEME=implementation.scheme.name,
['make', 'TYPE=' + implementation.scheme.type, 'SCHEME=' + scheme_name, 'IMPLEMENTATION=' + implementation_name], IMPLEMENTATION=implementation.name,
os.path.join('..', 'test') working_dir=os.path.join('..', 'test'))
)
out = helpers.run_subprocess( out = helpers.run_subprocess(
['./testvectors_{}_{}'.format(scheme_name, implementation_name)], ['./testvectors_{}_{}'.format(implementation.scheme.name,
implementation.name)],
os.path.join('..', 'bin'), os.path.join('..', 'bin'),
) )
assert(scheme.metadata()['testvectors-sha256'].lower() == hashlib.sha256(out.encode('utf-8')).hexdigest().lower()) assert(implementation.scheme.metadata()['testvectors-sha256'].lower()
== hashlib.sha256(out.encode('utf-8')).hexdigest().lower())
if __name__ == '__main__': if __name__ == '__main__':