From c0191cdf1e11e6b496962de82312f17c6bfa07ac Mon Sep 17 00:00:00 2001 From: Tom Forbes Date: Thu, 6 Sep 2018 20:00:42 +0100 Subject: [PATCH] Update test coverage and add failing vector to tests. #4 --- .travis.yml | 11 +++- setup.py | 15 +---- test_requirements.txt | 3 +- tests/files/vectors_simple3 | 1 + tests/test_vector.py | 106 ++++++++++++++++++++---------------- 5 files changed, 70 insertions(+), 66 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2577741..1971916 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,20 @@ language: python python: - - "3.3" - - "3.4" - "3.5" + - "3.6" - "pypy3" +env: + - DJANGO=1.11.0 + - DJANGO=2.0.0 + - DJANGO=2.1.0 # command to install dependencies +cache: pip install: - pip install --upgrade pip wheel - pip install -r test_requirements.txt + - pip install django~=$DJANGO - pip install . # command to run tests script: - export PYTHONPATH=./tests/:$PYTHONPATH - - cd tests && py.test . -vv + - cd tests && py.test . -l -n auto diff --git a/setup.py b/setup.py index 6cc47b3..0e88473 100644 --- a/setup.py +++ b/setup.py @@ -1,18 +1,8 @@ from setuptools import setup -import sys - -requirements = [] - -# Enum34 fails in Python 3.5 (and not needed in 3.4), so skip it. -if sys.version_info < (3, 4): - requirements.append("enum34") - -if sys.version_info < (3, 2): - requirements.append("backports.functools_lru_cache") setup( name='cvsslib', - version='0.5.5', + version='0.6.0', packages=['cvsslib', 'cvsslib.cvss2', 'cvsslib.cvss3', 'cvsslib.contrib'], url='https://github.com/ctxis/cvsslib', license='GPL', @@ -21,8 +11,7 @@ description='CVSS 2/3 utilities', long_description='A library for manipulating CVSS v2 and v3 vectors. Visit the github page ' '(https://github.com/ctxis/cvsslib) for examples and documentation.', - install_requires=requirements, - python_requires='>=3', + python_requires='>=3.5', entry_points={ 'console_scripts': ['cvss=cvsslib.command:main'], }, diff --git a/test_requirements.txt b/test_requirements.txt index bb8e39f..4a6aef1 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -1,5 +1,4 @@ -django==1.8.7 django-enumfields -#pytest-pythonpath pytest-django pathlib +pytest-xdist \ No newline at end of file diff --git a/tests/files/vectors_simple3 b/tests/files/vectors_simple3 index 284ecab..d74887e 100644 --- a/tests/files/vectors_simple3 +++ b/tests/files/vectors_simple3 @@ -2590,3 +2590,4 @@ CVSS:3.0/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:L/A:N - (1.6, 1.6, 1.6) CVSS:3.0/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:H - (3.8, 3.8, 3.8) CVSS:3.0/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:L - (1.6, 1.6, 1.6) CVSS:3.0/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:N - (0.0, 0.0, 0.0) +CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H/IR:H - (7.5, 7.5, 7.5) \ No newline at end of file diff --git a/tests/test_vector.py b/tests/test_vector.py index 938246a..e5cde93 100644 --- a/tests/test_vector.py +++ b/tests/test_vector.py @@ -3,7 +3,7 @@ from cvsslib.utils import get_enums from cvsslib.example_vectors import v3_vectors, v2_vectors import pathlib - +import pytest data_dir = pathlib.Path(__file__).parent / "files" @@ -18,68 +18,78 @@ def split_vector(line): return vector, score -def test_v3_vector_files(): - for name in ("vectors_random3", "vectors_simple3"): - with (data_dir / name).open() as fd: - for line in fd: - vector, score = split_vector(line) - - parsed = calculate_vector(vector, cvss3) - assert parsed == score - - -def test_v2_vector_files(): - for name in ("vectors_random2", "vectors_simple2"): - with (data_dir / name).open() as fd: - for line in fd: - vector, score = split_vector(line) +@pytest.mark.parametrize('line', (data_dir / 'vectors_simple3').read_text().splitlines()) +def test_v3_vector_files_simple3(line): + vector, score = split_vector(line) + parsed = calculate_vector(vector, cvss3) + assert parsed == score - parsed = calculate_vector(vector, cvss2) - assert parsed == score +@pytest.mark.parametrize('line', (data_dir / 'vectors_random3').read_text().splitlines()) +def test_v3_vector_files_random3(line): + vector, score = split_vector(line) + parsed = calculate_vector(vector, cvss3) + assert parsed == score -def test_v3_vector(): - for vector, results in v3_vectors: - score = calculate_vector(vector, cvss3) - assert results == score, "Vector {0} failed".format(vector) +@pytest.mark.parametrize('line', (data_dir / 'vectors_random2').read_text().splitlines()) +def test_v3_vector_files_random2(line): + vector, score = split_vector(line) + parsed = calculate_vector(vector, cvss2) + assert parsed == score -def test_v2_vector(): - for vector, results in v2_vectors: - score = calculate_vector(vector, cvss2) +@pytest.mark.parametrize('line', (data_dir / 'vectors_simple2').read_text().splitlines()) +def test_v3_vector_files_random2(line): + vector, score = split_vector(line) + parsed = calculate_vector(vector, cvss2) + assert parsed == score - assert results == score, "Vector {0} failed".format(vector) +@pytest.mark.parametrize('vector, results', v3_vectors) +def test_v3_vector(vector, results): + score = calculate_vector(vector, cvss3) + assert results == score, "Vector {0} failed".format(vector) -def test_cvss_class_mixin(): - # Test that an instance of every enum class is present within each of the state classes - - for cls, module, vectors in [(CVSS2State, cvss2, v2_vectors), (CVSS3State, cvss3, v3_vectors)]: - instance = cls() - enum_classes_in_module = set([x[1] for x in get_enums(module)]) - enum_classes_in_class = set([e[1].__class__ for e in get_enums(instance, only_classes=False)]) +@pytest.mark.parametrize('vector, results', v2_vectors) +def test_v2_vector(vector, results): + score = calculate_vector(vector, cvss2) + assert results == score, "Vector {0} failed".format(vector) - assert enum_classes_in_class == enum_classes_in_module - # For each test vector we parse it into an instance, then output a vector from that instance. - # Then we make a new instance and feed that vector into it, then compare that the resulting calculations - # are all equal. +@pytest.mark.parametrize('vector, expected', v2_vectors) +def test_mixin_vectors_v2(vector, expected): + instance = CVSS2State() + instance.from_vector(vector) + new_vector = instance.to_vector() - for vector, expected in vectors: - instance = cls() - instance.from_vector(vector) + new_instance = CVSS2State() + new_instance.from_vector(new_vector) + assert vector == new_vector + assert new_instance.debug() == instance.debug() + assert instance.calculate() == expected + assert new_instance.calculate() == expected - new_vector = instance.to_vector() - new_instance = cls() - new_instance.from_vector(new_vector) +@pytest.mark.parametrize('vector, expected', v3_vectors) +def test_mixin_vectors_v3(vector, expected): + instance = CVSS3State() + instance.from_vector(vector) + new_vector = instance.to_vector() - assert vector == new_vector + new_instance = CVSS3State() + new_instance.from_vector(new_vector) + assert vector == new_vector + assert new_instance.debug() == instance.debug() + assert instance.calculate() == expected + assert new_instance.calculate() == expected - assert new_instance.debug() == instance.debug() - - assert instance.calculate() == expected - assert new_instance.calculate() == expected +@pytest.mark.parametrize('cls,module', ((CVSS3State, cvss3), (CVSS2State, cvss2))) +def test_cvss_class_mixin(cls, module): + # Test that an instance of every enum class is present within each of the state classes + instance = cls() + enum_classes_in_module = set([x[1] for x in get_enums(module)]) + enum_classes_in_class = set([e[1].__class__ for e in get_enums(instance, only_classes=False)]) + assert enum_classes_in_class == enum_classes_in_module