From 6bb56ced2ef904985dfa556868aa561675d4632e Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Mon, 21 Jan 2019 18:18:58 +0000 Subject: [PATCH 01/10] Run tests from tox, wether runtests or pytest --- Gemfile | 7 +- tests/tox-helper.py | 44 ++++++++ tests/unit/test_module_names.py | 1 + tox.ini | 188 +++++++++++++++++++++++++++++++- 4 files changed, 233 insertions(+), 7 deletions(-) create mode 100644 tests/tox-helper.py diff --git a/Gemfile b/Gemfile index 360fb4bfca..b014c8fa1b 100644 --- a/Gemfile +++ b/Gemfile @@ -2,9 +2,8 @@ source 'https://rubygems.org' -# Point this back at the test-kitchen package after 1.23.3 is relased -gem 'test-kitchen', :git => 'https://github.com/dwoz/test-kitchen.git', :branch => 'winrm_opts' -gem 'kitchen-salt', '~>0.2' +gem 'test-kitchen', '~>1.23.3' +gem 'kitchen-salt', '~>0.4.1' gem 'kitchen-sync' gem 'git' @@ -14,7 +13,7 @@ end group :windows do gem 'winrm', '~>2.0' - gem 'winrm-fs', '~>1.3.1' + gem 'winrm-fs', '~>1.3.1' end group :ec2 do diff --git a/tests/tox-helper.py b/tests/tox-helper.py new file mode 100644 index 0000000000..98e60fe0f3 --- /dev/null +++ b/tests/tox-helper.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This script exists so that path handling when running tox works for both Linux and Windows + +# Import Python Libs +from __future__ import absolute_import, unicode_literals +import os +import shutil +import argparse +import tempfile + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--rootdir', + default=os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + ) + subparsers = parser.add_subparsers(help='sub-command help', dest='subparser') + + subparsers.add_parser('create-dirs') + subparsers.add_parser('move-artifacts') + + options = parser.parse_args() + if options.subparser == 'create-dirs': + for dirname in ('logs', 'coverage', 'xml-unittests-output'): + path = os.path.join(options.rootdir, 'artifacts', dirname) + if not os.path.exists(path): + os.makedirs(path) + + if options.subparser == 'move-artifacts': + tmp_artifacts_dir = os.path.join(tempfile.gettempdir(), 'artifacts') + if not os.path.exists(tmp_artifacts_dir): + os.makedirs(tmp_artifacts_dir) + + for dirname in ('logs', 'coverage', 'xml-unittests-output'): + src = os.path.join(options.rootdir, 'artifacts', dirname) + dst = os.path.join(tmp_artifacts_dir, dirname) + shutil.copytree(src, dst) + + +if __name__ == '__main__': + main() diff --git a/tests/unit/test_module_names.py b/tests/unit/test_module_names.py index a53ca7b974..8e6f8d6791 100644 --- a/tests/unit/test_module_names.py +++ b/tests/unit/test_module_names.py @@ -48,6 +48,7 @@ EXCLUDED_FILES = [ os.path.join('tests', 'modparser.py'), os.path.join('tests', 'committer_parser.py'), os.path.join('tests', 'zypp_plugin.py'), + os.path.join('tests', 'tox-helper.py'), os.path.join('tests', 'unit', 'transport', 'mixins.py'), os.path.join('tests', 'integration', 'utils', 'testprogram.py'), ] diff --git a/tox.ini b/tox.ini index ea50d3d284..d8beec1275 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,194 @@ [tox] -envlist = py27,py34,py35,py36,pylint-salt,pylint-tests +envlist = + py{27,34,35,36}, + py{27,34,35,36}-coverage, + py{27,34,35,36}-pytest, + py{27,34,35,36}-runtests, + py{27,34,35,36}-pytest-coverage, + py{27,34,35,36}-runtests-coverage, + pylint-salt, + pylint-tests skip_missing_interpreters = True skipsdist = True [testenv] deps = -Ur{toxinidir}/requirements/tests.txt -commands = pytest --rootdir {toxinidir} {posargs} +changedir = {toxinidir} +commands_pre = {envpython} tests/tox-helper.py create-dirs passenv = LANG HOME sitepackages = True +commands = {[testenv:runtests]commands} + +[testenv:runtests] +deps = + {[testenv]deps} + unittest-xml-reporting +commands = {envpython} {toxinidir}/tests/runtests.py --tests-logfile={toxinidir}/artifacts/logs/runtests.log {posargs} + +[testenv:pytest] +commands = pytest --rootdir {toxinidir} --log-file={toxinidir}/artifacts/logs/runtests.log {posargs} + +[testenv:runtests-coverage] +commands_pre = + - coverage erase +commands = + coverage run -m tests.runtests {posargs} +commands_post = + - coverage combine + - coverage xml -o {toxinidir}/artifacts/coverage/coverage.xml + +[testenv:pytest-coverage] +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands = coverage run -m py.test --rootdir {toxinidir} {posargs} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py2-pytest] +commands = {[testenv:pytest]commands} + +[testenv:py2-runtests] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests]commands} + +[testenv:py2-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py2-runtests-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py2-pytest-coverage] +commands = {[testenv:pytest-coverage]commands} +commands_pre = {[testenv:pytest-coverage]commands_pre} +commands_post = {[testenv:pytest-coverage]commands_post} + +[testenv:py27-pytest] +commands = {[testenv:pytest]commands} + +[testenv:py27-runtests] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests]commands} + +[testenv:py27-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py27-runtests-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py27-pytest-coverage] +commands = {[testenv:pytest-coverage]commands} +commands_pre = {[testenv:pytest-coverage]commands_pre} +commands_post = {[testenv:pytest-coverage]commands_post} + +[testenv:py3-pytest] +commands = {[testenv:pytest]commands} + +[testenv:py3-runtests] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests]commands} + +[testenv:py3-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py3-runtests-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py3-pytest-coverage] +commands = {[testenv:pytest-coverage]commands} +commands_pre = {[testenv:pytest-coverage]commands_pre} +commands_post = {[testenv:pytest-coverage]commands_post} + + +[testenv:py34-pytest] +commands = {[testenv:pytest]commands} + +[testenv:py34-runtests] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests]commands} + +[testenv:py34-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py34-runtests-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py34-pytest-coverage] +commands = {[testenv:pytest-coverage]commands} +commands_pre = {[testenv:pytest-coverage]commands_pre} +commands_post = {[testenv:pytest-coverage]commands_post} + + +[testenv:py35-pytest] +commands = {[testenv:pytest]commands} + +[testenv:py35-runtests] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests]commands} + +[testenv:py35-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py35-runtests-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py35-pytest-coverage] +commands = {[testenv:pytest-coverage]commands} +commands_pre = {[testenv:pytest-coverage]commands_pre} +commands_post = {[testenv:pytest-coverage]commands_post} + + +[testenv:py36-pytest] +commands = {[testenv:pytest]commands} + +[testenv:py36-runtests] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests]commands} + +[testenv:py36-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py36-runtests-coverage] +deps = {[testenv:runtests]deps} +commands = {[testenv:runtests-coverage]commands} +commands_pre = {[testenv:runtests-coverage]commands_pre} +commands_post = {[testenv:runtests-coverage]commands_post} + +[testenv:py36-pytest-coverage] +commands = {[testenv:pytest-coverage]commands} +commands_pre = {[testenv:pytest-coverage]commands_pre} +commands_post = {[testenv:pytest-coverage]commands_post} + [testenv:pylint-salt] basepython = python2.7 @@ -17,6 +198,7 @@ commands = pylint --rcfile=.testing.pylintrc --disable=I,W1307,C0411,C0413,W8410,str-format-in-logging {posargs:setup.py salt/} sitepackages = False + [testenv:pylint-tests] basepython = python2.7 deps = -r{toxinidir}/requirements/dev.txt @@ -26,6 +208,6 @@ commands = sitepackages = False [pytest] -addopts = --log-file /tmp/salt-runtests.log --no-print-logs --ssh-tests -ra -sv +addopts = --no-print-logs --ssh-tests -ra -sv testpaths = tests norecursedirs = tests/kitchen From 6d62156a11cc98a4c6d736adbd3aa823bcd0ce2a Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Mon, 10 Dec 2018 19:02:13 +0000 Subject: [PATCH 02/10] Add `.coveragerc` --- .coveragerc | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000000..7771c44f33 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,34 @@ +[run] +branch = True +cover_pylib = False +source = + salt +parallel = True +concurrency = multiprocessing +omit = + tests/*.py + setup.py + +[report] +# Regexes for lines to exclude from consideration +exclude_lines = + # Have to re-enable the standard pragma + pragma: no cover + + # Don't complain about missing debug-only code: + def __repr__ + + # Don't complain if tests don't hit defensive assertion code: + raise AssertionError + raise NotImplementedError + + # Don't complain if non-runnable code isn't run: + if 0: + if __name__ == .__main__.: + + +ignore_errors = True + +[paths] +source = + salt From 716bda44144904cff15acc1605b1edf31eda58e8 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Tue, 22 Jan 2019 11:00:01 +0000 Subject: [PATCH 03/10] Remove duplicate dependency --- requirements/tests.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements/tests.txt b/requirements/tests.txt index 2da1cc5709..6747e0a2ed 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -29,7 +29,6 @@ PyMySQL; sys.platform != 'win32' and sys.platform != 'darwin' jsonschema strict_rfc3339 rfc3987 -jinja2 pyOpenSSL ioflo dnspython From 840b3d210316e7be9edb1f875283757dfc41eba9 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Tue, 22 Jan 2019 13:22:46 +0000 Subject: [PATCH 04/10] Add `pytest-salt-from-filenames` to pytest requirements --- requirements/pytest.txt | 1 + tests/conftest.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements/pytest.txt b/requirements/pytest.txt index c27d5cb2ea..7b166d46ee 100644 --- a/requirements/pytest.txt +++ b/requirements/pytest.txt @@ -5,3 +5,4 @@ pytest-salt == 2018.12.8 pytest-timeout >= 1.3.3 pytest-tempdir >= 2018.8.11 pytest-helpers-namespace >= 2017.11.11 +pytest-salt-from-filenames >= 2019.1.22 diff --git a/tests/conftest.py b/tests/conftest.py index 44f8dbc326..48d929ada8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -55,7 +55,7 @@ import salt.log.setup from salt.utils.odict import OrderedDict # Define the pytest plugins we rely on -pytest_plugins = ['tempdir', 'helpers_namespace'] # pylint: disable=invalid-name +pytest_plugins = ['tempdir', 'helpers_namespace', 'salt-from-filenames'] # pylint: disable=invalid-name # Define where not to collect tests from collect_ignore = ['setup.py'] From 138ca2e682e2f44655afe30d69bafe89db23daaf Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Tue, 22 Jan 2019 16:24:44 +0000 Subject: [PATCH 05/10] Show objects on assertion failure --- tests/unit/serializers/test_serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/serializers/test_serializers.py b/tests/unit/serializers/test_serializers.py index 3bf42b67d7..8ebedcdd3f 100644 --- a/tests/unit/serializers/test_serializers.py +++ b/tests/unit/serializers/test_serializers.py @@ -152,7 +152,7 @@ class TestSerializers(TestCase): # BLAAM! yml_src is not valid ! final_obj = OrderedDict(yaml.deserialize(yml_src)) - assert obj != final_obj + assert obj != final_obj, 'Objects matched! {} == {}'.format(obj, final_obj) @skipIf(not yamlex.available, SKIP_MESSAGE % 'sls') def test_sls_aggregate(self): From a26ba7f3aae7cb5108a7718dbd7f4caf90298422 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Tue, 22 Jan 2019 16:15:45 +0000 Subject: [PATCH 06/10] Don't fail the test because of order --- tests/integration/modules/test_supervisord.py | 2 +- tests/unit/modules/inspectlib/test_fsdb.py | 22 ++++--------------- tests/unit/modules/test_cassandra.py | 7 ++++-- tests/unit/modules/test_pillar.py | 5 +++-- tests/unit/states/test_proxy.py | 4 +--- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/tests/integration/modules/test_supervisord.py b/tests/integration/modules/test_supervisord.py index bdb8f8c179..6a508f8d08 100644 --- a/tests/integration/modules/test_supervisord.py +++ b/tests/integration/modules/test_supervisord.py @@ -222,7 +222,7 @@ class SupervisordModuleTest(ModuleCase): ret = self.run_function( 'supervisord.status', [], conf_file=self.supervisor_conf, bin_env=self.venv_dir) - self.assertEqual(list(ret.keys()), ['sleep_service', 'sleep_service2']) + self.assertEqual(sorted(ret), ['sleep_service', 'sleep_service2']) def test_status_one(self): ''' diff --git a/tests/unit/modules/inspectlib/test_fsdb.py b/tests/unit/modules/inspectlib/test_fsdb.py index 366c621c6e..3a3e2dd6fe 100644 --- a/tests/unit/modules/inspectlib/test_fsdb.py +++ b/tests/unit/modules/inspectlib/test_fsdb.py @@ -135,26 +135,12 @@ class InspectorFSDBTestCase(TestCase): csvdb.open() csvdb.create_table_from_object(FoobarEntity()) + sorted_writable_data = sorted(writable.data[0].strip().split(',')) if six.PY2: - assert writable.data[0].strip() == "foo:int,bar:unicode,spam:float" + sorted_expected_data = sorted("foo:int,bar:unicode,spam:float".split(',')) else: - # Order in PY3 is not the same for every run - writable_data = writable.data[0].strip() - assert_order_options = ['bar:str,foo:int,spam:float', - 'bar:str,spam:float,foo:int', - 'foo:int,spam:float,bar:str', - 'foo:int,bar:str,spam:float', - 'spam:float,foo:int,bar:str', - 'spam:float,bar:str,foo:int'] - while assert_order_options: - assert_option = assert_order_options.pop() - try: - assert writable_data == assert_option - break - except AssertionError: - if not assert_order_options: - raise - continue + sorted_expected_data = sorted("foo:int,bar:str,spam:float".split(',')) + self.assertEqual(sorted_writable_data, sorted_expected_data) def test_list_databases(self): ''' diff --git a/tests/unit/modules/test_cassandra.py b/tests/unit/modules/test_cassandra.py index 9bba531c66..dfc6bee507 100644 --- a/tests/unit/modules/test_cassandra.py +++ b/tests/unit/modules/test_cassandra.py @@ -118,9 +118,12 @@ class CassandraTestCase(TestCase, LoaderModuleMockMixin): self.assertCountEqual(cassandra.column_families(), {'A': ['a', 'b'], 'B': ['c', 'd']}) else: - self.assertEqual(cassandra.column_families('A'), + self.assertEqual(sorted(cassandra.column_families('A')), ['a', 'b']) - self.assertEqual(cassandra.column_families(), + column_families = cassandra.column_families() + for key in ('A', 'B'): + column_families[key] = sorted(column_families[key]) + self.assertEqual(column_families, {'A': ['a', 'b'], 'B': ['c', 'd']}) def test_column_family_definition(self): diff --git a/tests/unit/modules/test_pillar.py b/tests/unit/modules/test_pillar.py index f952e375d0..6c058df340 100644 --- a/tests/unit/modules/test_pillar.py +++ b/tests/unit/modules/test_pillar.py @@ -54,10 +54,11 @@ class PillarModuleTestCase(TestCase, LoaderModuleMockMixin): @skipIf(NO_MOCK, NO_MOCK_REASON) def test_ls(self): with patch('salt.modules.pillar.items', MagicMock(return_value=pillar_value_1)): + ls = sorted(pillarmod.ls()) if six.PY3: - self.assertCountEqual(pillarmod.ls(), ['a', 'b']) + self.assertCountEqual(ls, ['a', 'b']) else: - self.assertEqual(pillarmod.ls(), ['a', 'b']) + self.assertEqual(ls, ['a', 'b']) @skipIf(NO_MOCK, NO_MOCK_REASON) def test_pillar_get_default_merge(self): diff --git a/tests/unit/states/test_proxy.py b/tests/unit/states/test_proxy.py index bcb1d5ad64..226bccaa30 100644 --- a/tests/unit/states/test_proxy.py +++ b/tests/unit/states/test_proxy.py @@ -70,9 +70,7 @@ class ProxyTestCase(TestCase, LoaderModuleMockMixin): with patch.dict(proxy.__salt__, patches): out = proxy.managed('192.168.0.1', '3128', user='frank', password='passw0rd', bypass_domains=['salt.com', 'test.com']) - if six.PY3: - # Sorting is different in Py3 - out['changes']['new'][-1]['bypass_domains'] = sorted(out['changes']['new'][-1]['bypass_domains']) + out['changes']['new'][-1]['bypass_domains'] = sorted(out['changes']['new'][-1]['bypass_domains']) calls = [ call('192.168.0.1', '3128', 'frank', 'passw0rd', 'Ethernet'), From 8fcf235b75c57efcfa794e60eb6d59a2a745f85a Mon Sep 17 00:00:00 2001 From: twangboy Date: Tue, 22 Jan 2019 09:43:17 -0700 Subject: [PATCH 07/10] Fix minion start issue --- salt/utils/network.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/utils/network.py b/salt/utils/network.py index 37253dda12..4786936217 100644 --- a/salt/utils/network.py +++ b/salt/utils/network.py @@ -1940,7 +1940,7 @@ def parse_host_port(host_port): if _s_[0] == "[": if "]" in host_port: host, _s_ = _s_.lstrip("[").rsplit("]", 1) - host = ipaddress.IPv6Address(host) + host = ipaddress.IPv6Address(host).compressed if _s_[0] == ":": port = int(_s_.lstrip(":")) else: @@ -1958,7 +1958,7 @@ def parse_host_port(host_port): host = _s_ try: if not isinstance(host, ipaddress._BaseAddress): - host_ip = ipaddress.ip_address(host) + host_ip = ipaddress.ip_address(host).compressed host = host_ip except ValueError: log.debug('"%s" Not an IP address? Assuming it is a hostname.', host) From 3000d2095d08c433ce86db2a550d1227b9cf7727 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 23 Jan 2019 11:55:02 +0000 Subject: [PATCH 08/10] Fix tests. We no longer get `ipaddress` instances back. --- tests/unit/utils/test_network.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/utils/test_network.py b/tests/unit/utils/test_network.py index eaccf1e852..0ade387ed6 100644 --- a/tests/unit/utils/test_network.py +++ b/tests/unit/utils/test_network.py @@ -206,12 +206,12 @@ class NetworkTestCase(TestCase): def test_parse_host_port(self): _ip = ipaddress.ip_address good_host_ports = { - '10.10.0.3': (_ip('10.10.0.3'), None), - '10.10.0.3:1234': (_ip('10.10.0.3'), 1234), - '2001:0db8:85a3::8a2e:0370:7334': (_ip('2001:0db8:85a3::8a2e:0370:7334'), None), - '[2001:0db8:85a3::8a2e:0370:7334]:1234': (_ip('2001:0db8:85a3::8a2e:0370:7334'), 1234), - '2001:0db8:85a3::7334': (_ip('2001:0db8:85a3::7334'), None), - '[2001:0db8:85a3::7334]:1234': (_ip('2001:0db8:85a3::7334'), 1234) + '10.10.0.3': (_ip('10.10.0.3').compressed, None), + '10.10.0.3:1234': (_ip('10.10.0.3').compressed, 1234), + '2001:0db8:85a3::8a2e:0370:7334': (_ip('2001:0db8:85a3::8a2e:0370:7334').compressed, None), + '[2001:0db8:85a3::8a2e:0370:7334]:1234': (_ip('2001:0db8:85a3::8a2e:0370:7334').compressed, 1234), + '2001:0db8:85a3::7334': (_ip('2001:0db8:85a3::7334').compressed, None), + '[2001:0db8:85a3::7334]:1234': (_ip('2001:0db8:85a3::7334').compressed, 1234) } bad_host_ports = [ '10.10.0.3/24', From f27589aff711ffc0fb05da8fe5e4f2e672051aa1 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Thu, 24 Jan 2019 20:55:48 +0000 Subject: [PATCH 09/10] Remove unused imports --- tests/unit/states/test_proxy.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/unit/states/test_proxy.py b/tests/unit/states/test_proxy.py index 226bccaa30..f21e050643 100644 --- a/tests/unit/states/test_proxy.py +++ b/tests/unit/states/test_proxy.py @@ -14,9 +14,6 @@ from tests.support.mock import ( call ) -# Import 3rd-party libs -from salt.ext import six - # Import Salt Libs import salt.states.proxy as proxy From 39fb981faaf686682490a30a626da18f258790d3 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 25 Jan 2019 12:58:52 +0000 Subject: [PATCH 10/10] "Tell" coverage to track subprocesses. --- tests/support/coverage/sitecustomize.py | 11 +++++++++++ tox.ini | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/support/coverage/sitecustomize.py diff --git a/tests/support/coverage/sitecustomize.py b/tests/support/coverage/sitecustomize.py new file mode 100644 index 0000000000..76f7babf5f --- /dev/null +++ b/tests/support/coverage/sitecustomize.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +''' +Python will always try to import sitecustomize. +We use that fact to try and support code coverage for sub-processes +''' +from __future__ import absolute_import +try: + import coverage + coverage.process_startup() +except ImportError: + pass diff --git a/tox.ini b/tox.ini index d8beec1275..b4ee8d0b87 100644 --- a/tox.ini +++ b/tox.ini @@ -29,6 +29,12 @@ commands = {envpython} {toxinidir}/tests/runtests.py --tests-logfile={toxinidir} commands = pytest --rootdir {toxinidir} --log-file={toxinidir}/artifacts/logs/runtests.log {posargs} [testenv:runtests-coverage] +# Add tests/support/coverage to PYTHONPATH in order to get code coverage from subprocesses. +# Additional, set the COVERAGE_PROCESS_START environment variable so that the coverage library +# knows it's supposed to track subprocesses. +setenv = + PYTHONPATH={toxinidir}/tests/support/coverage + COVERAGE_PROCESS_START={toxinidir}/.coveragerc commands_pre = - coverage erase commands = @@ -38,6 +44,7 @@ commands_post = - coverage xml -o {toxinidir}/artifacts/coverage/coverage.xml [testenv:pytest-coverage] +setenv = {[testenv:runtests-coverage]setenv} commands_pre = {[testenv:runtests-coverage]commands_pre} commands = coverage run -m py.test --rootdir {toxinidir} {posargs} commands_post = {[testenv:runtests-coverage]commands_post} @@ -51,17 +58,20 @@ commands = {[testenv:runtests]commands} [testenv:py2-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py2-runtests-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py2-pytest-coverage] +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:pytest-coverage]commands} commands_pre = {[testenv:pytest-coverage]commands_pre} commands_post = {[testenv:pytest-coverage]commands_post} @@ -75,17 +85,20 @@ commands = {[testenv:runtests]commands} [testenv:py27-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py27-runtests-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py27-pytest-coverage] +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:pytest-coverage]commands} commands_pre = {[testenv:pytest-coverage]commands_pre} commands_post = {[testenv:pytest-coverage]commands_post} @@ -99,17 +112,20 @@ commands = {[testenv:runtests]commands} [testenv:py3-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py3-runtests-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py3-pytest-coverage] +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:pytest-coverage]commands} commands_pre = {[testenv:pytest-coverage]commands_pre} commands_post = {[testenv:pytest-coverage]commands_post} @@ -124,17 +140,20 @@ commands = {[testenv:runtests]commands} [testenv:py34-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py34-runtests-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py34-pytest-coverage] +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:pytest-coverage]commands} commands_pre = {[testenv:pytest-coverage]commands_pre} commands_post = {[testenv:pytest-coverage]commands_post} @@ -149,17 +168,20 @@ commands = {[testenv:runtests]commands} [testenv:py35-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py35-runtests-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py35-pytest-coverage] +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:pytest-coverage]commands} commands_pre = {[testenv:pytest-coverage]commands_pre} commands_post = {[testenv:pytest-coverage]commands_post} @@ -174,17 +196,20 @@ commands = {[testenv:runtests]commands} [testenv:py36-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py36-runtests-coverage] deps = {[testenv:runtests]deps} +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:runtests-coverage]commands} commands_pre = {[testenv:runtests-coverage]commands_pre} commands_post = {[testenv:runtests-coverage]commands_post} [testenv:py36-pytest-coverage] +setenv = {[testenv:runtests-coverage]setenv} commands = {[testenv:pytest-coverage]commands} commands_pre = {[testenv:pytest-coverage]commands_pre} commands_post = {[testenv:pytest-coverage]commands_post}