Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update testing versions #86

Merged
merged 7 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/python-ci-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: stix-validator test harness
on: [push, pull_request]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', '3.11', '3.12']

name: Python ${{ matrix.python-version }} Build
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install and update essential dependencies
run: |
pip install -U pip setuptools
pip install tox-gh-actions
- name: Test with Tox
run: |
tox
28 changes: 0 additions & 28 deletions .travis.yml

This file was deleted.

9 changes: 4 additions & 5 deletions sdv/scripts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

# external
import lxml.etree
from mixbox.vendor.six import iteritems, itervalues

# internal
import sdv
Expand Down Expand Up @@ -290,7 +289,7 @@ def print_profile_results(results, level):
for e in results.errors:
errors_[e.message].append(e.line)

for msg, lines in iteritems(errors_):
for msg, lines in errors_.items():
lines = ', '.join(str(x) for x in lines)
print_level("[!] %s [%s]", level+1, msg, lines)

Expand All @@ -303,7 +302,7 @@ def print_json_results(results):
results to print.
"""
json_results = {}
for fn, result in iteritems(results):
for fn, result in results.items():
d = {}
if result.schema_results is not None:
d['schema validation'] = result.schema_results.as_dict()
Expand Down Expand Up @@ -335,7 +334,7 @@ def print_results(results, options):
return

level = 0
for fn, result in sorted(iteritems(results)):
for fn, result in sorted(results.items()):
print("=" * 80)
print_level("[-] Results: %s", level, fn)

Expand Down Expand Up @@ -511,7 +510,7 @@ def status_code(results):
"""
status = codes.EXIT_SUCCESS

for result in itervalues(results):
for result in results.values():
schema = result.schema_results
best_practice = result.best_practice_results
profile = result.profile_results
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from io import StringIO
import unittest
from mixbox.vendor.six import StringIO

import sdv
import sdv.errors as errors
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from io import StringIO
import json
import unittest
from mixbox.vendor.six import StringIO

from lxml import etree

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from io import StringIO
import unittest
from mixbox.vendor.six import StringIO

import sdv
import sdv.errors as errors
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from io import StringIO
import unittest
from mixbox.vendor.six import StringIO

import sdv
import sdv.errors as errors
Expand Down
4 changes: 2 additions & 2 deletions sdv/test/utils_tests.py → sdv/test/utils_test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from io import StringIO
import unittest
import datetime
from mixbox.vendor.six import StringIO

from lxml import etree
import dateutil.parser
Expand Down Expand Up @@ -146,4 +146,4 @@ def test_is_qname(self):
self.assertTrue(utils.is_qname(s))

for s in invalid:
self.assertEqual(False, utils.is_qname(s), msg=s)
self.assertEqual(False, utils.is_qname(s), msg=s)
4 changes: 2 additions & 2 deletions sdv/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
import contextlib
import datetime
from distutils.version import StrictVersion
from io import StringIO, BytesIO

# external
import dateutil.parser
from lxml import etree
from mixbox.vendor.six import StringIO, BytesIO

# relative
from . import errors, xmlconst
Expand Down Expand Up @@ -500,4 +500,4 @@ def remove_version_prefix(version):
"""
if version.startswith('stix-'):
version = version.partition('stix-')[2]
return version
return version
7 changes: 2 additions & 5 deletions sdv/validators/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
import abc
import json

# external
from mixbox.vendor.six import iteritems

# internal
from .. import utils

Expand Down Expand Up @@ -93,7 +90,7 @@ def _get_validators(self, schema_dir=None):
self._KEY_USER_DEFINED: self._get_validator_impl(schema_dir)
}
else:
for version, location in iteritems(self._SCHEMAS):
for version, location in self._SCHEMAS.items():
validator = self._get_validator_impl(location)
validators[version] = validator

Expand Down Expand Up @@ -148,4 +145,4 @@ def _validate(self, doc, version=None, schemaloc=False):
'ValidationError',
'ValidationResults',
'BaseSchemaValidator'
]
]
43 changes: 17 additions & 26 deletions sdv/validators/stix/best_practice.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
import re
import itertools
import collections
import distutils.version
from packaging.version import parse as parse_version

# external
from lxml import etree
from mixbox.vendor.six import iteritems, itervalues, with_metaclass
from mixbox import compat

# internal
from sdv import utils, xmlconst
Expand All @@ -21,13 +19,6 @@
from ...utils import remove_version_prefix


# Python 2.6 doesn't have collections.OrderedDict :(
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict


# STIX ID Format: [ns prefix]:[construct type]-[GUID]
# Note: This will validate invalid QNames, so this should be used with a
# QName format check.
Expand Down Expand Up @@ -62,7 +53,7 @@ def __new__(metacls, name, bases, dict_):
ruledict = collections.defaultdict(list)

# Find all @rule marked functions in the class dict_
rulefuncs = (x for x in itervalues(dict_) if hasattr(x, 'is_rule'))
rulefuncs = (x for x in dict_.values() if hasattr(x, 'is_rule'))

# Build the rule function dict.
for rule in rulefuncs:
Expand All @@ -74,7 +65,7 @@ def __new__(metacls, name, bases, dict_):
return obj


class BestPracticeWarning(compat.MutableMapping, base.ValidationError):
class BestPracticeWarning(collections.abc.MutableMapping, base.ValidationError):
"""Represents a best practice warning. These are built within best
practice rule checking methods and attached to
:class:`BestPracticeWarningCollection` instances.
Expand Down Expand Up @@ -102,7 +93,7 @@ class BestPracticeWarning(compat.MutableMapping, base.ValidationError):
def __init__(self, node, message=None):
base.ValidationError.__init__(self)

self._inner = OrderedDict()
self._inner = collections.OrderedDict()
self._node = node

self['line'] = node.sourceline
Expand Down Expand Up @@ -185,10 +176,10 @@ def as_dict(self):
necessary.

"""
return dict(iteritems(self))
return dict(self.items())


class BestPracticeWarningCollection(compat.MutableSequence):
class BestPracticeWarningCollection(collections.abc.MutableSequence):
"""A collection of :class:`BestPracticeWarning` instances for a given
type of STIX Best Practice.

Expand Down Expand Up @@ -257,7 +248,7 @@ def as_dict(self):
return {self.name: [x.as_dict() for x in self]}


class BestPracticeValidationResults(base.ValidationResults, compat.MutableSequence):
class BestPracticeValidationResults(base.ValidationResults, collections.abc.MutableSequence):
"""Represents STIX best practice validation results. This class behaves
like a ``list`` and accepts instances of
:class:`BestPracticeWarningCollection`.
Expand Down Expand Up @@ -338,7 +329,7 @@ def as_dict(self):
return d


class STIXBestPracticeValidator(with_metaclass(BestPracticeMeta, object)):
class STIXBestPracticeValidator(object, metaclass=BestPracticeMeta):
"""Performs STIX Best Practice validation."""

@rule('1.0')
Expand Down Expand Up @@ -449,7 +440,7 @@ def _check_1_2_duplicate_ids(self, root, namespaces, version): # noqa
idnodes[node.attrib.get('id')].append(node)

# Find all nodes that have duplicate IDs
dups = [x for x in itervalues(idnodes) if len(x) > 1]
dups = [x for x in idnodes.values() if len(x) > 1]

# Build warnings for all nodes that have conflicting id/timestamp pairs.
for nodeset in dups:
Expand All @@ -469,7 +460,7 @@ def _check_1_0_duplicate_ids(self, root, namespaces, version): # noqa
id_nodes[node.attrib['id']].append(node)

results = BestPracticeWarningCollection('Duplicate IDs')
for nodes in itervalues(id_nodes):
for nodes in id_nodes.values():
if len(nodes) > 1:
results.extend(BestPracticeWarning(node=x) for x in nodes)

Expand Down Expand Up @@ -611,7 +602,7 @@ def _is_expected(node, expected):
return True
return node.attrib['version'] == expected

for selector, expected in iteritems(to_check):
for selector, expected in to_check.items():
xpath = "//%s" % selector

for node in root.xpath(xpath, namespaces=namespaces):
Expand Down Expand Up @@ -1124,7 +1115,7 @@ def can_inspect(node):

warns = []
seen = set()

for node in filtered:
o = node.attrib.get('ordinality')

Expand Down Expand Up @@ -1192,17 +1183,17 @@ def can_run(stix_version, rule_min, rule_max):
if not rule_min:
return True

doc_ver = StrictVersion(remove_version_prefix(stix_version))
min_ver = StrictVersion(remove_version_prefix(rule_min))
doc_ver = parse_version(remove_version_prefix(stix_version))
min_ver = parse_version(remove_version_prefix(rule_min))

if rule_max:
max_ver = StrictVersion(remove_version_prefix(rule_max))
max_ver = parse_version(remove_version_prefix(rule_max))
return (min_ver <= doc_ver <= max_ver)

return min_ver <= doc_ver

StrictVersion = distutils.version.StrictVersion
all_rules = iteritems(self._rules) # noqa
#StrictVersion = distutils.version.StrictVersion
all_rules = self._rules.items() # noqa

# Get a generator which yields all best practice methods that are
# assigned a version number <= the input STIX document version number.
Expand Down
9 changes: 5 additions & 4 deletions sdv/validators/stix/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
# builtin
import re
import functools
from distutils.version import StrictVersion
# from distutils.version import StrictVersion
from packaging.version import parse as parse_version

# external
from lxml import etree
Expand Down Expand Up @@ -284,7 +285,7 @@ def is_idref_content_exception(node):

def _get_cybox_vocab_version(name, version):
versions = CYBOX_VOCAB_VERSIONS
descending = sorted(versions, key=StrictVersion, reverse=True)
descending = sorted(versions, key=parse_version, reverse=True)
idx = descending.index

for key in descending[idx(version):]:
Expand All @@ -301,7 +302,7 @@ def _get_cybox_vocab_version(name, version):
def _get_stix_vocab_version(name, version):
versions = STIX_VOCAB_VERSIONS
descending = sorted(versions, key=lambda v:
StrictVersion(utils.remove_version_prefix(v)), reverse=True)
parse_version(utils.remove_version_prefix(v)), reverse=True)
idx = descending.index

for key in descending[idx(version):]:
Expand Down Expand Up @@ -451,7 +452,7 @@ def get_stix_namespaces(version):
found=version
)

if StrictVersion(utils.remove_version_prefix(version)) < '1.2.1':
if parse_version(utils.remove_version_prefix(version)) < parse_version('1.2.1'):
nsmap = {
PREFIX_XSI: xmlconst.NS_XSI,
PREFIX_STIX_CORE: 'http://stix.mitre.org/stix-1',
Expand Down
Loading