diff --git a/meson.build b/meson.build index 1f8789932..4aa6f3cd2 100644 --- a/meson.build +++ b/meson.build @@ -22,11 +22,11 @@ completions = dependency('bash-completion') systemd_generator_dir = systemd.get_variable(pkgconfig: 'systemdsystemgeneratordir') bash_completions_dir = completions.get_variable(pkgconfig: 'completionsdir', default_value: '/etc/bash_completion.d') -# Order: Fedora/Mageia/openSUSE || Debian/Ubuntu -pyflakes = find_program('pyflakes-3', 'pyflakes3', required: get_option('testing')) +# Order: Fedora/Mageia/openSUSE || Debian/Ubuntu || Virtualenv +pyflakes = find_program('pyflakes-3', 'pyflakes3', 'pyflakes', required: get_option('testing')) pycodestyle = find_program('pycodestyle-3', 'pycodestyle', 'pep8', required: get_option('testing')) pytest = find_program('pytest-3', 'pytest3', required: get_option('testing')) # also requires the pytest-cov plugin -pycoverage = find_program('coverage-3', 'python3-coverage', required: get_option('testing')) +pycoverage = find_program('coverage-3', 'python3-coverage', 'coverage', required: get_option('testing')) pandoc = find_program('pandoc', required: false) find = find_program('find') @@ -78,15 +78,24 @@ if get_option('testing') subdir('tests/ctests') endif - #FIXME: exclude doc/env/ + # Note: Pyflakes doesn't support excluding files. + # Alternative could be flake8. test('linting', pyflakes, timeout: 100, - args: [meson.current_source_dir()]) + args: [ + join_paths(meson.current_source_dir(), 'doc'), + join_paths(meson.current_source_dir(), 'sitecustomize.py'), + join_paths(meson.current_source_dir(), 'netplan_cli'), + join_paths(meson.current_source_dir(), 'examples'), + join_paths(meson.current_source_dir(), 'tests'), + join_paths(meson.current_source_dir(), 'tools'), + join_paths(meson.current_source_dir(), 'python-cffi'), + ]) test('codestyle', pycodestyle, timeout: 100, - args: ['--max-line-length=130', '--exclude=doc/env,*meson-private/pycompile.py', meson.current_source_dir()]) + args: ['--max-line-length=130', '--exclude=doc/env,*meson-private/pycompile.py,.venv,build', meson.current_source_dir()]) test('documentation', find_program('tests/validate_docs.sh'), timeout: 100, diff --git a/netplan_cli/cli/core.py b/netplan_cli/cli/core.py index 918df9997..57414f6a6 100644 --- a/netplan_cli/cli/core.py +++ b/netplan_cli/cli/core.py @@ -20,6 +20,7 @@ import logging import os +import sys from . import utils from netplan import NetplanException, NetplanValidationException, NetplanParserException @@ -59,7 +60,10 @@ def main(self): except NetplanParserException as e: message = f'{e.filename}:{e.line}:{e.column}: {e}' logging.warning(f'Command failed: {message}') + sys.exit(1) except NetplanValidationException as e: logging.warning(f'Command failed: {e.filename}: {e}') + sys.exit(1) except NetplanException as e: logging.warning(f'Command failed: {e}') + sys.exit(1) diff --git a/tests/cli/test_units.py b/tests/cli/test_units.py index c50cf8e78..1ed8f64fb 100644 --- a/tests/cli/test_units.py +++ b/tests/cli/test_units.py @@ -140,15 +140,15 @@ def test_raises_exception_main_function(self): # my attempts to mock sys.stderr didn't work with pytest # This will get the error message passed to logging.warning # as a parameter - with patch('logging.warning') as log: + with patch('logging.warning') as log, self.assertRaises(SystemExit) as e: old_argv = sys.argv args = ['get', '--root-dir', self.tmproot] sys.argv = [old_argv[0]] + args Netplan().main() - sys.argv = old_argv - - args = log.call_args.args - self.assertIn('Error in network definition: invalid boolean value', args[0]) + self.assertEqual(1, e.exception.code) + sys.argv = old_argv + args = log.call_args.args + self.assertIn('Error in network definition: invalid boolean value', args[0]) @unittest.skipIf(os.getuid() == 0, 'Root can always read the file') def test_raises_exception_main_function_permission_denied(self): @@ -160,15 +160,15 @@ def test_raises_exception_main_function_permission_denied(self): os.chmod(os.path.join(self.tmproot, 'etc/netplan/test.yaml'), 0) - with patch('logging.warning') as log: + with patch('logging.warning') as log, self.assertRaises(SystemExit) as e: old_argv = sys.argv args = ['get', '--root-dir', self.tmproot] sys.argv = [old_argv[0]] + args Netplan().main() - sys.argv = old_argv - - args = log.call_args.args - self.assertIn('Permission denied', args[0]) + self.assertEqual(1, e.exception.code) + sys.argv = old_argv + args = log.call_args.args + self.assertIn('Permission denied', args[0]) def test_get_validation_error_exception(self): with open(os.path.join(self.tmproot, 'etc/netplan/test.yaml'), 'w') as f: @@ -177,14 +177,15 @@ def test_get_validation_error_exception(self): eth0: set-name: abc''') - with patch('logging.warning') as log: + with patch('logging.warning') as log, self.assertRaises(SystemExit) as e: old_argv = sys.argv args = ['get', '--root-dir', self.tmproot] sys.argv = [old_argv[0]] + args Netplan().main() - sys.argv = old_argv - args = log.call_args.args - self.assertIn('etc/netplan/test.yaml: Error in network definition', args[0]) + self.assertEqual(1, e.exception.code) + sys.argv = old_argv + args = log.call_args.args + self.assertIn('etc/netplan/test.yaml: Error in network definition', args[0]) def test_set_generic_validation_error_exception(self): with open(os.path.join(self.tmproot, 'etc/netplan/test.yaml'), 'w') as f: @@ -196,11 +197,12 @@ def test_set_generic_validation_error_exception(self): - table: 200 to: 1.2.3.4''') - with patch('logging.warning') as log: + with patch('logging.warning') as log, self.assertRaises(SystemExit) as e: old_argv = sys.argv args = ['get', '--root-dir', self.tmproot] sys.argv = [old_argv[0]] + args Netplan().main() - sys.argv = old_argv - args = log.call_args.args - self.assertIn("VRF routes table mismatch", args[0]) + self.assertEqual(1, e.exception.code) + sys.argv = old_argv + args = log.call_args.args + self.assertIn("VRF routes table mismatch", args[0])