Merge pull request #531 from open-quantum-safe/ds-pytest

Move more tests to Python unit testing framework
This commit is contained in:
Douglas Stebila 2019-08-01 21:37:45 -04:00 committed by GitHub
commit ae1e616094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 631 additions and 574 deletions

103
.circleci/config.yml Normal file
View File

@ -0,0 +1,103 @@
version: 2
.oqsjob: &oqsjob
docker:
- image: ${IMAGE}
steps:
- checkout
- run:
name: Configure
command: autoreconf -i && ./configure --enable-silent-rules ${CONFIGURE_ARGS}
- run:
name: Build
command: make -j && make check
- run:
name: Run tests
command: mkdir -p test-results/pytest && python3 -m pytest --verbose --junitxml=test-results/pytest/results.xml --numprocesses=auto
- store_test_results: # Note that this command will fail when running CircleCI locally, that is expected behaviour
path: test-results
jobs:
debian-buster-amd64:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:debian-buster-amd64-0.1.0
CONFIGURE_ARGS: --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
SKIP_TESTS: style
ubuntu-xenial-x86_64-gcc49:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:ubuntu-xenial-x86_64-0.1.0
CC: gcc-4.9
CONFIGURE_ARGS: --disable-sig-picnic --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
ubuntu-xenial-x86_64-gcc5:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:ubuntu-xenial-x86_64-0.1.0
CC: gcc-5
CONFIGURE_ARGS: --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
ubuntu-xenial-x86_64-gcc6:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:ubuntu-xenial-x86_64-0.1.0
CC: gcc-6
CONFIGURE_ARGS: --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
ubuntu-xenial-x86_64-gcc7:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:ubuntu-xenial-x86_64-0.1.0
CC: gcc-7
CONFIGURE_ARGS: --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
ubuntu-xenial-x86_64-gcc8:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:ubuntu-xenial-x86_64-0.1.0
CC: gcc-8
CONFIGURE_ARGS: --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
ubuntu-xenial-x86_64-gcc8-noopenssl:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:ubuntu-xenial-x86_64-0.1.0
CC: gcc-8
CONFIGURE_ARGS: --without-openssl --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
ubuntu-xenial-x86_64-gcc8-noshared:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:ubuntu-xenial-x86_64-0.1.0
CC: gcc-8
CONFIGURE_ARGS: --disable-shared --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
ubuntu-bionic-x86_64-gcc7:
<<: *oqsjob
environment:
IMAGE: dstebila/liboqs:ubuntu-bionic-x86_64-0.1.0
CC: gcc-7
CONFIGURE_ARGS: --disable-kem-bike # FIXME: BIKE doesn't work on CircleCI due to symbol _CMP_LT_OS not being defined
SKIP_TESTS: style
workflows:
version: 2
build:
jobs:
- debian-buster-amd64
- ubuntu-xenial-x86_64-gcc8
- ubuntu-xenial-x86_64-gcc8-noopenssl
- ubuntu-xenial-x86_64-gcc8-noshared
- ubuntu-bionic-x86_64-gcc7
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- master
jobs:
- debian-buster-amd64
- ubuntu-xenial-x86_64-gcc49
- ubuntu-xenial-x86_64-gcc5
- ubuntu-xenial-x86_64-gcc6
- ubuntu-xenial-x86_64-gcc7
- ubuntu-xenial-x86_64-gcc8
- ubuntu-xenial-x86_64-gcc8-noopenssl
- ubuntu-xenial-x86_64-gcc8-noshared
- ubuntu-bionic-x86_64-gcc7

4
.gitignore vendored
View File

@ -45,7 +45,6 @@ tests/test_sha3
#kat
tests/kat_kem
kat_kem_rsp/
# Debug files
*.dSYM/
@ -112,4 +111,5 @@ src/oqsconfig.h
.objs_upstream
*.geany
.tags*
__pycache__
__pycache__
test-results

View File

@ -4,25 +4,6 @@ sudo: true
matrix:
include:
- os: linux
compiler: gcc
env:
- CC_OVERRIDE=gcc
- ENABLE_SIG_PICNIC=0
- WITH_OPENSSL=1
- CHECK_STYLE=true
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- doxygen
- graphviz
- python3-pytest
before_install:
- sh .travis/install-clang-format-linux.sh
script:
- .travis/all-tests.sh
- os: linux
compiler: arm-linux-gnueabi-gcc
addons:
@ -34,72 +15,41 @@ matrix:
script:
- scripts/arm-cross-compile.sh
- scripts/arm-run-tests-qemu.sh
- os: linux
compiler: gcc
env:
- CC_OVERRIDE=gcc-4.9
- ENABLE_SIG_PICNIC=0
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.9
- doxygen
- graphviz
- python3-pytest
before_install:
- sh .travis/install-clang-format-linux.sh
script:
- .travis/all-tests.sh
- os: linux
compiler: gcc
env: CC_OVERRIDE=gcc-5
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-5
- doxygen
- graphviz
- python3-pytest
script:
- .travis/all-tests.sh
- os: linux
compiler: gcc
env:
- CC_OVERRIDE=gcc-6
- WITH_OPENSSL=1
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-6
- libssl-dev
- doxygen
- graphviz
- python3-pytest
script:
- .travis/all-tests.sh
- os: osx
compiler: clang
env:
- CC_OVERRIDE=clang
- WITH_OPENSSL=1
- SKIP_TESTS=style
- HOMEBREW_NO_AUTO_UPDATE=1
before_install:
- brew install doxygen graphviz
- pip3 install pytest
- pip3 install pytest pytest-xdist
script:
- .travis/all-tests.sh
- autoreconf -i
- ./configure --enable-silent-rules
- make
- make test
- ./configure --enable-silent-rules --disable-shared
- make clean
- make
- make check
- python3 -m pytest --verbose --numprocesses=auto
- os: osx
compiler: clang
env:
- CC_OVERRIDE=clang
- WITH_OPENSSL=0
- SKIP_TESTS=style
- HOMEBREW_NO_AUTO_UPDATE=1
before_install:
- brew install doxygen graphviz
- pip3 install pytest
- pip3 install pytest pytest-xdist
script:
- .travis/all-tests.sh
- autoreconf -i
- ./configure --enable-silent-rules --without-openssl
- make
- make test
- ./configure --enable-silent-rules --disable-shared
- make clean
- make
- make check
- python3 -m pytest --verbose --numprocesses=auto

View File

@ -1,35 +0,0 @@
#!/bin/bash
###
# Checks that all algorithms have an algorithm datasheet in doc/algorithms.
###
set -e
source $(dirname $0)/defs.sh
# get the list of KEMs and signatures from the list of algorithm identifiers src/kem/kem.h and src/sig/sig.h
ALGS=$(grep -E 'define OQS_(KEM|SIG)_alg_' src/kem/kem.h src/sig/sig.h | grep -v 'default' | sed -e 's/^[^"]*"//' | sed -e 's/".*$//' | tr -d '[:blank:]')
RET=0
for alg in ${ALGS}; do
set +e
FOUND=$(grep ${alg} docs/algorithms/*.md)
set -e
if [[ -z "${FOUND}" ]];
then
${PRINT_RED}
echo "Could not find algorithm datasheet containing '${alg}'."
${PRINT_RESET}
RET=1
fi
done
if [[ "${RET}" == "0" ]];
then
${PRINT_GREEN}
echo "Algorithm datasheet present for all algs #defined in src/kem/kem.h and src/sig/sig.h.";
${PRINT_RESET}
fi
exit ${RET}

View File

@ -1,71 +0,0 @@
#!/bin/bash
###
# Run all tests for Travis
#
# Need to set the following environment variables:
# - CC_OVERRIDE: whatever compiler you want to use
###
source $(dirname $0)/defs.sh
( # this is like the start of a "try...catch" block, see https://stackoverflow.com/questions/22009364/is-there-a-try-catch-command-in-bash#22010339
set -e
# See what has been modified (ignoring submodules because they are likely patched)
MODIFIED=$(git status -s)
if [[ ! -z "${MODIFIED}" ]];
then
${PRINT_RED}
echo "There are modified files present in the directory prior to .travis/all-tests.sh. This may indicate that some files should be added to .gitignore or need to be committed. Travis tests will not yield correct results if modified files are present. Please fix and try again.";
${PRINT_RESET}
git status -s
exit 1;
fi;
if [ -z ${CC_OVERRIDE+x} ]; then
echo "CC_OVERRIDE environment variable not set."
exit 1
fi
export CC=$CC_OVERRIDE
# construct configure arguments
enable_disable_str=
if [[ ${WITH_OPENSSL} == 1 ]];then
enable_disable_str=" --with-openssl"
else
enable_disable_str=" --without-openssl"
fi
if [[ ${ENABLE_SIG_PICNIC} == 0 ]];then
enable_disable_str+=" --disable-sig-picnic"
fi
# build and run
autoreconf -i
./configure --enable-silent-rules ${enable_disable_str}
make clean
make
make docs
make test
# Excercise static build of liboqs too
./configure --enable-shared=no --enable-silent-rules ${enable_disable_str}
make clean
make
make docs
make test
for f in $(ls .travis/*-check.sh); do
bash $f;
done
) # the end of the "try...catch" block
ERROR_CODE=$?
if [ ${ERROR_CODE} -ne 0 ]; then
${PRINT_RED}
echo "An error occurred while running all-tests.sh. If the previous line is a green success message, that is likely what the *last* successful command, and the next command is what caused the error.";
${PRINT_RESET}
exit 1;
fi

View File

@ -1,6 +0,0 @@
#!/bin/bash
PRINT_GREEN="tput setaf 2"
PRINT_RED="tput setaf 1"
PRINT_RESET="tput sgr 0"
PRINT_YELLOW="tput setaf 3"

View File

@ -1,37 +0,0 @@
#!/bin/bash
###
# Checks that "free" is not used unprotected in the main OQS code.
###
set -e
source $(dirname $0)/defs.sh
RET=0
# We need to temporarily remove bash fail-on-error for the last command, because grep returns with error code 1 when there are no lines found
set +e
FREE=$(find src -name '*.c' | grep -v upstream | grep -v 'picnic/external' | xargs grep '[^_]free' | grep "free(" | grep -v 'IGNORE free-check')
ERROR_CODE=$?
set -e
if [ ${ERROR_CODE} -ne 1 ];
then
${PRINT_RED}
echo "'free' is used in the following non-upstream files. These should be changed to 'OQS_MEM_secure_free' or 'OQS_MEM_insecure_free' as appropriate.";
${PRINT_RESET}
echo -n ${FREE} | tr ';' '\n' | sed -e 's/^ //'
${PRINT_RED}
echo "If you are sure you want to use 'free' in a particular spot, add the comment"
echo " // IGNORE free-check"
echo "on the line where 'free' occurs."
${PRINT_RESET}
RET=1
else
${PRINT_GREEN}
echo "No uses of 'free' detected in non-upstream files.";
${PRINT_RESET}
fi;
exit ${RET}

View File

@ -1,30 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/defs.sh
REGEX=' T [_]?(OQS|PQCLEAN|picnic|Keccak|.*shake128|.*shake256|rand_bytes|cpu_supports|uint64_from_char_array|uint64_to_char_array|print_hex|ntt_double|rec|aligned_alloc|aligned_free)'
# For catching errors, we have the first (otherwise superfluous) two lines below two make sure that the commands are being executed correctly
NON_NAMESPACED=`nm -g .libs/liboqs.a`
NON_NAMESPACED=`nm -g .libs/liboqs.a | grep ' T '`
# But we need to temporarily remove bash fail-on-error for the last command, because grep returns with error code 1 when there are no lines found
set +e
NON_NAMESPACED=`nm -g .libs/liboqs.a | grep ' T ' | grep -E -v -i "$REGEX"`
ERROR_CODE=$?
set -e
if [ ${ERROR_CODE} -ne 1 ];
then
${PRINT_RED}
echo "Code contains the following non-namespaced global symbols; see https://github.com/open-quantum-safe/liboqs/wiki/Coding-conventions for function naming conventions.";
${PRINT_RESET}
echo ${NON_NAMESPACED}
exit 1;
else
${PRINT_GREEN}
echo "Code adheres to the project standards (global namespace).";
${PRINT_RESET}
exit 0;
fi;

View File

@ -1,14 +0,0 @@
#!/bin/bash
###
# Install clang-format on Linux
###
set -e
if [ ! -x "$(which clang-format-3.9)" ]; then
sudo add-apt-repository 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.9 main'
wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update -qq
sudo apt-get install -qq -y clang-format-3.9
fi;

View File

@ -1,28 +0,0 @@
#!/bin/bash
###
# Checks that all KATs pass.
###
set -e
source $(dirname $0)/defs.sh
RET=0
./tests/kat_kem
scripts/check_kats.sh
error=$?
if [ $error -eq 0 ];
then
${PRINT_GREEN}
echo "All known answer tests passed.";
${PRINT_RESET}
else
${PRINT_RED}
echo "Error in known answer tests.";
${PRINT_RESET}
RET=1
fi
exit ${RET}

View File

@ -1,79 +0,0 @@
#!/bin/bash
###
# Checks that all non-upstream files satisfy prettyprint requirements.
###
set -e
source $(dirname $0)/defs.sh
if [[ "x${TRAVIS}" == "xtrue" ]];
then
if [[ ! "x${CHECK_STYLE}" == "xtrue" ]];
then
echo "When running on Travis, style-check is only run on some builds."
exit 0
fi
fi
# Make sure that there are no modified files to start with
MODIFIED=$(git status -s)
if [[ ! -z "${MODIFIED}" ]];
then
${PRINT_RED}
echo "There are modified files present in the directory prior to prettyprint check. This may indicate that some files should be added to .gitignore or need to be committed.";
${PRINT_RESET}
git status -s
exit 1;
fi;
# Find clang-format
TRY_CLANGFORMAT="/usr/local/Cellar/clang-format/2016-06-27/bin/clang-format"
if [[ ! -x $(which ${TRY_CLANGFORMAT}) ]];
then
TRY_CLANGFORMAT="clang-format-3.9"
if [[ ! -x $(which ${TRY_CLANGFORMAT}) ]];
then
TRY_CLANGFORMAT="clang-format"
if [[ ! -x $(which ${TRY_CLANGFORMAT}) ]];
then
${PRINT_RED}
echo "Cannot find clang-format."
${PRINT_RESET}
exit 1
fi
fi
fi
# Check clang-format version
set +e
CLANG_FORMAT_VERSION=$(${TRY_CLANGFORMAT} -version | grep 3.9)
ERROR_CODE=$?
set -e
if [ ${ERROR_CODE} -ne 0 ];
then
${PRINT_RED}
echo "clang-format is not version 3.9."
${PRINT_RESET}
${TRY_CLANGFORMAT} -version
exit 1
fi;
# Pretty-print everything
make prettyprint CLANGFORMAT=${TRY_CLANGFORMAT}
# Check if there are any modified files
MODIFIED=$(git status -s)
if [[ ! -z "${MODIFIED}" ]]; then
${PRINT_RED}
echo "Code does not adhere to the project standards. Run \"make prettyprint\".";
${PRINT_RESET}
git status -s
exit 1;
else
${PRINT_GREEN}
echo "Code adheres to the project standards (prettyprint).";
${PRINT_RESET}
exit 0;
fi;

View File

@ -97,18 +97,8 @@ installheader_HEADERS= src/oqs.h \
test: check
tests/example_kem
tests/example_sig
tests/test_kem
tests/test_sig
tests/test_aes
tests/test_sha3
python3 -m pytest -v
kat: clean-kats check
tests/kat_kem
scripts/check_kats.sh
links:
$(MKDIR_P) include/oqs
cp -f src/oqs.h include/oqs
@ -144,9 +134,6 @@ clean-local:
clean-tests:
rm -f tests/example_kem tests/example_sig tests/speed_kem tests/speed_sig tests/test_kem tests/test_sig tests/test_aes tests/test_sha3
clean-kats:
rm -rf tests/kat_kem kat_kem_rsp/
prettyprint:
find src tests -name '*.c' -o -name '*.h' | grep -v picnic/external* | grep -v frodokem/external* | grep -v pqclean | xargs $(CLANGFORMAT) -style=file -i

View File

@ -107,10 +107,6 @@ Lifecycle for master branch
Building and running liboqs master branch
-----------------------------------------
Builds are tested using the Travis continuous integration system on macOS 10.13.3 (clang 9.1.0) and Ubuntu 14.04.5 (gcc.4.8, gcc-4.9, gcc-5, gcc-6). It has also been tested manually on macOS 10.14 (clang 10.0.0), Ubuntu 14.04 (gcc-5), Ubuntu 16.04 (gcc-5), and Ubuntu 18.04.1 (gcc-7).
- [Build status using Travis continuous integration system:](https://travis-ci.org/open-quantum-safe/liboqs/branches) ![Build status image](https://travis-ci.org/open-quantum-safe/liboqs.svg?branch=master)
### Install dependencies for Linux Ubuntu
You need to install the following packages:
@ -137,7 +133,6 @@ On OpenBSD you have to explicitly set the environment variables `AUTOCONF_VERSIO
export AUTOCONF_VERSION=`ls -1 /usr/local/bin/autoreconf-* | sort | tail -n 1 | cut -d'-' -f2`
export AUTOMAKE_VERSION=`ls -1 /usr/local/bin/automake-* | sort | tail -n 1 | cut -d'-' -f2`
### Building
To build, first clone or download the source from GitHub:
@ -162,23 +157,25 @@ The main build result is `liboqs.a`, a static library. (This may be placed in t
There are also a variety of test programs built under the `tests` directory:
- `test_kem`: Simple test harness for all enabled key encapsulation mechanisms
- `test_sig`: Simple test harness for all enabled key signature schemes
- `kat_kem`: Program that generates known answer test (KAT) values for all enabled key encapsulation mechanisms using the same mechanism as the NIST submission requirements, for checking against submitted KAT values using `scripts/check_kats.sh`
- `test_kem`: Simple test harness for key encapsulation mechanisms
- `test_sig`: Simple test harness for key signature schemes
- `kat_kem`: Program that generates known answer test (KAT) values for key encapsulation mechanisms using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py`
- `speed_kem`: Benchmarking program for key encapsulation mechanisms; see `./speed_kem --help` for usage instructions
- `speed_sig`: Benchmarking program for signature mechanisms; see `./speed_sig --help` for usage instructions
- `example_kem`: Minimal runnable example showing the usage of the KEM API
- `example_sig`: Minimal runnable example showing the usage of the signature API
- `test_aes`, `test_sha3`: Simple test harnesses for crypto sub-components
A range of tests (including all `test_*` and `kat_*` programs above) can be run using
python3 -m pytest
Building and running on Windows
-------------------------------
Windows binaries can be generated using the Visual Studio solution in the `VisualStudio` folder.
Builds are tested using the Appveyor continuous integration system on Windows Server 2016 (Visual Studio 2017). Our developers also test builds periodically on Windows 10.
- [Build status using Appveyor continuous integration system:](https://ci.appveyor.com/project/dstebila/liboqs) ![Build status image](https://ci.appveyor.com/api/projects/status/9d2ts78x88r8wnii/branch/master?svg=true)
Builds are tested using the AppVeyor continuous integration system on Windows Server 2016 (Visual Studio 2017). Our developers also test builds periodically on Windows 10.
The supported schemes are defined in the projects' `winconfig.h` file.
@ -198,6 +195,44 @@ Once the toolchain is installed, you can use the following scripts to build and
At present there are still some quirks with our ARM build, including problems with Picnic and qTESLA and the known answer tests causing build errors or segmentation faults. See issues #461, #462, and #463.
Testing
-------
A range of tests (including all `test_*` and `kat_*` programs above) can be run using `make test` or equivalently `python3 -m pytest -v`.
Builds are tested using continuous integration systems as follows:
- macOS 10.13.3 (clang 9.1.0) using Travis CI
- Ubuntu 14.04.5 (Trusty), with gcc, on ARM Cortex-A8 (via QEMU) using Travis CI
- Ubuntu 16.04.6 (Xenial), with gcc-4.9, gcc-5, gcc-6, gcc-7, and gcc-8, on x86_64 using CircleCI
- Ubuntu 18.04.2 (Bionic), with gcc-7, on x86_64 using CircleCI
- Debian 10 (Buster), with gcc-8.3.0, on amd64 using CircleCI
- Windows Server 2016, with Visual Studio 2017, on x86_64 using AppVeyor
Build status:
- [AppVeyor](https://ci.appveyor.com/project/dstebila/liboqs): ![Build status image](https://ci.appveyor.com/api/projects/status/9d2ts78x88r8wnii/branch/master?svg=true)
- [CircleCI](https://circleci.com/gh/open-quantum-safe/liboqs/tree/master): ![Build status image](https://circleci.com/gh/open-quantum-safe/liboqs/tree/master.svg?style=svg)
- [Travis CI](https://travis-ci.org/open-quantum-safe/liboqs): ![Build status image](https://travis-ci.org/open-quantum-safe/liboqs.svg?branch=master)
You can locally run any of the integration tests that CircleCI runs. First, you need to install CircleCI's local command line interface as indicated in the [installation instructions](https://circleci.com/docs/2.0/local-cli/). Then:
circleci local execute --job <jobname>
where `<jobname>` is one of the following:
- `debian-buster-amd64`
- `ubuntu-xenial-x86_64-gcc49`
- `ubuntu-xenial-x86_64-gcc5`
- `ubuntu-xenial-x86_64-gcc6`
- `ubuntu-xenial-x86_64-gcc7`
- `ubuntu-xenial-x86_64-gcc8`
- `ubuntu-xenial-x86_64-gcc8-noopenssl`
- `ubuntu-xenial-x86_64-gcc8-noshared`
- `ubuntu-bionic-x86_64`
You may receive an error "Failed uploading test results directory" when running CircleCI locally, that is expected behaviour.
Documentation
-------------

View File

@ -1,13 +0,0 @@
@echo off
REM compares KAT files for Windows-enabled KEM algs
for /R src\kem\ %%K in (*.kat) DO (
if exist kat_kem_rsp\%%~nxK (
FC %%K kat_kem_rsp\%%~nxK >nul 2>nul
if errorlevel 1 (
echo %%~nxK not matching
exit /b 1
)
)
)

View File

@ -12,24 +12,30 @@ branches:
- /.*nist.*/
- /master-new-.*/
init:
- set PATH="C:\\Python37";"C:\\Python37\Scripts";%PATH%
configuration:
- Debug
- DebugDLL
- Release
- ReleaseDLL
before_test:
- cmd: >-
python -m pip install pytest pytest-xdist
mkdir %APPVEYOR_BUILD_FOLDER%\test-results\pytest
test_script:
- cmd: >-
%APPVEYOR_BUILD_FOLDER%\VisualStudio\%PLATFORM%\%CONFIGURATION%\test_kem.exe
cd %APPVEYOR_BUILD_FOLDER%
%APPVEYOR_BUILD_FOLDER%\VisualStudio\%PLATFORM%\%CONFIGURATION%\test_sig.exe
python -m pytest --verbose --numprocesses=auto --junitxml=test-results\pytest\results.xml
%APPVEYOR_BUILD_FOLDER%\VisualStudio\%PLATFORM%\%CONFIGURATION%\example_kem.exe
after_test:
- ps: >-
$wc = New-Object 'System.Net.WebClient'
%APPVEYOR_BUILD_FOLDER%\VisualStudio\%PLATFORM%\%CONFIGURATION%\kat_kem.exe
%APPVEYOR_BUILD_FOLDER%\VisualStudio\kat-check.bat
%APPVEYOR_BUILD_FOLDER%\VisualStudio\%PLATFORM%\%CONFIGURATION%\speed_kem.exe
%APPVEYOR_BUILD_FOLDER%\VisualStudio\%PLATFORM%\%CONFIGURATION%\speed_sig.exe
$wc.UploadFile("https://ci.appveyor.com/api/testresults/xunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\test-results\pytest\results.xml))

View File

@ -7,7 +7,42 @@ set -e
CHOST=arm-linux-gnueabi
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/example_kem
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE1-L1
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE1-L3
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE1-L5
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE2-L1
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE2-L3
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE2-L5
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE3-L1
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE3-L3
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem BIKE3-L5
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Kyber512
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Kyber768
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Kyber1024
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem NewHope-512-CCA
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem NewHope-1024-CCA
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem NTRU-HPS-2048-509
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem NTRU-HPS-2048-677
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem NTRU-HPS-4096-821
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem NTRU-HRSS-701
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem LightSaber-KEM
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Saber-KEM
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem FireSaber-KEM
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem FrodoKEM-640-AES
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem FrodoKEM-640-SHAKE
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem FrodoKEM-976-AES
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem FrodoKEM-976-SHAKE
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem FrodoKEM-1344-AES
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem FrodoKEM-1344-SHAKE
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Sidh-p434
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Sidh-p503
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Sidh-p610
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Sidh-p751
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Sike-p434
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Sike-p503
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Sike-p610
qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_kem Sike-p751
# qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/example_sig
# qemu-arm -cpu cortex-a8 -L /usr/arm-linux-gnueabi tests/test_sig

View File

@ -1,72 +0,0 @@
#!/bin/bash
###
# Checks that all generated KATs match their upstream values.
###
PRINT_GREEN="tput setaf 2"
PRINT_RED="tput setaf 1"
PRINT_RESET="tput sgr 0"
PRINT_YELLOW="tput setaf 3"
RET=0
ALGS=$(grep -E 'define OQS_(KEM|SIG)_alg_' src/kem/kem.h src/sig/sig.h | grep -v 'default' | grep -v 'sidh' | sed -e 's/^[^"]*"//' | sed -e 's/".*$//' | tr -d '[:blank:]')
for alg in ${ALGS}; do
kat=$(find kat_*_rsp -name ${alg}.kat |tr '\n' ' ')
if [ -z "${kat}" ];
then
${PRINT_YELLOW}
echo "KAT file not generated for ${alg}"
${PRINT_RESET}
RET=0
continue
fi
origs=$(find src -name ${alg}.kat -o -name ${alg}.*.kat |tr '\n' ' ')
if [[ "x${origs}x" == "xx" ]];
then
${PRINT_RED}
echo "No original KAT file found for ${alg}"
${PRINT_RESET}
RET=1
continue
fi
match=0
for orig in ${origs}; do
diff ${orig} ${kat} > /dev/null 2>&1
error=$?
if [ $error -eq 0 ]
then
echo "KAT values match for ${alg} and ${orig}"
match=1
break
elif [ ! $error -eq 1 ]
then
${PRINT_RED}
echo "An error occurred in the diff command"
${PRINT_RESET}
RET=1
fi
done
if [ $match -eq 0 ]
then
${PRINT_RED}
echo "KAT values do not match for ${alg} with any of ${origs}"
${PRINT_RESET}
RET=1
fi
done
if [[ "${RET}" == "0" ]];
then
${PRINT_GREEN}
echo "All KAT values matched.";
${PRINT_RESET}
fi
exit ${RET}

View File

@ -11,6 +11,7 @@
#define CPU_H
#include <stdbool.h>
#include "oqs_picnic_macros.h"
/* CPU supports SSE2 */
#define CPU_CAP_SSE2 0x00000001

View File

@ -27,6 +27,7 @@
#define bitstream_put_bits_8 oqs_sig_picnic_bitstream_put_bits_8
#define buildMerkleTree oqs_sig_picnic_buildMerkleTree
#define copyShares oqs_sig_picnic_copyShares
#define cpu_supports oqs_sig_picnic_cpu_supports
#define createTree oqs_sig_picnic_createTree
#define freeCommitments oqs_sig_picnic_freeCommitments
#define freeCommitments2 oqs_sig_picnic_freeCommitments2
@ -196,6 +197,8 @@
#define mzd_xor_uint64_960 oqs_sig_picnic_mzd_xor_uint64_960
#define openMerkleTree oqs_sig_picnic_openMerkleTree
#define openMerkleTreeSize oqs_sig_picnic_openMerkleTreeSize
#define reconstructSeeds oqs_sig_picnic_reconstructSeeds
#define reconstructShares oqs_sig_picnic_reconstructShares
#define revealSeeds oqs_sig_picnic_revealSeeds
#define revealSeedsSize oqs_sig_picnic_revealSeedsSize
#define sbox_layer_10_uint64_aux oqs_sig_picnic_sbox_layer_10_uint64_aux

View File

@ -1,27 +1,9 @@
import functools
import os
import os.path
import pytest
import subprocess
# subprocess.run is not defined on older versions of Python that are present on our test platform
# so we need to supply our own backport
# see https://stackoverflow.com/a/40590445
def run(*popenargs, input=None, check=False, **kwargs):
if input is not None:
if 'stdin' in kwargs:
raise ValueError('stdin and input arguments may not both be used.')
kwargs['stdin'] = subprocess.PIPE
process = subprocess.Popen(*popenargs, **kwargs)
try:
stdout, stderr = process.communicate(input)
except:
process.kill()
process.wait()
raise
retcode = process.poll()
if check and retcode:
raise subprocess.CalledProcessError(
retcode, process.args, output=stdout, stderr=stderr)
return retcode, stdout, stderr
import sys
def run_subprocess(command, working_dir='.', env=None, expected_returncode=0, input=None):
"""
@ -34,10 +16,10 @@ def run_subprocess(command, working_dir='.', env=None, expected_returncode=0, in
env = env_
# Note we need to capture stdout/stderr from the subprocess,
# then print it, which nose/unittest will then capture and
# then print it, which pytest will then capture and
# buffer appropriately
print(working_dir + " > " + " ".join(command))
retcode, stdout, stderr = run(
result = subprocess.run(
command,
input=input,
stdout=subprocess.PIPE,
@ -45,6 +27,107 @@ def run_subprocess(command, working_dir='.', env=None, expected_returncode=0, in
cwd=working_dir,
env=env,
)
print(stdout.decode('utf-8'))
assert retcode == expected_returncode, "Got unexpected return code {}".format(retcode)
return stdout.decode('utf-8')
if result.returncode != expected_returncode:
print(result.stdout.decode('utf-8'))
assert False, "Got unexpected return code {}".format(result.returncode)
return result.stdout.decode('utf-8')
def available_kems_by_name():
available_names = []
with open(os.path.join('src', 'kem', 'kem.h')) as fh:
for line in fh:
if line.startswith("#define OQS_KEM_alg_"):
kem_name = line.split(' ')[2]
kem_name = kem_name[1:-2]
if kem_name != "DEFAULT":
available_names.append(kem_name)
return available_names
def is_kem_enabled_by_name(name):
symbol = None
with open(os.path.join('src', 'kem', 'kem.h')) as fh:
for line in fh:
if line.startswith("#define OQS_KEM_alg_"):
kem_symbol = line.split(' ')[1]
kem_symbol = kem_symbol[len("OQS_KEM_alg_"):]
kem_name = line.split(' ')[2]
kem_name = kem_name[1:-2]
if kem_name == name:
symbol = kem_symbol
break
if symbol == None: return False
if sys.platform.startswith("win"):
header = os.path.join('VisualStudio', 'winconfig.h')
else:
header = os.path.join('include', 'oqs', 'oqsconfig.h')
with open(header) as fh:
for line in fh:
if line.startswith("#define OQS_ENABLE_KEM_"):
kem_symbol = line.split(' ')[1]
kem_symbol = kem_symbol[len("OQS_ENABLE_KEM_"):].rstrip()
if kem_symbol == symbol:
return True
return False
def available_sigs_by_name():
available_names = []
with open(os.path.join('src', 'sig', 'sig.h')) as fh:
for line in fh:
if line.startswith("#define OQS_SIG_alg_"):
sig_name = line.split(' ')[2]
sig_name = sig_name[1:-2]
if sig_name != "DEFAULT":
available_names.append(sig_name)
return available_names
def is_sig_enabled_by_name(name):
symbol = None
with open(os.path.join('src', 'sig', 'sig.h')) as fh:
for line in fh:
if line.startswith("#define OQS_SIG_alg_"):
sig_symbol = line.split(' ')[1]
sig_symbol = sig_symbol[len("OQS_SIG_alg_"):]
sig_name = line.split(' ')[2]
sig_name = sig_name[1:-2]
if sig_name == name:
symbol = sig_symbol
break
if symbol == None: return False
if sys.platform.startswith("win"):
header = os.path.join('VisualStudio', 'winconfig.h')
else:
header = os.path.join('include', 'oqs', 'oqsconfig.h')
with open(header) as fh:
for line in fh:
if line.startswith("#define OQS_ENABLE_SIG_"):
sig_symbol = line.split(' ')[1]
sig_symbol = sig_symbol[len("OQS_ENABLE_SIG_"):].rstrip()
if sig_symbol == symbol:
return True
return False
def filtered_test(func):
funcname = func.__name__[len("test_"):]
@functools.wraps(func)
def wrapper(*args, **kwargs):
if ('SKIP_TESTS' in os.environ) and (funcname in os.environ['SKIP_TESTS'].lower().split(',')):
pytest.skip("Test disabled by filter")
else:
return func(*args, **kwargs)
return wrapper
def path_to_executable(program_name):
if sys.platform.startswith("win"):
if 'APPVEYOR_BUILD_FOLDER' not in os.environ: os.environ['APPVEYOR_BUILD_FOLDER'] = "."
if 'PLATFORM' not in os.environ: os.environ['PLATFORM'] = "x64"
if 'CONFIGURATION' not in os.environ: os.environ['CONFIGURATION'] = "Debug"
return os.path.join(
os.environ['APPVEYOR_BUILD_FOLDER'],
'VisualStudio',
os.environ['PLATFORM'],
os.environ['CONFIGURATION'],
program_name + ".EXE"
)
else:
return os.path.join("tests", program_name)

View File

@ -40,7 +40,6 @@ OQS_STATUS kem_kat(const char *method_name) {
uint8_t *ciphertext = NULL;
uint8_t *shared_secret_e = NULL;
uint8_t *shared_secret_d = NULL;
char filename[200];
OQS_STATUS rc, ret = OQS_ERROR;
int rv;
@ -60,12 +59,7 @@ OQS_STATUS kem_kat(const char *method_name) {
}
OQS_randombytes_nist_kat_init(entropy_input, NULL, 256);
sprintf(filename, "kat_kem_rsp/%s.kat", method_name);
fh = fopen(filename, "w");
if (fh == NULL) {
goto err;
}
fh = stdout;
fprintf(fh, "count = 0\n");
OQS_randombytes(seed, 48);
@ -123,9 +117,6 @@ algo_not_enabled:
ret = OQS_SUCCESS;
cleanup:
if (fh != NULL) {
fclose(fh);
}
if (kem != NULL) {
OQS_MEM_secure_free(secret_key, kem->length_secret_key);
OQS_MEM_secure_free(shared_secret_e, kem->length_shared_secret);
@ -137,27 +128,25 @@ cleanup:
return ret;
}
int main() {
int main(int argc, char **argv) {
int ret = EXIT_SUCCESS;
OQS_STATUS rc;
int status;
#if defined(_WIN32)
status = _mkdir("kat_kem_rsp");
#else
status = mkdir("kat_kem_rsp", S_IRWXU);
#endif
if (!((status == 0) || (errno == EEXIST))) {
if (argc != 2) {
fprintf(stderr, "Usage: kat_kem algname\n");
fprintf(stderr, " algname: ");
for (size_t i = 0; i < OQS_KEM_algs_length; i++) {
if (i > 0) {
fprintf(stderr, ", ");
}
fprintf(stderr, "%s", OQS_KEM_alg_identifier(i));
}
fprintf(stderr, "\n");
return EXIT_FAILURE;
}
for (size_t i = 0; i < OQS_KEM_algs_length; i++) {
rc = kem_kat(OQS_KEM_alg_identifier(i));
if (rc != OQS_SUCCESS) {
ret = EXIT_FAILURE;
}
char *alg_name = argv[1];
OQS_STATUS rc = kem_kat(alg_name);
if (rc != OQS_SUCCESS) {
return EXIT_FAILURE;
}
return ret;
return EXIT_SUCCESS;
}

35
tests/test_cmdline.py Normal file
View File

@ -0,0 +1,35 @@
import helpers
import os
import pytest
import sys
@helpers.filtered_test
@pytest.mark.parametrize('program', ['example_kem', 'example_sig'])
def test_examples(program):
helpers.run_subprocess(
[helpers.path_to_executable(program)],
)
@helpers.filtered_test
@pytest.mark.parametrize('kem_name', helpers.available_kems_by_name())
def test_kem(kem_name):
if not(helpers.is_kem_enabled_by_name(kem_name)): pytest.skip('Not enabled')
helpers.run_subprocess(
[helpers.path_to_executable('test_kem'), kem_name],
)
@helpers.filtered_test
@pytest.mark.parametrize('sig_name', helpers.available_sigs_by_name())
def test_sig(sig_name):
if not(helpers.is_sig_enabled_by_name(sig_name)): pytest.skip('Not enabled')
if sys.platform.startswith("win") and 'APPVEYOR' in os.environ:
if 'SPHINCS' in sig_name and ('192f' in sig_name or '192s' in sig_name or '256f' in sig_name or '256s' in sig_name):
pytest.skip('Skipping SPHINCS+ 192s and 256s tests on Windows AppVeyor builds')
helpers.run_subprocess(
[helpers.path_to_executable('test_sig'), sig_name],
)
if __name__ == "__main__":
import sys
pytest.main(sys.argv)

View File

@ -0,0 +1,31 @@
import helpers
import pytest
import sys
@helpers.filtered_test
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not needed on Windows")
@pytest.mark.parametrize('kem_name', helpers.available_kems_by_name())
def test_datasheet_kem(kem_name):
helpers.run_subprocess(
['grep', '-r', kem_name, 'docs/algorithms']
)
@helpers.filtered_test
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not needed on Windows")
@pytest.mark.parametrize('sig_name', helpers.available_sigs_by_name())
def test_datasheet_sig(sig_name):
helpers.run_subprocess(
['grep', '-r', sig_name, 'docs/algorithms']
)
@helpers.filtered_test
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not needed on Windows")
def test_doxygen():
helpers.run_subprocess(
['make', 'docs']
)
if __name__ == "__main__":
import sys
pytest.main(sys.argv)

View File

@ -1,27 +1,48 @@
import hashlib
import helpers
import pytest
import sys
@helpers.filtered_test
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
def test_aes():
helpers.run_subprocess(
[helpers.path_to_executable('test_aes')],
)
@helpers.filtered_test
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
def test_sha3():
helpers.run_subprocess(
[helpers.path_to_executable('test_sha3')],
)
@helpers.filtered_test
@pytest.mark.parametrize('msg', ['', 'a', 'abc', '1234567890123456789012345678901678901567890'])
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
def test_sha256(msg):
output = helpers.run_subprocess(
['tests/test_hash', 'sha256'],
[helpers.path_to_executable('test_hash'), 'sha256'],
input = msg.encode(),
)
assert(output.rstrip() == hashlib.sha256(msg.encode()).hexdigest())
@helpers.filtered_test
@pytest.mark.parametrize('msg', ['', 'a', 'abc', '1234567890123456789012345678901678901567890'])
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
def test_sha384(msg):
output = helpers.run_subprocess(
['tests/test_hash', 'sha384'],
[helpers.path_to_executable('test_hash'), 'sha384'],
input = msg.encode(),
)
assert(output.rstrip() == hashlib.sha384(msg.encode()).hexdigest())
@helpers.filtered_test
@pytest.mark.parametrize('msg', ['', 'a', 'abc', '1234567890123456789012345678901678901567890'])
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
def test_sha512(msg):
output = helpers.run_subprocess(
['tests/test_hash', 'sha512'],
[helpers.path_to_executable('test_hash'), 'sha512'],
input = msg.encode(),
)
assert(output.rstrip() == hashlib.sha512(msg.encode()).hexdigest())

25
tests/test_kat.py Normal file
View File

@ -0,0 +1,25 @@
import helpers
import os
import os.path
import pytest
@helpers.filtered_test
@pytest.mark.parametrize('kem_name', helpers.available_kems_by_name())
def test_kem(kem_name):
if kem_name.startswith('Sidh'): pytest.skip('KATs not available for SIDH')
if not(helpers.is_kem_enabled_by_name(kem_name)): pytest.skip('Not enabled')
output = helpers.run_subprocess(
[helpers.path_to_executable('kat_kem'), kem_name],
)
output = output.replace("\r\n", "\n")
kats = []
for filename in os.listdir(os.path.join('tests', 'KATs', 'kem')):
if filename.startswith(kem_name + '.') and filename.endswith('.kat'):
with open(os.path.join('tests', 'KATs', 'kem', filename), 'r') as myfile:
kats.append(myfile.read())
assert(output in kats)
if __name__ == "__main__":
import sys
pytest.main(sys.argv)

View File

@ -120,20 +120,28 @@ cleanup:
return ret;
}
int main() {
int main(int argc, char **argv) {
int ret = EXIT_SUCCESS;
OQS_STATUS rc;
if (argc != 2) {
fprintf(stderr, "Usage: test_kem algname\n");
fprintf(stderr, " algname: ");
for (size_t i = 0; i < OQS_KEM_algs_length; i++) {
if (i > 0) {
fprintf(stderr, ", ");
}
fprintf(stderr, "%s", OQS_KEM_alg_identifier(i));
}
fprintf(stderr, "\n");
return EXIT_FAILURE;
}
// Use system RNG in this program
OQS_randombytes_switch_algorithm(OQS_RAND_alg_system);
for (size_t i = 0; i < OQS_KEM_algs_length; i++) {
rc = kem_test_correctness(OQS_KEM_alg_identifier(i));
if (rc != OQS_SUCCESS) {
ret = EXIT_FAILURE;
}
char *alg_name = argv[1];
OQS_STATUS rc = kem_test_correctness(alg_name);
if (rc != OQS_SUCCESS) {
return EXIT_FAILURE;
}
return ret;
return EXIT_SUCCESS;
}

26
tests/test_lint.py Normal file
View File

@ -0,0 +1,26 @@
import helpers
import pytest
import sys
###
# Checks that "free" is not used unprotected in the main OQS code.
###
@helpers.filtered_test
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not needed on Windows")
def test_free():
files = helpers.run_subprocess(['find', 'src', '-name', '*.c'])
files = helpers.run_subprocess(['grep', '-v', 'picnic/external'], input=files.encode('utf8'))
lines = helpers.run_subprocess(['xargs', 'grep', '[^_]free('], input=files.encode('utf8'))
lines = lines.split("\n")
okay = True
for line in lines:
if line == "": continue
if not('IGNORE free-check' in line):
okay = False
print("Suspicious `free` in " + line)
assert okay, "'free' is used in some files. These should be changed to 'OQS_MEM_secure_free' or 'OQS_MEM_insecure_free' as appropriate. If you are sure you want to use 'free' in a particular spot, add the comment '// IGNORE free-check' on the line where 'free' occurs."
if __name__ == "__main__":
import sys
pytest.main(sys.argv)

44
tests/test_namespace.py Normal file
View File

@ -0,0 +1,44 @@
import helpers
import pytest
import sys
# Check if liboqs contains any non-namespaced global symbols
# See https://github.com/open-quantum-safe/liboqs/wiki/Coding-conventions for function naming conventions
@helpers.filtered_test
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not needed on Windows")
def test_namespace():
out = helpers.run_subprocess(
['nm', '-g', '.libs/liboqs.a']
)
lines = out.strip().split("\n")
symbols = []
for line in lines:
if ' T ' in line or ' D ' in line or ' S ' in line:
symbols.append(line)
# ideally this would be just ['oqs', 'pqclean'] but the Picnic implementation has a few more symbols
namespaces = ['oqs', 'pqclean', 'keccak', 'picnic', 'aligned_alloc', 'aligned_free']
non_namespaced = []
for symbolstr in symbols:
*_, symtype, symbol = symbolstr.split()
if symtype in 'TR':
is_namespaced = False
for namespace in namespaces:
if symbol.lower().startswith(namespace) or symbol.lower().startswith('_' + namespace):
is_namespaced = True
if not(is_namespaced):
non_namespaced.append(symbol)
if len(non_namespaced) > 0:
for symbol in non_namespaced:
print("Non-namespaced symbol: {}".format(symbol))
assert(len(non_namespaced) == 0)
if __name__ == "__main__":
import sys
pytest.main(sys.argv)

View File

@ -84,19 +84,28 @@ cleanup:
return ret;
}
int main() {
int ret = EXIT_SUCCESS;
OQS_STATUS rc;
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: test_sig algname\n");
fprintf(stderr, " algname: ");
for (size_t i = 0; i < OQS_SIG_algs_length; i++) {
if (i > 0) {
fprintf(stderr, ", ");
}
fprintf(stderr, "%s", OQS_SIG_alg_identifier(i));
}
fprintf(stderr, "\n");
return EXIT_FAILURE;
}
// Use system RNG in this program
OQS_randombytes_switch_algorithm(OQS_RAND_alg_system);
for (size_t i = 0; i < OQS_SIG_algs_length; i++) {
rc = sig_test_correctness(OQS_SIG_alg_identifier(i));
if (rc != OQS_SUCCESS) {
ret = EXIT_FAILURE;
}
char *alg_name = argv[1];
OQS_STATUS rc = sig_test_correctness(alg_name);
if (rc != OQS_SUCCESS) {
return EXIT_FAILURE;
}
return ret;
return EXIT_SUCCESS;
}

51
tests/test_style.py Normal file
View File

@ -0,0 +1,51 @@
import helpers
import pytest
import sys
@helpers.filtered_test
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not needed on Windows")
def test_style():
modified_files = helpers.run_subprocess(
['git', 'status', '-s']
)
if (modified_files != ""):
print(modified_files)
assert False, "There are modified files present in the directory prior to prettyprint check. This may indicate that some files should be added to .gitignore or need to be committed."
clang_formats = ['/usr/local/Cellar/clang-format/2016-06-27/bin/clang-format', 'clang-format-3.9', 'clang-format']
found_clang_format = None
for clang_format in clang_formats:
try:
helpers.run_subprocess(
[clang_format, '/dev/null'],
)
found_clang_format = clang_format
break
except:
pass
finally:
pass
assert found_clang_format != None, 'No clang-format found'
version = helpers.run_subprocess(
[found_clang_format, '-version']
)
assert 'version 3.9' in version, 'Invalid clang-format version (' + version + ')'
helpers.run_subprocess(
['make', 'prettyprint'],
env = {'CLANGFORMAT': found_clang_format},
)
modified_files = helpers.run_subprocess(
['git', 'status', '-s']
)
if (modified_files != ""):
print(modified_files)
assert False, "Some files do not adhere to project style standards. See the last list of files below `git status -s`"
if __name__ == "__main__":
import sys
pytest.main(sys.argv)