From 7cc9afc5932df0084a36b49bcbbe71fd1e14580a Mon Sep 17 00:00:00 2001
From: Marco Clemencic <marco.clemencic@cern.ch>
Date: Tue, 2 Oct 2018 14:46:13 +0200
Subject: [PATCH] Use nose2 instead of nose for testing

added Python 3.7 support and removed 2.6
---
 .coveragerc                             |  6 +++++
 .gitlab-ci.yml                          | 28 +++++++++++++++++-----
 LbPlatformUtils/__init__.py             |  3 +--
 LbPlatformUtils/tests/test_describe.py  | 22 ++++-------------
 LbPlatformUtils/tests/test_detection.py | 26 ++++++++++----------
 LbPlatformUtils/tests/utils.py          | 32 +++++++++++++++++++++----
 nose2.cfg                               | 13 ++++++++++
 setup.cfg                               |  7 ------
 setup.py                                | 10 ++++----
 9 files changed, 93 insertions(+), 54 deletions(-)
 create mode 100644 nose2.cfg
 delete mode 100644 setup.cfg

diff --git a/.coveragerc b/.coveragerc
index 10844f7..29a7797 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,6 +1,12 @@
 [run]
 cover_pylib = False
 omit = /usr/*
+       */.local/*
+       */tests/*
+       setup.py
 
 [report]
 show_missing = True
+
+[html]
+directory = cover
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4b4f259..174f665 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,7 +8,7 @@ centos7:
   image: gitlab-registry.cern.ch/lhcb-docker/python-deployment:centos7
   script:
     - python --version
-    - python setup.py nosetests --cover-package LbPlatformUtils
+    - python setup.py test
     - mkdir -p cover_report && mv -f cover cover_report/$CI_JOB_NAME
     - python setup.py install && lb-describe-platform --flags
   artifacts:
@@ -23,7 +23,7 @@ slc6:
   image: gitlab-registry.cern.ch/lhcb-docker/python-deployment:slc6
   script:
     - python --version
-    - python setup.py nosetests --cover-package LbPlatformUtils
+    - python setup.py test
     - mkdir -p cover_report && mv -f cover cover_report/$CI_JOB_NAME
     - python setup.py install && lb-describe-platform --flags
   artifacts:
@@ -38,7 +38,7 @@ slc5:
   image: gitlab-registry.cern.ch/lhcb-docker/python-deployment:slc5
   script:
     - python --version
-    - python setup.py nosetests --cover-package LbPlatformUtils
+    - python setup.py test
     - mkdir -p cover_report && mv -f cover cover_report/$CI_JOB_NAME
     - python setup.py install && lb-describe-platform --flags
   artifacts:
@@ -51,7 +51,7 @@ python2.7:
   image: gitlab-registry.cern.ch/lhcb-docker/python-deployment:python-2.7
   script:
     - python --version
-    - python setup.py nosetests --cover-package LbPlatformUtils
+    - python setup.py test
     - mkdir -p cover_report && mv -f cover cover_report/$CI_JOB_NAME
     - python setup.py install && lb-describe-platform --flags
     - python setup.py bdist_wheel --dist-dir public/${CI_PROJECT_NAME,,}
@@ -68,7 +68,7 @@ python3.5:
   image: gitlab-registry.cern.ch/lhcb-docker/python-deployment:python-3.5
   script:
     - python --version
-    - python setup.py nosetests --cover-package LbPlatformUtils
+    - python setup.py test
     - mkdir -p cover_report && mv -f build/lib/cover cover_report/$CI_JOB_NAME
     - python setup.py install && lb-describe-platform --flags
   artifacts:
@@ -81,7 +81,23 @@ python3.6:
   image: gitlab-registry.cern.ch/lhcb-docker/python-deployment:python-3.6
   script:
     - python --version
-    - python setup.py nosetests --cover-package LbPlatformUtils
+    - python setup.py test
+    - mkdir -p cover_report && mv -f build/lib/cover cover_report/$CI_JOB_NAME
+    - python setup.py install && lb-describe-platform --flags
+    - python setup.py sdist --dist-dir public/${CI_PROJECT_NAME,,}
+    - python setup.py bdist_wheel --dist-dir public/${CI_PROJECT_NAME,,}
+  artifacts:
+    paths:
+      - cover_report
+      - public
+    when: always
+    expire_in: 1 week
+
+python3.7:
+  image: gitlab-registry.cern.ch/lhcb-docker/python-deployment:python-3.7
+  script:
+    - python --version
+    - python setup.py test
     - mkdir -p cover_report && mv -f build/lib/cover cover_report/$CI_JOB_NAME
     - python setup.py install && lb-describe-platform --flags
     - python setup.py sdist --dist-dir public/${CI_PROJECT_NAME,,}
diff --git a/LbPlatformUtils/__init__.py b/LbPlatformUtils/__init__.py
index 9e6a3c8..489f9c8 100644
--- a/LbPlatformUtils/__init__.py
+++ b/LbPlatformUtils/__init__.py
@@ -17,7 +17,6 @@ Part of the code was imported from Gaudi and inspired by
 * https://github.com/HEP-SF/documents/tree/master/HSF-TN/draft-2015-NAM
 * https://github.com/HEP-SF/tools
 '''
-import platform
 import sys
 import os
 
@@ -33,7 +32,7 @@ except ImportError:  # pragma: no cover
 
 # map reference OSs to equivalent ones
 OS_ALIASES = {
-    'centos7': ['sl7', 'redhat7', 'suse42'],
+    'centos7': ['sl7', 'redhat7', 'suse42', 'suse15'],
     'slc6': ['sl6', 'centos6', 'redhat6'],
     'slc5': ['sl5', 'centos5', 'redhat5'],
     'ubuntu1604': [],
diff --git a/LbPlatformUtils/tests/test_describe.py b/LbPlatformUtils/tests/test_describe.py
index 6c8432e..dd58ff4 100644
--- a/LbPlatformUtils/tests/test_describe.py
+++ b/LbPlatformUtils/tests/test_describe.py
@@ -11,16 +11,7 @@
 # or submit itself to any jurisdiction.                                       #
 ###############################################################################
 import json
-
-
-def setup():
-    from LbPlatformUtils.tests import utils
-    utils.setup_all()
-
-
-def teardown():
-    from LbPlatformUtils.tests import utils
-    utils.teardown_all()
+from LbPlatformUtils.tests.utils import wrap_test
 
 
 # Content of https://lhcb-couchdb.cern.ch/nightlies-release/_design/names/_view/platforms?group=true
@@ -69,6 +60,7 @@ BINARY_TAGS_DATA = '''{"rows":[
 ]}'''
 
 
+@wrap_test
 def test_get_binary_tags():
     import LbPlatformUtils.describe
 
@@ -114,6 +106,7 @@ def test_get_binary_tags():
         'x86_64-slc6-gcc62-opt', 'x86_64-centos9-gcc9-opt']
 
 
+@wrap_test
 def test_script():
     import platform
     platform._system = 'Linux'
@@ -122,10 +115,6 @@ def test_script():
         'CentOS Linux release 7.4.1708 (Core)\n'
 
     # let's pretend we are on a supported platform
-    import sys
-    del sys.modules['LbPlatformUtils']
-    del sys.modules['LbPlatformUtils.inspect']
-    del sys.modules['LbPlatformUtils.describe']
     from LbPlatformUtils.describe import main
     main(args=[])
 
@@ -139,6 +128,7 @@ def test_script():
     main(args=['--platforms-list', '/some/random/file'])
 
 
+@wrap_test
 def test_host_binary_tag_script():
     import platform
     platform._system = 'Linux'
@@ -147,9 +137,5 @@ def test_host_binary_tag_script():
         'CentOS Linux release 7.4.1708 (Core)\n'
 
     # let's pretend we are on a supported platform
-    import sys
-    del sys.modules['LbPlatformUtils']
-    del sys.modules['LbPlatformUtils.inspect']
-    del sys.modules['LbPlatformUtils.describe']
     from LbPlatformUtils.describe import host_binary_tag_script
     host_binary_tag_script(args=[])
diff --git a/LbPlatformUtils/tests/test_detection.py b/LbPlatformUtils/tests/test_detection.py
index 9314afe..9e4e007 100644
--- a/LbPlatformUtils/tests/test_detection.py
+++ b/LbPlatformUtils/tests/test_detection.py
@@ -11,18 +11,10 @@
 # or submit itself to any jurisdiction.                                       #
 ###############################################################################
 import sys
+from LbPlatformUtils.tests.utils import wrap_test
 
 
-def setup():
-    from LbPlatformUtils.tests import utils
-    utils.setup_all()
-
-
-def teardown():
-    from LbPlatformUtils.tests import utils
-    utils.teardown_all()
-
-
+@wrap_test
 def test_os_id_function_selection():
     import platform
     import LbPlatformUtils.inspect as PU
@@ -50,6 +42,7 @@ def test_os_id_function_selection():
     del sys.modules['LbPlatformUtils.inspect']
 
 
+@wrap_test
 def test_rh_flavours():
     import platform
     import LbPlatformUtils.inspect as PU
@@ -101,6 +94,7 @@ def test_rh_flavours():
             '%s did not map to %s' % (reldata.strip(), expected)
 
 
+@wrap_test
 def test_suse():
     import platform
     import LbPlatformUtils.inspect as PU
@@ -114,6 +108,7 @@ def test_suse():
             '%s did not map to %s' % (platform._linux_dist_short, expected)
 
 
+@wrap_test
 def test_debian_flavours():
     import platform
     import LbPlatformUtils.inspect as PU
@@ -158,6 +153,7 @@ def test_debian_flavours():
             '%s did not map to %s' % (platform._linux_dist_short, expected)
 
 
+@wrap_test
 def test_macos():
     import platform
     import LbPlatformUtils.inspect as PU
@@ -170,6 +166,7 @@ def test_macos():
         assert PU._Darwin_os() == expected
 
 
+@wrap_test
 def test_windows():
     import platform
     import LbPlatformUtils.inspect as PU
@@ -183,6 +180,7 @@ def test_windows():
         assert PU._Windows_os() == expected
 
 
+@wrap_test
 def test_unknown_os():
     import platform
     import LbPlatformUtils.inspect as PU
@@ -190,6 +188,7 @@ def test_unknown_os():
     assert PU._unknown_os() == 'unknown'
 
 
+@wrap_test
 def test_host_os():
     import platform
     import LbPlatformUtils as PU
@@ -223,6 +222,7 @@ def test_host_os():
             assert PU.host_os() == expected
 
 
+@wrap_test
 def test_microarch_flags():
     import LbPlatformUtils.inspect as PUI
     open._overrides['/proc/cpuinfo'] = 'flags           : sse2 sse4_2 abc xyz'
@@ -235,6 +235,7 @@ def test_microarch_flags():
     assert PUI.microarch_flags() == set()
 
 
+@wrap_test
 def test_model_name():
     import LbPlatformUtils.inspect as PUI
     expected = 'Intel(R) Core(TM) i7-7560U CPU @ 2.40GHz'
@@ -248,6 +249,7 @@ def test_model_name():
     assert PUI.model_name() == 'unknown'
 
 
+@wrap_test
 def test_dirac_platform():
     import platform
     import LbPlatformUtils.inspect as PUI
@@ -299,11 +301,9 @@ def test_dirac_platform():
             assert PU.dirac_platform() == expected
 
 
+@wrap_test
 def test_compiler_id():
     import subprocess
-    if 'LbPlatformUtils.inspect' in sys.modules:
-        del sys.modules['LbPlatformUtils.inspect']
-    import LbPlatformUtils
     import LbPlatformUtils.inspect as PUI
 
     from contextlib import contextmanager
diff --git a/LbPlatformUtils/tests/utils.py b/LbPlatformUtils/tests/utils.py
index 935b843..c1540e9 100644
--- a/LbPlatformUtils/tests/utils.py
+++ b/LbPlatformUtils/tests/utils.py
@@ -46,8 +46,9 @@ class MockOpen(object):
     '''
     Mock open function to hijack read of some system files.
     '''
-    def __init__(self):
+    def __init__(self, orig):
         self._overrides = {}
+        self._orig = orig
 
     def __call__(self, *args, **kwargs):
         from StringIO import StringIO
@@ -65,12 +66,12 @@ class MockOpen(object):
             else:
                 return StringIO(data)
         else:
-            return orig_open(*args, **kwargs)
+            return self._orig(*args, **kwargs)
 
 
 def setup_open():
     import __builtin__
-    __builtin__.open = MockOpen()
+    __builtin__.open = MockOpen(orig_open)
 
     def mock_exists(path):
         if path in open._overrides:
@@ -90,7 +91,7 @@ def teardown_open():
 
 def setup_urlopen():
     import urllib2
-    urllib2.urlopen = MockOpen()
+    urllib2.urlopen = MockOpen(orig_urlopen)
 
 
 def teardown_urlopen():
@@ -106,7 +107,14 @@ def teardown_platform():
     sys.modules['platform'] = orig_platform
 
 
+def unload_modules():
+    for m in ('LbPlatformUtils.inspect', 'LbPlatformUtils.describe', 'LbPlatformUtils'):
+        if m in sys.modules:
+            del sys.modules[m]
+
+
 def setup_all():
+    unload_modules()
     setup_open()
     setup_urlopen()
     setup_platform()
@@ -116,3 +124,19 @@ def teardown_all():
     teardown_open()
     teardown_urlopen()
     teardown_platform()
+    unload_modules()
+
+
+def wrap_test(f):
+    from nose2.tools.decorators import with_setup, with_teardown
+    return with_teardown(teardown_all)(with_setup(setup_all)(f))
+
+
+class Layer(object):
+    @classmethod
+    def setUp(cls):
+        setup_all()
+
+    @classmethod
+    def tearDown(cls):
+        teardown_all()
diff --git a/nose2.cfg b/nose2.cfg
new file mode 100644
index 0000000..5e506ab
--- /dev/null
+++ b/nose2.cfg
@@ -0,0 +1,13 @@
+[unittest]
+plugins = nose2.plugins.doctests
+
+[coverage]
+always-on = True
+coverage-report = term-missing
+                  html
+
+[doctest]
+always-on = True
+
+[output-buffer]
+always-on = True
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index fa779c9..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-[nosetests]
-verbosity=2
-detailed-errors=1
-with-doctest=1
-with-coverage=1
-cover-erase=1
-cover-html=1
diff --git a/setup.py b/setup.py
index 959cb35..4f0e975 100644
--- a/setup.py
+++ b/setup.py
@@ -96,14 +96,14 @@ setup(
         # Specify the Python versions you support here. In particular, ensure
         # that you indicate whether you support Python 2, Python 3 or both.
         'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.6',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
     ],
 
-    python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4',
+    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4',
 
     # This field adds keywords for your project which will appear on the
     # project page. What does your project relate to?
@@ -142,8 +142,10 @@ setup(
     # extras_require={  # Optional
     #     'dev': ['check-manifest'],
     # },
-    tests_require=['coverage'],
-    setup_requires=['nose>=1.0', 'setuptools_scm'],
+    setup_requires=['setuptools_scm'],
+
+    tests_require=['nose2', 'coverage'],
+    test_suite='nose2.collector.collector',
     # If there are data files included in your packages that need to be
     # installed, specify them here.
     #
-- 
GitLab