diff --git a/hook.py b/hook.py index 105e34f..48d273f 100644 --- a/hook.py +++ b/hook.py @@ -13,7 +13,6 @@ async def enable(services): atomic_gui = AtomicGUI(services, name, description) - app = services.get('app_svc').application # we only ingest data once, and save new abilities in the data/ folder of the plugin if "abilities" not in os.listdir(data_dir): diff --git a/scripts/check_coverage.py b/scripts/check_coverage.py new file mode 100644 index 0000000..58cca7c --- /dev/null +++ b/scripts/check_coverage.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +"""Run coverage combine/xml/report only when coverage data files exist. + +Used by the coverage-ci tox environment to avoid a "No data to combine" +failure when upstream test environments did not produce any coverage data. +""" +import glob +import subprocess +import sys + + +def main(): + files = glob.glob('.coverage.*') + if not files: + print('No coverage data files found, skipping combine') + return + + for cmd in [['coverage', 'combine'], ['coverage', 'xml'], ['coverage', 'report']]: + result = subprocess.run(cmd) + if result.returncode != 0: + print( + f'Command {" ".join(cmd)!r} failed with exit code {result.returncode}', + file=sys.stderr, + ) + sys.exit(result.returncode) + + +if __name__ == '__main__': + main() diff --git a/tests/test_hook.py b/tests/test_hook.py index f23c090..34d6c79 100644 --- a/tests/test_hook.py +++ b/tests/test_hook.py @@ -1,6 +1,6 @@ import os import pytest -from unittest.mock import MagicMock, AsyncMock, patch, PropertyMock +from unittest.mock import MagicMock, AsyncMock, patch class TestHookModuleAttributes: @@ -103,23 +103,3 @@ async def test_enable_skips_ingest_when_abilities_exist(self): # AtomicService should NOT be instantiated when abilities dir exists mock_svc_cls.assert_not_called() - @pytest.mark.asyncio - async def test_enable_accesses_app(self): - """enable() should access services['app_svc'].application.""" - import hook - - mock_app = MagicMock() - mock_app_svc = MagicMock() - type(mock_app_svc).application = PropertyMock(return_value=mock_app) - - services = { - 'auth_svc': MagicMock(), - 'data_svc': MagicMock(), - 'app_svc': mock_app_svc, - } - - with patch.object(hook, 'data_dir', '/tmp/atomic_test_hook_data'), \ - patch('os.listdir', return_value=['abilities']), \ - patch('hook.AtomicGUI'): - await hook.enable(services) - type(mock_app_svc).application.assert_called() diff --git a/tox.ini b/tox.ini index ce5c3be..38257e9 100644 --- a/tox.ini +++ b/tox.ini @@ -26,17 +26,17 @@ deps = pytest-aiohttp coverage codecov -changedir = {homedir}/tmp +changedir = {env:HOME}/tmp commands = - /usr/bin/git clone https://github.com/mitre/caldera.git --recursive {homedir}/tmp - /bin/rm -rf {homedir}/tmp/plugins/atomic - python -m pip install -r {homedir}/tmp/requirements.txt - /usr/bin/cp -R {toxinidir} {homedir}/tmp/plugins/atomic - coverage run -p -m pytest --tb=short --rootdir={homedir}/tmp -Werror plugins/atomic/tests + git clone https://github.com/mitre/caldera.git --recursive {env:HOME}/tmp + rm -rf {env:HOME}/tmp/plugins/atomic + python -m pip install -r {env:HOME}/tmp/requirements.txt + cp -R {toxinidir} {env:HOME}/tmp/plugins/atomic + coverage run -p -m pytest --tb=short --rootdir={env:HOME}/tmp -Werror plugins/atomic/tests allowlist_externals = - /usr/bin/sudo * - /usr/bin/git * - /usr/bin/cp * + git + rm + cp [testenv:py38] description = run tests @@ -47,23 +47,23 @@ deps = pytest-aiohttp coverage codecov -changedir = {homedir}/tmp +changedir = {env:HOME}/tmp commands = - /usr/bin/git clone https://github.com/mitre/caldera.git --recursive {homedir}/tmp - /bin/rm -rf {homedir}/tmp/plugins/atomic - python -m pip install -r {homedir}/tmp/requirements.txt - /usr/bin/cp -R {toxinidir} {homedir}/tmp/plugins/atomic - coverage run -p -m pytest --tb=short --rootdir={homedir}/tmp {homedir}/tmp/plugins/atomic/tests + git clone https://github.com/mitre/caldera.git --recursive {env:HOME}/tmp + rm -rf {env:HOME}/tmp/plugins/atomic + python -m pip install -r {env:HOME}/tmp/requirements.txt + cp -R {toxinidir} {env:HOME}/tmp/plugins/atomic + coverage run -p -m pytest --tb=short --rootdir={env:HOME}/tmp {env:HOME}/tmp/plugins/atomic/tests allowlist_externals = - /usr/bin/sudo * - /usr/bin/git * - /usr/bin/cp * + git + rm + cp [testenv:coverage] deps = coverage skip_install = true -changedir = {homedir}/tmp +changedir = {env:HOME}/tmp commands = coverage combine coverage html @@ -74,8 +74,6 @@ deps = coveralls coverage skip_install = true -changedir = {homedir}/tmp +changedir = {env:HOME}/tmp commands = - coverage combine - coverage xml - coverage report + python {toxinidir}/scripts/check_coverage.py