diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 495bcca..c48ce0e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,4 +23,8 @@ jobs: python -m pip install --upgrade pip wheel python -m pip install tox==4.* tox-gh-actions==3.* - name: Run tox - run: tox \ No newline at end of file + run: tox + - name: System test + env: + SC_GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + run: .test/system-test/system_test.sh diff --git a/src/security_constraints/common.py b/src/security_constraints/common.py index f41f17f..971a5e6 100644 --- a/src/security_constraints/common.py +++ b/src/security_constraints/common.py @@ -1,4 +1,6 @@ """This module contains common definitions for use in any other module.""" +from __future__ import annotations + import abc import argparse import dataclasses @@ -17,15 +19,14 @@ get_type_hints, ) -if sys.version_info >= (3, 11): - from typing import Self # pragma: no cover (=py311) - - if TYPE_CHECKING: # pragma: no cover from typing import TypedDict + if sys.version_info >= (3, 11): + from typing import Self # pragma: no cover (=py311) + class _ConfigurationKwargs(TypedDict, total=False): ignore_ids: Set[str] min_severity: "SeverityLevel" @@ -40,7 +41,7 @@ class SeverityLevel(str, enum.Enum): LOW = "LOW" @classmethod - def _missing_(cls: Type[Self], value: object) -> Optional[Self]: + def _missing_(cls, value: object) -> Optional[Self]: # Makes instantiation case-insensitive if isinstance(value, str): for member in cls: @@ -48,7 +49,7 @@ def _missing_(cls: Type[Self], value: object) -> Optional[Self]: return member return None - def get_higher_or_equal_severities(self: Self) -> Set[Self]: + def get_higher_or_equal_severities(self) -> Set[Self]: """Get a set containing this SeverityLevel and all higher ones.""" return { type(self)(value) @@ -110,7 +111,7 @@ class ArgumentNamespace(argparse.Namespace): def __setattr__(self, key: str, value: Any) -> None: # Makes it so that no attributes except those type hinted above can be set. - if key not in get_type_hints(self): + if key not in self.__annotations__: #get_type_hints(self): raise AttributeError(f"No attribute named '{key}'") super().__setattr__(key, value) diff --git a/test/system_test/sc-conf.yaml b/test/system_test/sc-conf.yaml new file mode 100644 index 0000000..0463a1a --- /dev/null +++ b/test/system_test/sc-conf.yaml @@ -0,0 +1,2 @@ +ignore_ids: + - "GHSA-8r8j-xvfj-36f9" diff --git a/test/system_test/system_test.sh b/test/system_test/system_test.sh new file mode 100755 index 0000000..cab5eab --- /dev/null +++ b/test/system_test/system_test.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +echo "Preparing system test..." +THIS_DIR="$(dirname "$0")" +pushd "${THIS_DIR}" &> /dev/null || exit 1 +VENV=$(mktemp --directory) +python -m venv "${VENV}" +. "${VENV}/bin/activate" +"${VENV}/bin/python3" -m pip install --quiet --upgrade pip +"${VENV}/bin/python3" -m pip install --quiet --editable "$(git rev-parse --show-toplevel)" || exit 1 +OUTPUT_FILE=$(mktemp) + +echo "Executing system test..." +security-constraints --config="sc-conf.yaml" --output="${OUTPUT_FILE}" || exit 1 + +echo "Verifying that ID from config was ignored..." +test -z "$(grep --files-with-match "(ID: GHSA-8r8j-xvfj-3fff6f9)" "${OUTPUT_FILE}" )" || exit 1 +echo "Verifying that pip install works with the output file..." +"${VENV}/bin/python3" -m pip install --quiet --dry-run ymlref --constraint="${OUTPUT_FILE}" || exit 1 + +popd &> /dev/null || exit 1 + +echo "System test passed!"