From bc5d18e7cdfdacc5e0aeabea043c263f7477772b Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Thu, 4 Apr 2019 12:05:43 -0400 Subject: [PATCH] Add duplicate consistency check --- test/pqclean.py | 5 ++++ test/test_duplicate_consistency.py | 40 ++++++++++++++++++++++++++++++ test/test_metadata.py | 27 +++++++++++++++++--- 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 test/test_duplicate_consistency.py diff --git a/test/pqclean.py b/test/pqclean.py index f3384dbe..ecabe0c3 100644 --- a/test/pqclean.py +++ b/test/pqclean.py @@ -69,6 +69,11 @@ class Implementation: def __init__(self, scheme, name): self.scheme = scheme self.name = name + + def metadata(self): + for i in self.scheme.metadata()['implementations']: + if i['name'] == self.name: + return i def path(self, base='..') -> str: return os.path.join(self.scheme.path(), self.name) diff --git a/test/test_duplicate_consistency.py b/test/test_duplicate_consistency.py new file mode 100644 index 00000000..890d36e2 --- /dev/null +++ b/test/test_duplicate_consistency.py @@ -0,0 +1,40 @@ +""" +Checks that files duplicated across schemes/implementations are consistent. +""" + +import os +import pqclean +import helpers + + +def test_duplicate_consistency(): + for scheme in pqclean.Scheme.all_schemes(): + for implementation in scheme.implementations: + yield check_duplicate_consistency, implementation + + +def file_get_contents(filename): + with open(filename) as f: + return f.read() + +def check_duplicate_consistency(implementation): + print(implementation.metadata()) + if 'duplicate-consistency' in implementation.metadata(): + dc = implementation.metadata()['duplicate-consistency'] + for pairs in dc['files']: + transformed_src = helpers.run_subprocess( + ['sed', '-e', 's/{}/{}/g'.format(dc['source_namespace'], dc['target_namespace']), pairs['source_file']], + '..', + ) + this_src = file_get_contents(os.path.join(implementation.path(), pairs['target_file'])) + print(this_src) + assert(transformed_src == this_src) + + +if __name__ == '__main__': + try: + import nose2 + nose2.main() + except ImportError: + import nose + nose.runmodule() diff --git a/test/test_metadata.py b/test/test_metadata.py index 71ca7798..c8f352db 100644 --- a/test/test_metadata.py +++ b/test/test_metadata.py @@ -52,6 +52,24 @@ EXPECTED_FIELDS = { 'spec': { 'name': {'type': str}, 'version': {'type': str}, + 'duplicate-consistency': { + 'type': dict, + 'optional': True, + 'spec': { + 'source_namespace': {'type': str}, + 'target_namespace': {'type': str}, + 'files': { + 'type': list, + 'elements': { + 'type': dict, + 'spec': { + 'source_file': {'type': str}, + 'target_file': {'type': str}, + }, + }, + }, + }, + }, }, }, }, @@ -68,14 +86,15 @@ SIGNATURE_FIELDS = { def check_spec(metadata, spec): for field, props in spec: - if field not in metadata: + if field not in metadata and 'optional' not in props: raise AssertionError("Field '{}' not present.".format(field)) # validate element - check_element(field, metadata[field], props) + if field in metadata: + check_element(field, metadata[field], props) - # delete it to detect extras - del metadata[field] + # delete it to detect extras + del metadata[field] # Done checking all specified fields, check if we have extras for field, value in metadata.items():