Merge pull request #117 from PQClean/run-only-diffs

Be more selective in test runs
This commit is contained in:
Thom Wiggers 2019-04-19 17:09:29 +02:00 committed by GitHub
commit da10273e52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 195 additions and 106 deletions

View File

@ -4,22 +4,27 @@ version: 2
machine: true machine: true
steps: steps:
- checkout - checkout
- run: - run: &checkouttask
name: Pull submodules name: Pull submodules
command: | command: |
git submodule init git submodule init
git submodule update git submodule update
git checkout $CIRCLECI_BRANCH
git reset --hard $CIRCLECI_SHA1
- run: - run:
name: Install the emulation handlers name: Install the emulation handlers
command: docker run --rm --privileged multiarch/qemu-user-static:register --reset command: docker run --rm --privileged multiarch/qemu-user-static:register --reset
- run: - run:
name: Run the tests in a container name: Run the tests in a container
command: | command: |
docker run -e CI=true --rm -v `pwd`:`pwd` -w `pwd` "pqclean/ci-container:$ARCH" /bin/bash -c " docker run -e CI=true -e PQCLEAN_ONLY_DIFF=1 --rm -v `pwd`:`pwd` -w `pwd` "pqclean/ci-container:$ARCH" /bin/bash -c "
uname -a && uname -a &&
export CC=${CC} && export CC=${CC} &&
pip3 install -r requirements.txt && pip3 install -r requirements.txt &&
cd test && python3 -m nose --rednose --verbose" mkdir test-results &&
cd test && python3 -m nose --rednose --verbose --with-xunit --xunit-file=../test-results/nosetests.xml"
- store_test_results:
path: test-results
.native_job: &nativejob .native_job: &nativejob
docker: docker:
@ -27,17 +32,18 @@ version: 2
steps: steps:
- checkout - checkout
- run: - run:
name: Pull submodules <<: *checkouttask
command: |
git submodule init
git submodule update
- run: - run:
name: Run tests name: Run tests
command: | command: |
export CC=${CC} export CC=${CC}
pip3 install -r requirements.txt && export PQCLEAN_ONLY_DIFF=1
cd test && python3 -m nose --rednose --verbose pip3 install -r requirements.txt
mkdir test-results
cd test
python3 -m nose --rednose --verbose --with-xunit --xunit-file=../test-results/nosetests.xml
- store_test_results:
path: test-results
jobs: jobs:
arm64-gcc: arm64-gcc:

View File

@ -6,8 +6,15 @@ matrix:
compiler: clang compiler: clang
before_install: before_install:
- pip3 install -r requirements.txt - pip3 install -r requirements.txt
before_script:
- git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
- git fetch --unshallow
- git checkout $TRAVIS_BRANCH
- git reset --hard $TRAVIS_COMMIT
script: script:
- "cd test && python3 -m nose --rednose --verbose" - "cd test && python3 -m nose --rednose --verbose"
env:
PQCLEAN_ONLY_DIFF: 1
addons: addons:
homebrew: homebrew:
packages: packages:
@ -21,7 +28,13 @@ matrix:
packages: packages:
- astyle - astyle
- gcc@8 - gcc@8
env:
PQCLEAN_ONLY_DIFF: 1
before_install: before_install:
- git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
- git fetch --unshallow
- git checkout $TRAVIS_BRANCH
- git reset --hard $TRAVIS_COMMIT
- pip3 install -r requirements.txt - pip3 install -r requirements.txt
- brew link gcc - brew link gcc
- export PATH="/usr/local/bin:$PATH" - export PATH="/usr/local/bin:$PATH"

View File

@ -5,7 +5,10 @@ image: Visual Studio 2017
build: build:
verbosity: minimal verbosity: minimal
shallow_clone: false
environment: environment:
PQCLEAN_ONLY_DIFF: 1
matrix: matrix:
- BITS: 64 - BITS: 64
- BITS: 32 - BITS: 32
@ -19,6 +22,11 @@ init:
- set PATH="C:\\Python37";"C:\\Python37\Scripts";%PATH% - set PATH="C:\\Python37";"C:\\Python37\Scripts";%PATH%
build_script: build_script:
- git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
- git fetch --all
- git checkout %APPVEYOR_REPO_BRANCH%
- git reset --hard %APPVEYOR_REPO_COMMIT%
- git diff --name-only origin/master
- python -m pip install -r requirements.txt - python -m pip install -r requirements.txt
- cd test - cd test
# Download Astyle to local folder because putting it in PATH doesn't work # Download Astyle to local folder because putting it in PATH doesn't work

View File

@ -20,6 +20,9 @@ CFLAGS=-O3 -Wall -Wextra -Wpedantic -Werror -std=c99 \
-fstrict-aliasing -fno-common -pipe \ -fstrict-aliasing -fno-common -pipe \
-I$(COMMON_DIR) $(EXTRAFLAGS) -I$(COMMON_DIR) $(EXTRAFLAGS)
# Number of tests run for functests
NTESTS=1
all: $(DEST_DIR)/functest_$(SCHEME)_$(IMPLEMENTATION) \ all: $(DEST_DIR)/functest_$(SCHEME)_$(IMPLEMENTATION) \
$(DEST_DIR)/testvectors_$(SCHEME)_$(IMPLEMENTATION) \ $(DEST_DIR)/testvectors_$(SCHEME)_$(IMPLEMENTATION) \
$(DEST_DIR)/printparams_$(SCHEME)_$(IMPLEMENTATION) $(DEST_DIR)/printparams_$(SCHEME)_$(IMPLEMENTATION)
@ -50,7 +53,7 @@ $(DEST_DIR)/test_common_%: common/%.c $(COMMON_FILES)
$(DEST_DIR)/functest_$(SCHEME)_$(IMPLEMENTATION): build-scheme crypto_$(TYPE)/functest.c $(COMMON_FILES) $(COMMON_DIR)/randombytes.c $(COMMON_HEADERS) $(DEST_DIR)/functest_$(SCHEME)_$(IMPLEMENTATION): build-scheme crypto_$(TYPE)/functest.c $(COMMON_FILES) $(COMMON_DIR)/randombytes.c $(COMMON_HEADERS)
mkdir -p $(DEST_DIR) mkdir -p $(DEST_DIR)
$(CC) $(CFLAGS) -DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) -I$(SCHEME_DIR) crypto_$(TYPE)/functest.c $(COMMON_FILES) $(COMMON_DIR)/notrandombytes.c -o $@ -L$(SCHEME_DIR) -l$(SCHEME)_$(IMPLEMENTATION) $(CC) $(CFLAGS) -DNTESTS=$(NTESTS) -DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) -I$(SCHEME_DIR) crypto_$(TYPE)/functest.c $(COMMON_FILES) $(COMMON_DIR)/notrandombytes.c -o $@ -L$(SCHEME_DIR) -l$(SCHEME)_$(IMPLEMENTATION)
$(DEST_DIR)/testvectors_$(SCHEME)_$(IMPLEMENTATION): build-scheme crypto_$(TYPE)/testvectors.c $(COMMON_FILES) $(COMMON_DIR)/notrandombytes.c $(COMMON_HEADERS) $(DEST_DIR)/testvectors_$(SCHEME)_$(IMPLEMENTATION): build-scheme crypto_$(TYPE)/testvectors.c $(COMMON_FILES) $(COMMON_DIR)/notrandombytes.c $(COMMON_HEADERS)
mkdir -p $(DEST_DIR) mkdir -p $(DEST_DIR)

View File

@ -5,7 +5,9 @@
#include "api.h" #include "api.h"
#include "randombytes.h" #include "randombytes.h"
#ifndef NTESTS
#define NTESTS 5 #define NTESTS 5
#endif
const uint8_t canary[8] = { const uint8_t canary[8] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF

View File

@ -6,7 +6,10 @@
#include "api.h" #include "api.h"
#include "randombytes.h" #include "randombytes.h"
#ifndef NTESTS
#define NTESTS 5 #define NTESTS 5
#endif
#define MLEN 32 #define MLEN 32
const uint8_t canary[8] = { const uint8_t canary[8] = {

View File

@ -7,6 +7,8 @@ import sys
import pqclean import pqclean
import logging
def run_subprocess(command, working_dir='.', env=None, expected_returncode=0): def run_subprocess(command, working_dir='.', env=None, expected_returncode=0):
""" """
@ -113,7 +115,7 @@ def ensure_available(executable):
raise AssertionError("{} not available on CI".format(executable)) raise AssertionError("{} not available on CI".format(executable))
def permit_test(testname, thing, **args): def permit_test(testname, thing, *args, **kwargs):
if 'PQCLEAN_ONLY_TESTS' in os.environ: if 'PQCLEAN_ONLY_TESTS' in os.environ:
if not(testname.lower() in os.environ['PQCLEAN_ONLY_TESTS'].lower().split(',')): if not(testname.lower() in os.environ['PQCLEAN_ONLY_TESTS'].lower().split(',')):
return False return False
@ -142,13 +144,14 @@ def permit_test(testname, thing, **args):
return False return False
if 'PQCLEAN_ONLY_DIFF' in os.environ: if 'PQCLEAN_ONLY_DIFF' in os.environ:
if shutil.which('git') != None: if shutil.which('git') is not None:
# if we're on a non-master branch, and the only changes are in schemes, # if we're on a non-master branch, and the only changes are in schemes,
# only run tests on those schemes # only run tests on those schemes
branch_result = subprocess.run( branch_result = subprocess.run(
['git', 'status', '--porcelain=2', '--branch'], ['git', 'status', '--porcelain=2', '--branch'],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT stderr=subprocess.STDOUT,
cwd="..",
) )
# ensure we're in a working directory # ensure we're in a working directory
if branch_result.returncode != 0: if branch_result.returncode != 0:
@ -161,14 +164,18 @@ def permit_test(testname, thing, **args):
return True return True
# where are there changes? # where are there changes?
diff_result = subprocess.run( diff_result = subprocess.run(
['git', 'diff', '--name-only', 'master'], ['git', 'diff', '--name-only', 'origin/master'],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT stderr=subprocess.STDOUT
) )
assert(diff_result.returncode == 0), "Got unexpected return code {}".format(diff_result.returncode) assert diff_result.returncode == 0, \
"Got unexpected return code {}".format(diff_result.returncode)
for diff_line in diff_result.stdout.decode('utf-8').splitlines(): for diff_line in diff_result.stdout.decode('utf-8').splitlines():
# don't skip test if there are any changes outside schemes # don't skip test if there are any changes outside schemes
if not(diff_line.startswith('crypto_kem')) and not (diff_line.startswith('crypto_sign')): if (not diff_line.startswith('crypto_kem') and
not diff_line.startswith('crypto_sign')):
logging.info("Running all tests as there are changes "
"outside of schemes")
return True return True
# do test if the scheme in question has been changed # do test if the scheme in question has been changed
if diff_line.startswith(thing.path(base='')): if diff_line.startswith(thing.path(base='')):
@ -177,3 +184,15 @@ def permit_test(testname, thing, **args):
return False return False
return True return True
def filtered_test(func):
funcname = func.__name__[len("check_"):]
@functools.wraps(func)
def wrapper(*args, **kwargs):
if permit_test(funcname, *args, **kwargs):
return func(*args, **kwargs)
else:
raise unittest.SkipTest("Test disabled by filter")
return wrapper

View File

@ -55,7 +55,7 @@ class Scheme:
metafile = os.path.join(self.path(), 'META.yml') metafile = os.path.join(self.path(), 'META.yml')
try: try:
with open(metafile, encoding='utf-8') as f: with open(metafile, encoding='utf-8') as f:
metadata = yaml.load(f.read()) metadata = yaml.safe_load(f.read())
return metadata return metadata
except Exception as e: except Exception as e:
print("Can't open {}: {}".format(metafile, e)) print("Can't open {}: {}".format(metafile, e))

View File

@ -5,14 +5,14 @@ import helpers
import pqclean import pqclean
def test_preprocessor(): def test_api_h():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('preprocessor', implementation): yield check_api_h, implementation
yield check_preprocessor, implementation
def check_preprocessor(implementation: pqclean.Implementation): @helpers.filtered_test
def check_api_h(implementation: pqclean.Implementation):
apipath = os.path.join(implementation.path(), 'api.h') apipath = os.path.join(implementation.path(), 'api.h')
errors = [] errors = []
p = re.compile(r'^\s*#include\s*"') p = re.compile(r'^\s*#include\s*"')
@ -25,6 +25,7 @@ def check_preprocessor(implementation: pqclean.Implementation):
"Prohibited external include in api.h" + "".join(errors) "Prohibited external include in api.h" + "".join(errors)
) )
if __name__ == "__main__": if __name__ == "__main__":
try: try:
import nose2 import nose2

View File

@ -17,7 +17,6 @@ def test_char():
) )
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('char', implementation):
yield check_char, implementation yield check_char, implementation
@ -30,6 +29,7 @@ def walk_tree(ast):
yield from walk_tree(child) # recursively yield prohibited nodes yield from walk_tree(child) # recursively yield prohibited nodes
@helpers.filtered_test
@helpers.skip_windows() @helpers.skip_windows()
def check_char(implementation): def check_char(implementation):
errors = [] errors = []

View File

@ -12,7 +12,8 @@ import helpers
def test_common(): def test_common():
for d in os.listdir('common'): for d in os.listdir('common'):
primitive = re.sub(r"\.c$", "", d) primitive = re.sub(r"\.c$", "", d)
if helpers.permit_test('common', None): yield check_common, primitive if helpers.permit_test('common', None):
yield check_common, primitive
def check_common(primitive): def check_common(primitive):

View File

@ -10,10 +10,10 @@ 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:
if helpers.permit_test('compile_lib', implementation):
yield check_compile_lib, implementation yield check_compile_lib, implementation
@helpers.filtered_test
def check_compile_lib(implementation): def check_compile_lib(implementation):
helpers.make('clean', working_dir=implementation.path()) helpers.make('clean', working_dir=implementation.path())
helpers.make(working_dir=implementation.path()) helpers.make(working_dir=implementation.path())

View File

@ -8,33 +8,54 @@ import helpers
import unittest import unittest
import yaml import yaml
helpers.skip_windows()
def _skipped_test(*args, **kwargs):
raise unittest.SkipTest("Skipped consistency check")
def test_duplicate_consistency(): def test_duplicate_consistency():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('duplicate_consistency', implementation): if not helpers.permit_test('duplicate_consistency',
if os.path.isfile(os.path.join('duplicate_consistency', '{}_{}.yml'.format(scheme.name, implementation.name))): implementation):
metafile = os.path.join('duplicate_consistency', '{}_{}.yml'.format(implementation.scheme.name, implementation.name)) yield _skipped_test, implementation
continue
if os.path.isfile(
os.path.join(
'duplicate_consistency',
'{}_{}.yml'.format(scheme.name, implementation.name))):
metafile = os.path.join(
'duplicate_consistency',
'{}_{}.yml'.format(scheme.name, implementation.name))
with open(metafile, encoding='utf-8') as f: with open(metafile, encoding='utf-8') as f:
metadata = yaml.load(f.read()) metadata = yaml.safe_load(f.read())
for group in metadata['consistency_checks']: for group in metadata['consistency_checks']:
source = pqclean.Implementation.by_name(group['source']['scheme'], group['source']['implementation']) source = pqclean.Implementation.by_name(
group['source']['scheme'],
group['source']['implementation'])
for file in group['files']: for file in group['files']:
yield check_duplicate_consistency, implementation, source, file yield (check_duplicate_consistency, implementation,
source, file)
def file_get_contents(filename): def file_get_contents(filename):
with open(filename) as f: with open(filename) as f:
return f.read() return f.read()
@helpers.skip_windows()
def check_duplicate_consistency(implementation, source, file): def check_duplicate_consistency(implementation, source, file):
transformed_src = helpers.run_subprocess( transformed_src = helpers.run_subprocess(
['sed', '-e', 's/{}/{}/g'.format(source.namespace_prefix(), implementation.namespace_prefix()), os.path.join(source.path(), file)] ['sed', '-e', 's/{}/{}/g'.format(source.namespace_prefix(),
implementation.namespace_prefix()), os.path.join(source.path(), file)]
) )
this_src = file_get_contents(os.path.join(implementation.path(), file)) this_src = file_get_contents(os.path.join(implementation.path(), file))
print(os.path.join(implementation.path(), file)) print(os.path.join(implementation.path(), file))
print(this_src) print(this_src)
assert(transformed_src == this_src) assert(transformed_src == this_src)
if __name__ == '__main__': if __name__ == '__main__':
try: try:
import nose2 import nose2

View File

@ -4,19 +4,17 @@ Checks that no dynamic memory functions are used
import pqclean import pqclean
import helpers import helpers
import sys
import unittest
def test_dynamic_memory(): def test_dynamic_memory():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('dynamic_memory', implementation):
# 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, implementation, function) yield (check_dynamic_memory, implementation, function)
@helpers.filtered_test
@helpers.skip_windows() @helpers.skip_windows()
def check_dynamic_memory(implementation, function): def check_dynamic_memory(implementation, function):
# 'make' will take care of not rebuilding existing library files # 'make' will take care of not rebuilding existing library files

View File

@ -5,15 +5,16 @@ import pqclean
def test_formatting(): def test_formatting():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('format', implementation):
yield check_format, implementation yield check_format, implementation
@helpers.filtered_test
def check_format(implementation: pqclean.Implementation): def check_format(implementation: pqclean.Implementation):
helpers.ensure_available('astyle') helpers.ensure_available('astyle')
cfiles = implementation.cfiles() cfiles = implementation.cfiles()
hfiles = implementation.hfiles() hfiles = implementation.hfiles()
result = helpers.run_subprocess(['astyle', result = helpers.run_subprocess(
['astyle',
'--dry-run', '--dry-run',
'--options=../.astylerc', '--options=../.astylerc',
*cfiles, *cfiles,

View File

@ -14,17 +14,16 @@ 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:
if helpers.permit_test('functest', implementation):
yield check_functest, implementation 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:
if helpers.permit_test('functest_sanitizers', implementation):
yield check_functest_sanitizers, implementation yield check_functest_sanitizers, implementation
@helpers.filtered_test
def check_functest(implementation): def check_functest(implementation):
helpers.make('functest', helpers.make('functest',
TYPE=implementation.scheme.type, TYPE=implementation.scheme.type,
@ -41,6 +40,7 @@ def check_functest(implementation):
) )
@helpers.filtered_test
@helpers.skip_windows() @helpers.skip_windows()
@helpers.slow_test @helpers.slow_test
def check_functest_sanitizers(implementation): def check_functest_sanitizers(implementation):

View File

@ -11,10 +11,10 @@ import helpers
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:
if helpers.permit_test('license', implementation):
yield check_license, implementation yield check_license, implementation
@helpers.filtered_test
def check_license(implementation): def check_license(implementation):
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')

View File

@ -12,10 +12,10 @@ additional_flags = []
def test_clang_tidy(): def test_clang_tidy():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('linter', implementation):
yield check_tidy, implementation yield check_tidy, implementation
@helpers.filtered_test
@helpers.skip_windows() @helpers.skip_windows()
def check_tidy(implementation: pqclean.Implementation): def check_tidy(implementation: pqclean.Implementation):
helpers.ensure_available('clang-tidy') helpers.ensure_available('clang-tidy')

View File

@ -8,12 +8,22 @@ import pqclean
import helpers import helpers
import glob import glob
import datetime import datetime
import unittest
def _skipped_test(*args, **kwargs):
"""Used to indicate skipped tests"""
raise unittest.SkipTest("Skipped makefile dependencies test")
def test_makefile_dependencies(): 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:
if helpers.permit_test('makefile_dependencies', implementation): if not helpers.permit_test(
'makefile_dependencies', implementation):
yield _skipped_test, implementation
continue
# initial build - want to have *all* files in place at beginning # initial build - want to have *all* files in place at beginning
helpers.make('clean', working_dir=implementation.path()) helpers.make('clean', working_dir=implementation.path())
helpers.make(working_dir=implementation.path()) helpers.make(working_dir=implementation.path())

View File

@ -10,10 +10,10 @@ import pqclean
def test_metadata(): def test_metadata():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
if helpers.permit_test('metadata', scheme):
yield check_metadata, scheme yield check_metadata, scheme
@helpers.filtered_test
def check_metadata(scheme): def check_metadata(scheme):
metadata = scheme.metadata() metadata = scheme.metadata()

View File

@ -8,10 +8,10 @@ import helpers
def test_metadata_sizes(): def test_metadata_sizes():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('metadata_sizes', implementation):
yield check_metadata_sizes, implementation yield check_metadata_sizes, implementation
@helpers.filtered_test
def check_metadata_sizes(implementation): def check_metadata_sizes(implementation):
metadata = implementation.scheme.metadata() metadata = implementation.scheme.metadata()
impl_meta = next((impl for impl in metadata['implementations'] impl_meta = next((impl for impl in metadata['implementations']

View File

@ -14,17 +14,21 @@ import pqclean
import helpers import helpers
import unittest import unittest
def test_nistkat(): def test_nistkat():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
if scheme.type != 'kem': continue if scheme.type != 'kem':
continue
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('nistkat', implementation):
yield check_nistkat, implementation yield check_nistkat, implementation
@helpers.filtered_test
def check_nistkat(implementation): def check_nistkat(implementation):
if implementation.scheme.name == "kyber768": if implementation.scheme.name == "kyber768":
raise unittest.SkipTest("Temporarily skip NIST KAT check for kyber768 since it's an outdated implementation") raise unittest.SkipTest(
"Temporarily skip NIST KAT check for kyber768 since it's "
"an outdated implementation")
helpers.make('nistkat', helpers.make('nistkat',
TYPE=implementation.scheme.type, TYPE=implementation.scheme.type,
SCHEME=implementation.scheme.name, SCHEME=implementation.scheme.name,

View File

@ -10,10 +10,10 @@ import helpers
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:
if helpers.permit_test('no_symlinks', implementation):
yield check_no_symlinks, implementation yield check_no_symlinks, implementation
@helpers.filtered_test
def check_no_symlinks(implementation): def check_no_symlinks(implementation):
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)

View File

@ -5,10 +5,10 @@ import helpers
def test_preprocessor(): def test_preprocessor():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('preprocessor', implementation):
yield check_preprocessor, implementation yield check_preprocessor, implementation
@helpers.filtered_test
def check_preprocessor(implementation: pqclean.Implementation): def check_preprocessor(implementation: pqclean.Implementation):
cfiles = implementation.cfiles() cfiles = implementation.cfiles()
hfiles = implementation.hfiles() hfiles = implementation.hfiles()

View File

@ -12,10 +12,10 @@ import unittest
def test_symbol_namespace(): def test_symbol_namespace():
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
if helpers.permit_test('symbol_namespace', implementation):
yield check_symbol_namespace, implementation yield check_symbol_namespace, implementation
@helpers.filtered_test
def check_symbol_namespace(implementation): def check_symbol_namespace(implementation):
if sys.platform not in ['linux', 'darwin']: if sys.platform not in ['linux', 'darwin']:
raise unittest.SkipTest("Unsupported platform") raise unittest.SkipTest("Unsupported platform")

View File

@ -10,13 +10,8 @@ import helpers
def test_testvectors(): def test_testvectors():
for scheme in pqclean.Scheme.all_schemes(): @helpers.filtered_test
for implementation in scheme.implementations: def check_testvectors(implementation):
if helpers.permit_test('testvectors', implementation):
yield check_vectors, implementation
def check_vectors(implementation):
helpers.make('testvectors', helpers.make('testvectors',
TYPE=implementation.scheme.type, TYPE=implementation.scheme.type,
SCHEME=implementation.scheme.name, SCHEME=implementation.scheme.name,
@ -33,6 +28,10 @@ def check_vectors(implementation):
assert(implementation.scheme.metadata()['testvectors-sha256'].lower() assert(implementation.scheme.metadata()['testvectors-sha256'].lower()
== hashlib.sha256(out.encode('utf-8')).hexdigest().lower()) == hashlib.sha256(out.encode('utf-8')).hexdigest().lower())
for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations:
yield check_testvectors, implementation
if __name__ == '__main__': if __name__ == '__main__':
try: try:

View File

@ -13,11 +13,11 @@ 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:
if helpers.permit_test('valgrind', implementation):
yield check_valgrind, implementation yield check_valgrind, implementation
@helpers.slow_test @helpers.slow_test
@helpers.filtered_test
def check_valgrind(implementation: pqclean.Implementation): def check_valgrind(implementation: pqclean.Implementation):
if (platform.machine() not in ('i386', 'x86_64') or if (platform.machine() not in ('i386', 'x86_64') or
platform.system() != 'Linux'): platform.system() != 'Linux'):