Skip to content

Commit

Permalink
Unitesting & coverage improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
lowell80 committed Oct 20, 2023
1 parent 8003a10 commit d49c3e9
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 13 deletions.
21 changes: 12 additions & 9 deletions ksconf/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from collections import namedtuple
from io import StringIO, open
from textwrap import dedent
from typing import Optional, TextIO
from typing import Mapping, Optional, TextIO
from warnings import warn

from ksconf.compat import cache
Expand Down Expand Up @@ -363,7 +363,7 @@ def redirect_io(self, stdin=None, stdout=None, stderr=None):
def exit(self, exit_code):
""" Allow overriding for unittesting or other high-level functionality, like an
interactive interface. """
sys.exit(exit_code)
sys.exit(exit_code) # pragma: no cover

def add_parser(self, subparser):
# Passing in the object return by 'ArgumentParser.add_subparsers()'
Expand Down Expand Up @@ -553,7 +553,8 @@ def add_file_handler(parser: ArgumentParser) -> ArgumentParser:
return parser


def _get_importlib_entrypoints(group, name=None) -> list:
def _get_importlib_entrypoints(group, name=None) -> Mapping:
# Returns "EntryPoints", but that complicates the imports. "Mapping" gets the job done
# Using a backport library to get Python 3.10 EntryPoints.select() functionality.
# But practically, if the backport is available, use it. It's likely newer than stdlib.
try:
Expand All @@ -569,7 +570,7 @@ def _get_fallback(group, name=None):
if name is None:
return entrypoints
else:
return entrypoints[name]
return {name: entrypoints[name]}


__get_entity_resolvers = [
Expand All @@ -585,7 +586,7 @@ def _get_fallback(group, name=None):

# This caching is *mostly* beneficial for unittest CLI testing
@cache
def get_entrypoints(group, name=None):
def get_entrypoints(group, name=None) -> Mapping:

for resolver in list(__get_entity_resolvers):
results = None
Expand All @@ -602,10 +603,12 @@ def get_entrypoints(group, name=None):


def get_all_ksconf_cmds(on_error="warn"):
for (name, entry) in get_entrypoints("ksconf_cmd").items():
entry_points = get_entrypoints("ksconf_cmd")
for name in entry_points:
entry = entry_points[name]
try:
cmd_cls = entry.load()
except (ImportError, NameError, SyntaxError) as e:
except (ImportError, NameError, SyntaxError) as e: # pragma: no cover
if on_error == "warn":
warn(f"Unable to load entrypoint for {name}. Disabling.\n"
f"Base exception {e}.", KsconfPluginWarning)
Expand All @@ -615,7 +618,7 @@ def get_all_ksconf_cmds(on_error="warn"):
else:
raise e
continue
if not issubclass(cmd_cls, KsconfCmd):
if not issubclass(cmd_cls, KsconfCmd): # pragma: no cover
msg = "Issue loading class for entrypoint: Disabling.\n" \
f"{entry!r} is not derived from KsconfCmd. "
if on_error == "warn":
Expand All @@ -627,7 +630,7 @@ def get_all_ksconf_cmds(on_error="warn"):
continue
try:
cmd_cls._handle_imports()
except ImportError as e:
except ImportError as e: # pragma: no cover
module = e.name
if on_error == "warn":
warn(f"Unable to load external modules for {name}. Disabling. "
Expand Down
9 changes: 8 additions & 1 deletion ksconf/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
# wildcard otherwise stick with simple string matching, for efficiency...)


# This should be re-written to (1) use functions/class pattern type handlers per item (slightly less
# efficient in some cases, but way more flexible by allowing mixing of wildcard and regex in one
# rule set, for example. (2) This should be registration based, (3) add support for switching modes
# with prefix patterns; therefore hooks could be used so that a plugin could add their own pattern
# matching scheme.


class FilteredList:
IGNORECASE = 1
INVERT = 2
Expand Down Expand Up @@ -99,7 +106,7 @@ def _pre_match(self): # pragma: no cover

def match(self, item: str) -> bool:
""" See if given item matches any of the given patterns. If no patterns were provided,
:py:attr:default: will be returned.
:py:attr:`default`: will be returned.
"""
if self.patterns:
self.prep()
Expand Down
2 changes: 1 addition & 1 deletion ksconf/setup_entrypoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def load(self):
return getattr(mod, self.object_name)


def get_entrypoints_fallback(group):
def get_entrypoints_fallback(group) -> dict:
entry_points = {}
for ep in _entry_points[group]:
entry_points[ep.name] = LocalEntryPoint(ep)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def test_tarball_manifest_with_filter(self):
filter_file=lambda relpath: relpath.name != "README.txt")
self.assertEqual(len(manifest.files), 14)
self.assertIsNotNone(manifest.files[0].hash)
self.assertEquals(manifest.hash, "6a747149379376f9d29aee55ba40147c14cb8374988c1ff87a3547a3a18634a5")
self.assertEqual(manifest.hash, "6a747149379376f9d29aee55ba40147c14cb8374988c1ff87a3547a3a18634a5")

@unittest.skipIf(sys.platform == "win32", "Requires NIX with file modes")
def test_filesystem_manifest_with_filter(self):
Expand All @@ -94,7 +94,7 @@ def test_filesystem_manifest_with_filter(self):
filter_file=lambda relpath: relpath.name != "README.txt")
self.assertEqual(len(manifest.files), 14)
self.assertIsNotNone(manifest.files[0].hash)
self.assertEquals(manifest.hash, "6a747149379376f9d29aee55ba40147c14cb8374988c1ff87a3547a3a18634a5")
self.assertEqual(manifest.hash, "6a747149379376f9d29aee55ba40147c14cb8374988c1ff87a3547a3a18634a5")

def test_the_do_it_all_function(self):
tarball_path = static_data("apps/modsecurity-add-on-for-splunk_12.tgz")
Expand Down
6 changes: 6 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import unittest

from ksconf.command import get_entrypoints
from ksconf.consts import EXIT_CODE_NO_SUCH_FILE, EXIT_CODE_SUCCESS, EXIT_CODE_USER_QUIT
from tests.cli_helper import FakeStdin, TestWorkDir, ksconf_cli

Expand Down Expand Up @@ -49,6 +50,11 @@ def test_conffileproxy_invalid_arg(self):
self.assertIn(ko.returncode, (EXIT_CODE_USER_QUIT, EXIT_CODE_NO_SUCH_FILE))
self.assertRegex(ko.stderr, ".*(failed to parse|invalid ConfFileType).*")

def test_get_named_entrypoint(self):
eps = get_entrypoints("ksconf_cmd", "diff")
self.assertEqual(len(eps), 1)
assert eps["diff"]


if __name__ == '__main__': # pragma: no cover
unittest.main()

0 comments on commit d49c3e9

Please sign in to comment.