[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#927348: unblock: salt/2018.3.4+dfsg1-2



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package salt

This version fixes the test_xen_virtual test case (bug #922352) and
exposes tornado4 as tornado for zmq.eventloop.ioloop (bug #924763). Our
salt 2018.3.3+dfsg1-1 package introduced a big patch to use
python3-tornado4 (instead of python3-tornado) due to missing support for
tornado version 5. Without the fix for #924763, zmq.eventloop.ioloop
will import tornado version 5 (if python3-tornado is installed).

I also included fix-various-spelling-mistakes.patch which fixes several
spelling mistakes. Because this patch file is long, I excluded it from the
attached debdiff.

This version also switches from the a pre-release git snapshot to the
official 2018.3.4 release. The only difference between this snapshot and
the release are two commits ("Fix ssh on Windows" and "Update url to
libsodium for mac builds") and that the release tarball ships less files
than what can be found in git.

For that reason, the attached debdiff is created with this command:

debdiff --exclude fix-various-spelling-mistakes.patch
salt_2018.3.4~git20180207+dfsg1-1.dsc salt_2018.3.4+dfsg1-2.dsc |
filterdiff -i '*/debian/*' -i '*/tests/*/test_ssh.py' -i
'*/salt/modules/ssh.py' -i '*/pkg/osx/build_env.sh' >
salt_2018.3.4+dfsg1-2.debdiff

Alternatively this more simple git diff command could be used:

git diff --diff-filter=ACM
debian/2018.3.4_git20180207+dfsg1-1..debian/2018.3.4+dfsg1-2

You can also look at all the individual commits on salsa:
https://salsa.debian.org/salt-team/salt/compare/debian%2F2018.3.4_git20180207+dfsg1-1...debian%2F2018.3.4+dfsg1-2

All 7575 unittest succeeded and I successfully tested this new salt
version on Debian unstable with our production environment setup
(running the highstate on a salt minion connected to the salt master).

unblock salt/2018.3.4+dfsg1-2

-- System Information:
Debian Release: buster/sid
  APT prefers disco
  APT policy: (500, 'disco')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.0.0-13-generic (SMP w/12 CPU cores)
Kernel taint flags: TAINT_WARN
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8), LANGUAGE=de_DE:en (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/changelog salt-2018.3.4+dfsg1/debian/changelog
--- salt-2018.3.4~git20180207+dfsg1/debian/changelog	2019-02-08 17:05:57.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/changelog	2019-04-17 20:26:11.000000000 +0200
@@ -1,3 +1,23 @@
+salt (2018.3.4+dfsg1-2) unstable; urgency=medium
+
+  * Fix test_xen_virtual on kernels with no Xen support (Closes: #922352)
+  * Expose tornado4 as tornado for zmq.eventloop.ioloop (Closes: #924763)
+
+ -- Benjamin Drung <benjamin.drung@cloud.ionos.com>  Wed, 17 Apr 2019 20:26:11 +0200
+
+salt (2018.3.4+dfsg1-1) unstable; urgency=medium
+
+  * New upstream release.
+  * Refresh patches
+  * Fix various spelling mistakes
+  * Drop NOTICE from salt-common (the upstream tarball does not contain it)
+  * Skip SampleConfTest and ExtendTestCase if the required sample conf or
+    templates directories are missing
+  * Run tests with LC_ALL=C.UTF-8
+  * Remove unused minified documentation CSS files
+
+ -- Benjamin Drung <benjamin.drung@cloud.ionos.com>  Fri, 05 Apr 2019 13:58:40 +0200
+
 salt (2018.3.4~git20180207+dfsg1-1) unstable; urgency=medium
 
   * New upstream pre-release snapshot.
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/patches/0001-Skip-SampleConfTest-if-sample-conf-directories-are-m.patch salt-2018.3.4+dfsg1/debian/patches/0001-Skip-SampleConfTest-if-sample-conf-directories-are-m.patch
--- salt-2018.3.4~git20180207+dfsg1/debian/patches/0001-Skip-SampleConfTest-if-sample-conf-directories-are-m.patch	1970-01-01 01:00:00.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/patches/0001-Skip-SampleConfTest-if-sample-conf-directories-are-m.patch	2019-04-03 16:36:21.000000000 +0200
@@ -0,0 +1,97 @@
+From 0473683aceaba9a975fc28f72ff80e8ab12dea2d Mon Sep 17 00:00:00 2001
+From: Benjamin Drung <benjamin.drung@cloud.ionos.com>
+Date: Wed, 3 Apr 2019 14:50:12 +0200
+Subject: [PATCH 1/2] Skip SampleConfTest if sample conf directories are
+ missing
+
+The release tarball does not contain `conf/cloud.profiles.d`,
+`conf/cloud.providers.d`, and `conf/cloud.maps.d`. Therefore the test
+cases will fail:
+
+```
+======================================================================
+ERROR: test_conf_cloud_maps_d_files_are_commented (unit.test_config.SampleConfTest)
+[CPU:0.0%|MEM:53.9%]
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "tests/unit/test_config.py", line 236, in test_conf_cloud_maps_d_files_are_commented
+    cloud_sample_files = os.listdir(SAMPLE_CONF_DIR + 'cloud.maps.d/')
+FileNotFoundError: [Errno 2] No such file or directory: 'conf/cloud.maps.d/'
+
+======================================================================
+ERROR: test_conf_cloud_profiles_d_files_are_commented (unit.test_config.SampleConfTest)
+[CPU:0.0%|MEM:53.9%]
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "tests/unit/test_config.py", line 200, in test_conf_cloud_profiles_d_files_are_commented
+    cloud_sample_files = os.listdir(SAMPLE_CONF_DIR + 'cloud.profiles.d/')
+FileNotFoundError: [Errno 2] No such file or directory: 'conf/cloud.profiles.d/'
+
+======================================================================
+ERROR: test_conf_cloud_providers_d_files_are_commented (unit.test_config.SampleConfTest)
+[CPU:0.0%|MEM:53.9%]
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "tests/unit/test_config.py", line 218, in test_conf_cloud_providers_d_files_are_commented
+    cloud_sample_files = os.listdir(SAMPLE_CONF_DIR + 'cloud.providers.d/')
+FileNotFoundError: [Errno 2] No such file or directory: 'conf/cloud.providers.d/'
+```
+
+Forwarded: https://github.com/saltstack/salt/pull/52403
+Signed-off-by: Benjamin Drung <benjamin.drung@cloud.ionos.com>
+---
+ tests/unit/test_config.py | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py
+index 740e086cf7..69b8aefb72 100644
+--- a/tests/unit/test_config.py
++++ b/tests/unit/test_config.py
+@@ -197,9 +197,12 @@ class SampleConfTest(TestCase):
+         commented out. This test loops through all of the files in that directory to check
+         for any lines that are not commented or blank.
+         '''
+-        cloud_sample_files = os.listdir(SAMPLE_CONF_DIR + 'cloud.profiles.d/')
++        cloud_sample_dir = SAMPLE_CONF_DIR + 'cloud.profiles.d/'
++        if not os.path.exists(cloud_sample_dir):
++            self.skipTest("Sample config directory '{}' is missing.".format(cloud_sample_dir))
++        cloud_sample_files = os.listdir(cloud_sample_dir)
+         for conf_file in cloud_sample_files:
+-            profile_conf = SAMPLE_CONF_DIR + 'cloud.profiles.d/' + conf_file
++            profile_conf = cloud_sample_dir + conf_file
+             ret = salt.config._read_conf_file(profile_conf)
+             self.assertEqual(
+                 ret,
+@@ -215,9 +218,12 @@ class SampleConfTest(TestCase):
+         commented out. This test loops through all of the files in that directory to check
+         for any lines that are not commented or blank.
+         '''
+-        cloud_sample_files = os.listdir(SAMPLE_CONF_DIR + 'cloud.providers.d/')
++        cloud_sample_dir = SAMPLE_CONF_DIR + 'cloud.providers.d/'
++        if not os.path.exists(cloud_sample_dir):
++            self.skipTest("Sample config directory '{}' is missing.".format(cloud_sample_dir))
++        cloud_sample_files = os.listdir(cloud_sample_dir)
+         for conf_file in cloud_sample_files:
+-            provider_conf = SAMPLE_CONF_DIR + 'cloud.providers.d/' + conf_file
++            provider_conf = cloud_sample_dir + conf_file
+             ret = salt.config._read_conf_file(provider_conf)
+             self.assertEqual(
+                 ret,
+@@ -233,9 +239,12 @@ class SampleConfTest(TestCase):
+         commented out. This test loops through all of the files in that directory to check
+         for any lines that are not commented or blank.
+         '''
+-        cloud_sample_files = os.listdir(SAMPLE_CONF_DIR + 'cloud.maps.d/')
++        cloud_sample_dir = SAMPLE_CONF_DIR + 'cloud.maps.d/'
++        if not os.path.exists(cloud_sample_dir):
++            self.skipTest("Sample config directory '{}' is missing.".format(cloud_sample_dir))
++        cloud_sample_files = os.listdir(cloud_sample_dir)
+         for conf_file in cloud_sample_files:
+-            map_conf = SAMPLE_CONF_DIR + 'cloud.maps.d/' + conf_file
++            map_conf = cloud_sample_dir + conf_file
+             ret = salt.config._read_conf_file(map_conf)
+             self.assertEqual(
+                 ret,
+-- 
+2.17.1
+
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/patches/0002-Explicitly-import-attributes-from-tornado.patch salt-2018.3.4+dfsg1/debian/patches/0002-Explicitly-import-attributes-from-tornado.patch
--- salt-2018.3.4~git20180207+dfsg1/debian/patches/0002-Explicitly-import-attributes-from-tornado.patch	2019-02-07 22:44:26.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/patches/0002-Explicitly-import-attributes-from-tornado.patch	2019-04-17 19:46:54.000000000 +0200
@@ -1046,7 +1046,7 @@
  import weakref
  from datetime import datetime
  
-@@ -2659,7 +2659,7 @@ class GitFS(GitBase):
+@@ -2672,7 +2672,7 @@ class GitFS(GitBase):
          exited.
          '''
          # No need to get the ioloop reference if we're not initializing remotes
@@ -1314,7 +1314,7 @@
              mock_opts["process_count_max"] = process_count_max
  
 -            io_loop = tornado.ioloop.IOLoop()
-+            io_loop =  IOLoop()
++            io_loop = IOLoop()
              minion = salt.minion.Minion(mock_opts, jid_queue=[], io_loop=io_loop)
              try:
  
@@ -1327,25 +1327,25 @@
  
                  # up until process_count_max: gen.sleep does not get called, processes are started normally
                  for i in range(process_count_max):
-@@ -241,7 +243,7 @@ class MinionTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
+@@ -242,7 +244,7 @@ class MinionTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
                  patch('salt.utils.process.SignalHandlingMultiprocessingProcess.join', MagicMock(return_value=True)):
              mock_opts = self.get_config('minion', from_scratch=True)
              mock_opts['beacons_before_connect'] = True
 -            io_loop = tornado.ioloop.IOLoop()
-+            io_loop =  IOLoop()
++            io_loop = IOLoop()
              io_loop.make_current()
              minion = salt.minion.Minion(mock_opts, io_loop=io_loop)
              try:
-@@ -267,7 +269,7 @@ class MinionTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
+@@ -269,7 +271,7 @@ class MinionTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
                  patch('salt.utils.process.SignalHandlingMultiprocessingProcess.join', MagicMock(return_value=True)):
              mock_opts = self.get_config('minion', from_scratch=True)
              mock_opts['scheduler_before_connect'] = True
 -            io_loop = tornado.ioloop.IOLoop()
-+            io_loop =  IOLoop()
++            io_loop = IOLoop()
              io_loop.make_current()
              minion = salt.minion.Minion(mock_opts, io_loop=io_loop)
              try:
-@@ -295,7 +297,7 @@ class MinionTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
+@@ -297,7 +299,7 @@ class MinionTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
  
  
  @skipIf(NO_MOCK, NO_MOCK_REASON)
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/patches/0002-Skip-ExtendTestCase-if-templates-directory-is-missin.patch salt-2018.3.4+dfsg1/debian/patches/0002-Skip-ExtendTestCase-if-templates-directory-is-missin.patch
--- salt-2018.3.4~git20180207+dfsg1/debian/patches/0002-Skip-ExtendTestCase-if-templates-directory-is-missin.patch	1970-01-01 01:00:00.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/patches/0002-Skip-ExtendTestCase-if-templates-directory-is-missin.patch	2019-04-03 16:36:21.000000000 +0200
@@ -0,0 +1,54 @@
+From e74f78fca666e730f48f24082e4824b67af7eb9f Mon Sep 17 00:00:00 2001
+From: Benjamin Drung <benjamin.drung@cloud.ionos.com>
+Date: Wed, 3 Apr 2019 15:04:20 +0200
+Subject: [PATCH 2/2] Skip ExtendTestCase if templates directory is missing
+
+The release tarball does not contain the `templates` directory.
+Therefore `ExtendTestCase` will fail:
+
+```
+======================================================================
+ERROR: test_run (unit.utils.test_extend.ExtendTestCase)
+[CPU:0.0%|MEM:53.9%]
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "tests/unit/utils/test_extend.py", line 40, in test_run
+    out = salt.utils.extend.run('test', 'test', 'this description', integration.CODE_DIR, False)
+  File "salt/utils/extend.py", line 242, in run
+    MODULE_OPTIONS = _fetch_templates(os.path.join(salt_dir, 'templates'))
+  File "salt/utils/extend.py", line 76, in _fetch_templates
+    for item in os.listdir(src):
+FileNotFoundError: [Errno 2] No such file or directory: ' templates'
+```
+
+Forwarded: https://github.com/saltstack/salt/pull/52403
+Signed-off-by: Benjamin Drung <benjamin.drung@cloud.ionos.com>
+---
+ tests/unit/utils/test_extend.py | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tests/unit/utils/test_extend.py b/tests/unit/utils/test_extend.py
+index 2cf90fcaaf..9cbb767ca5 100644
+--- a/tests/unit/utils/test_extend.py
++++ b/tests/unit/utils/test_extend.py
+@@ -14,7 +14,7 @@ import shutil
+ from datetime import date
+ 
+ # Import Salt Testing libs
+-from tests.support.unit import TestCase
++from tests.support.unit import TestCase, skipIf
+ from tests.support.mock import MagicMock, patch
+ 
+ # Import salt libs
+@@ -35,6 +35,8 @@ class ExtendTestCase(TestCase):
+                 shutil.rmtree(self.out, True)
+         os.chdir(self.starting_dir)
+ 
++    @skipIf(not os.path.exists(os.path.join(integration.CODE_DIR, 'templates')),
++            "Test template directory 'templates/' missing.")
+     def test_run(self):
+         with patch('sys.exit', MagicMock):
+             out = salt.utils.extend.run('test', 'test', 'this description', integration.CODE_DIR, False)
+-- 
+2.17.1
+
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/patches/0003-Use-renamed-python3-tornado4.patch salt-2018.3.4+dfsg1/debian/patches/0003-Use-renamed-python3-tornado4.patch
--- salt-2018.3.4~git20180207+dfsg1/debian/patches/0003-Use-renamed-python3-tornado4.patch	2019-02-08 15:19:06.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/patches/0003-Use-renamed-python3-tornado4.patch	2019-04-17 19:47:11.000000000 +0200
@@ -21,7 +21,7 @@
  salt/transport/ipc.py                         | 23 +++++++++++-----
  salt/transport/mixins/auth.py                 |  5 +++-
  salt/transport/tcp.py                         | 26 +++++++++++++------
- salt/transport/zeromq.py                      | 11 +++++---
+ salt/transport/zeromq.py                      | 20 +++++++++-----
  salt/utils/asynchronous.py                    |  8 ++++--
  salt/utils/event.py                           |  8 ++++--
  salt/utils/gitfs.py                           |  5 +++-
@@ -41,11 +41,11 @@
  tests/unit/test_minion.py                     | 18 +++++++++----
  tests/unit/transport/test_ipc.py              | 11 +++++---
  tests/unit/transport/test_tcp.py              | 14 +++++++---
- tests/unit/transport/test_zeromq.py           |  8 ++++--
+ tests/unit/transport/test_zeromq.py           | 13 ++++++++--
  tests/unit/utils/test_asynchronous.py         | 11 +++++---
  tests/unit/utils/test_context.py              | 11 +++++---
  tests/unit/utils/test_event.py                |  5 +++-
- 41 files changed, 303 insertions(+), 104 deletions(-)
+ 41 files changed, 314 insertions(+), 107 deletions(-)
 
 diff --git a/doc/conf.py b/doc/conf.py
 index 23d3442c16..720026b823 100644
@@ -454,7 +454,17 @@
 index 999197ba3a..cd1588e1cc 100644
 --- a/salt/transport/zeromq.py
 +++ b/salt/transport/zeromq.py
-@@ -47,9 +47,14 @@ except ImportError:
+@@ -36,9 +36,6 @@ from salt.exceptions import SaltReqTimeoutError
+ from salt._compat import ipaddress
+ 
+ from salt.utils.zeromq import zmq, ZMQDefaultLoop, install_zmq, ZMQ_VERSION_INFO, LIBZMQ_VERSION_INFO
+-import zmq.error
+-import zmq.eventloop.ioloop
+-import zmq.eventloop.zmqstream
+ 
+ try:
+     import zmq.utils.monitor
+@@ -47,9 +44,20 @@ except ImportError:
      HAS_ZMQ_MONITOR = False
  
  # Import Tornado Libs
@@ -465,10 +475,16 @@
 +    import tornado4
 +    import tornado4.gen as tornado_gen
 +    from tornado4.concurrent import Future as TornadoFuture
++    # Expose tornado4 as tornado for zmq.eventloop.ioloop
++    sys.modules['tornado'] = tornado4
 +except ImportError:
 +    import tornado
 +    import tornado.gen as tornado_gen
 +    from tornado.concurrent import Future as TornadoFuture
++
++import zmq.error
++import zmq.eventloop.ioloop
++import zmq.eventloop.zmqstream
  
  # Import third party libs
  try:
@@ -603,7 +619,7 @@
 index 715a9eb43e..6a247ceb8b 100644
 --- a/salt/version.py
 +++ b/salt/version.py
-@@ -584,7 +584,7 @@ def dependency_information(include_salt_cloud=False):
+@@ -590,7 +590,7 @@ def dependency_information(include_salt_cloud=False):
          ('RAET', 'raet', '__version__'),
          ('ZMQ', 'zmq', 'zmq_version'),
          ('Mako', 'mako', '__version__'),
@@ -612,7 +628,7 @@
          ('timelib', 'timelib', 'version'),
          ('dateutil', 'dateutil', '__version__'),
          ('pygit2', 'pygit2', '__version__'),
-@@ -610,7 +610,13 @@ def dependency_information(include_salt_cloud=False):
+@@ -616,7 +616,13 @@ def dependency_information(include_salt_cloud=False):
              yield name, attr
              continue
          try:
@@ -685,8 +701,8 @@
 index 493c5de8ab..20cb5c3eda 100644
 --- a/tests/integration/modules/test_ssh.py
 +++ b/tests/integration/modules/test_ssh.py
-@@ -17,7 +17,10 @@ from tests.support.helpers import skip_if_binaries_missing
- import salt.utils.files
+@@ -18,7 +18,10 @@ from tests.support.helpers import skip_if_binaries_missing
+ import salt.utils.platform
  
  # Import 3rd-party libs
 -from tornado.httpclient import HTTPClient
@@ -863,21 +879,30 @@
  import salt.config
  from salt.ext import six
 diff --git a/tests/unit/transport/test_zeromq.py b/tests/unit/transport/test_zeromq.py
-index 798ab0c6c6..4af9cd4547 100644
+index 798ab0c6c6..3846c30cb3 100644
 --- a/tests/unit/transport/test_zeromq.py
 +++ b/tests/unit/transport/test_zeromq.py
-@@ -23,8 +23,12 @@ import zmq.eventloop.ioloop
- # support pyzmq 13.0.x, TODO: remove once we force people to 14.0.x
- if not hasattr(zmq.eventloop.ioloop, 'ZMQIOLoop'):
-     zmq.eventloop.ioloop.ZMQIOLoop = zmq.eventloop.ioloop.IOLoop
--from tornado.testing import AsyncTestCase
--import tornado.gen as tornado_gen
+@@ -19,12 +19,21 @@ except ImportError:
+     from distro import linux_distribution
+ 
+ # Import 3rd-party libs
 +try:
++    import tornado4
 +    from tornado4.testing import AsyncTestCase
 +    import tornado4.gen as tornado_gen
++    # Expose tornado4 as tornado for zmq.eventloop.ioloop
++    import sys
++    sys.modules['tornado'] = tornado4
 +except ImportError:
 +    from tornado.testing import AsyncTestCase
 +    import tornado.gen as tornado_gen
++
+ import zmq.eventloop.ioloop
+ # support pyzmq 13.0.x, TODO: remove once we force people to 14.0.x
+ if not hasattr(zmq.eventloop.ioloop, 'ZMQIOLoop'):
+     zmq.eventloop.ioloop.ZMQIOLoop = zmq.eventloop.ioloop.IOLoop
+-from tornado.testing import AsyncTestCase
+-import tornado.gen as tornado_gen
  
  # Import Salt libs
  import salt.config
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/patches/Fix-test_xen_virtual-on-kernels-with-no-Xen-support.patch salt-2018.3.4+dfsg1/debian/patches/Fix-test_xen_virtual-on-kernels-with-no-Xen-support.patch
--- salt-2018.3.4~git20180207+dfsg1/debian/patches/Fix-test_xen_virtual-on-kernels-with-no-Xen-support.patch	1970-01-01 01:00:00.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/patches/Fix-test_xen_virtual-on-kernels-with-no-Xen-support.patch	2019-04-17 19:22:52.000000000 +0200
@@ -0,0 +1,69 @@
+From fb6eb4d0575adba07cb22efa862366cdb3e523ea Mon Sep 17 00:00:00 2001
+From: Benjamin Drung <benjamin.drung@cloud.ionos.com>
+Date: Wed, 17 Apr 2019 17:18:01 +0200
+Subject: [PATCH] Fix test_xen_virtual on kernels with no Xen support
+
+The latest version of salt is failing its autopkgtests on ppc64el and s390x
+architectures in Ubuntu:
+
+```
+[...]
+FAIL: test_xen_virtual (unit.grains.test_core.CoreGrainsTestCase)
+[CPU:0.0%|MEM:53.3%]
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "tests/unit/grains/test_core.py", line 701, in test_xen_virtual
+    'Xen PV DomU'
+AssertionError: None != 'Xen PV DomU'
+
+----------------------------------------------------------------------
+Ran 7575 tests in 3249.235s
+[...]
+```
+
+  (http://autopkgtest.ubuntu.com/packages/s/salt/disco/ppc64el)
+
+The cause of this failure is an improper test which mocks up an isfile check
+for /sys/bus/xen/drivers/xenconsole, but which doesn't also mock up the
+check for the /sys/bus/xen directory; so if run on a kernel with no Xen
+support at all, the test will fail.
+
+The test happens to pass on the other architectures on which Ubuntu runs
+autopkgtests, because these happen to be architectures which have Xen
+support and Xen happens to be enabled in the kernels on these architectures.
+But it's a bad test that depends on the kernel instead of actually unit
+testing the code.
+
+Therefore also mock `os.path.isdir` to return `True` for the path
+`/sys/bus/xen`.
+
+Bug-Debian: https://bugs.debian.org/922352
+Forwarded: https://github.com/saltstack/salt/pull/52582
+Signed-off-by: Benjamin Drung <benjamin.drung@cloud.ionos.com>
+---
+ tests/unit/grains/test_core.py | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/tests/unit/grains/test_core.py b/tests/unit/grains/test_core.py
+index b2f784b14f..6dbeb42a75 100644
+--- a/tests/unit/grains/test_core.py
++++ b/tests/unit/grains/test_core.py
+@@ -690,11 +690,10 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
+         '''
+         Test if OS grains are parsed correctly in Ubuntu Xenial Xerus
+         '''
+-        with patch.object(os.path, 'isfile', MagicMock(return_value=False)):
+-            with patch.dict(core.__salt__, {'cmd.run': MagicMock(return_value='')}), \
+-                patch.object(os.path,
+-                             'isfile',
+-                             MagicMock(side_effect=lambda x: True if x == '/sys/bus/xen/drivers/xenconsole' else False)):
++        with patch.multiple(os.path, isdir=MagicMock(side_effect=lambda x: x == '/sys/bus/xen'),
++                            isfile=MagicMock(side_effect=lambda x:
++                                             x == '/sys/bus/xen/drivers/xenconsole')):
++            with patch.dict(core.__salt__, {'cmd.run': MagicMock(return_value='')}):
+                 log.debug('Testing Xen')
+                 self.assertEqual(
+                     core._virtual({'kernel': 'Linux'}).get('virtual_subtype'),
+-- 
+2.20.1
+
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/patches/series salt-2018.3.4+dfsg1/debian/patches/series
--- salt-2018.3.4~git20180207+dfsg1/debian/patches/series	2019-02-08 17:05:14.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/patches/series	2019-04-17 17:38:18.000000000 +0200
@@ -4,6 +4,8 @@
 remove-privacy-breach.patch
 Make-default-pki-directory-configurable.patch
 Do-not-load-zyppnotify-file-on-module-import.patch
+0001-Skip-SampleConfTest-if-sample-conf-directories-are-m.patch
+0002-Skip-ExtendTestCase-if-templates-directory-is-missin.patch
 disable-failing-tests.patch
 run-salt-master-as-salt-user.patch
 Support-unittest.mock-from-Python-3.6-again.patch
@@ -12,6 +14,8 @@
 test_argspec_report-Fix-expected-argspec_report-resu.patch
 Silence-linux_distribution-deprecation-warning.patch
 Skip-test_module_name_source_match.patch
+Fix-test_xen_virtual-on-kernels-with-no-Xen-support.patch
+fix-various-spelling-mistakes.patch
 0001-Import-tornado.gen-as-tornado_gen.patch
 0002-Explicitly-import-attributes-from-tornado.patch
 0003-Use-renamed-python3-tornado4.patch
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/patches/Skip-test_module_name_source_match.patch salt-2018.3.4+dfsg1/debian/patches/Skip-test_module_name_source_match.patch
--- salt-2018.3.4~git20180207+dfsg1/debian/patches/Skip-test_module_name_source_match.patch	2019-02-08 17:05:14.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/patches/Skip-test_module_name_source_match.patch	2019-04-03 16:14:43.000000000 +0200
@@ -52,7 +52,7 @@
  
  # Import Salt libs
  import salt.utils.path
-@@ -95,6 +96,7 @@ class BadTestModuleNamesTestCase(TestCase):
+@@ -94,6 +95,7 @@ class BadTestModuleNamesTestCase(TestCase):
          error_msg += 'If it is a tests module, then please rename as suggested.'
          self.assertEqual([], bad_names, error_msg)
  
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/rules salt-2018.3.4+dfsg1/debian/rules
--- salt-2018.3.4~git20180207+dfsg1/debian/rules	2018-12-21 19:21:00.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/rules	2019-04-05 14:24:10.000000000 +0200
@@ -7,6 +7,7 @@
 
 override_dh_auto_build:
 	dh_auto_build
+	rm -f doc/_themes/saltstack/static/css/*.min.css
 	HTML_THEME=saltstack make -C doc html SPHINXBUILD=/usr/share/sphinx/scripts/python3/sphinx-build
 	HTML_THEME=saltstack make -C doc man SPHINXBUILD=/usr/share/sphinx/scripts/python3/sphinx-build
 
@@ -20,7 +21,7 @@
 
 override_dh_auto_test:
 ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
-	python3 ./tests/runtests.py -v --no-report --unit
+	LC_ALL=C.UTF-8 python3 ./tests/runtests.py -v --no-report --unit
 endif
 
 override_dh_install:
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/salt-common.docs salt-2018.3.4+dfsg1/debian/salt-common.docs
--- salt-2018.3.4~git20180207+dfsg1/debian/salt-common.docs	2019-02-08 15:19:07.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/salt-common.docs	1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-NOTICE
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/debian/salt-doc.links salt-2018.3.4+dfsg1/debian/salt-doc.links
--- salt-2018.3.4~git20180207+dfsg1/debian/salt-doc.links	2019-02-07 19:18:52.000000000 +0100
+++ salt-2018.3.4+dfsg1/debian/salt-doc.links	2019-04-05 14:43:18.000000000 +0200
@@ -5,7 +5,5 @@
 usr/share/javascript/sphinxdoc/1.0/searchtools.js usr/share/doc/salt/html/_static/searchtools.js
 usr/share/javascript/sphinxdoc/1.0/sidebar.js usr/share/doc/salt/html/_static/sidebar.js
 usr/share/javascript/sphinxdoc/1.0/underscore.js usr/share/doc/salt/html/_static/underscore.js
-usr/share/twitter-bootstrap/files/css/bootstrap-responsive.min.css usr/share/doc/salt/html/_static/css/bootstrap-responsive.min.css
-usr/share/twitter-bootstrap/files/css/bootstrap.min.css usr/share/doc/salt/html/_static/css/bootstrap.min.css
 usr/share/twitter-bootstrap/files/js/bootstrap.js usr/share/doc/salt/html/_static/js/vendor/bootstrap.js
 usr/share/twitter-bootstrap/files/js/bootstrap.min.js usr/share/doc/salt/html/_static/js/vendor/bootstrap.min.js
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/pkg/osx/build_env.sh salt-2018.3.4+dfsg1/pkg/osx/build_env.sh
--- salt-2018.3.4~git20180207+dfsg1/pkg/osx/build_env.sh	2019-02-07 17:55:37.000000000 +0100
+++ salt-2018.3.4+dfsg1/pkg/osx/build_env.sh	2019-02-25 16:53:25.000000000 +0100
@@ -177,7 +177,7 @@
 ############################################################################
 echo -n -e "\033]0;Build_Env: libsodium: download\007"
 
-PKGURL="https://download.libsodium.org/libsodium/releases/libsodium-1.0.15.tar.gz";
+PKGURL="https://download.libsodium.org/libsodium/releases/old/libsodium-1.0.15.tar.gz";
 PKGDIR="libsodium-1.0.15"
 
 download $PKGURL
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/salt/modules/ssh.py salt-2018.3.4+dfsg1/salt/modules/ssh.py
--- salt-2018.3.4~git20180207+dfsg1/salt/modules/ssh.py	2019-02-07 17:55:37.000000000 +0100
+++ salt-2018.3.4+dfsg1/salt/modules/ssh.py	2019-02-25 15:53:14.000000000 +0100
@@ -19,7 +19,6 @@
 import subprocess
 
 # Import salt libs
-from salt.ext import six
 import salt.utils.decorators.path
 import salt.utils.data
 import salt.utils.files
@@ -44,9 +43,8 @@
 
 
 def __virtual__():
-    # TODO: This could work on windows with some love
-    if salt.utils.platform.is_windows():
-        return (False, 'The module cannot be loaded on windows.')
+    if not salt.utils.path.which('ssh'):
+        return False, 'The module requires the ssh binary.'
     return True
 
 
@@ -753,9 +751,10 @@
         if not os.path.isdir(os.path.dirname(fconfig)):
             dpath = os.path.dirname(fconfig)
             os.makedirs(dpath)
-            if os.geteuid() == 0:
-                os.chown(dpath, uinfo['uid'], uinfo['gid'])
-            os.chmod(dpath, 448)
+            if not salt.utils.platform.is_windows():
+                if os.geteuid() == 0:
+                    os.chown(dpath, uinfo['uid'], uinfo['gid'])
+                os.chmod(dpath, 448)
             # If SELINUX is available run a restorecon on the file
             rcon = salt.utils.path.which('restorecon')
             if rcon:
@@ -784,9 +783,10 @@
             raise CommandExecutionError(msg.format(exc))
 
         if new_file:
-            if os.geteuid() == 0:
-                os.chown(fconfig, uinfo['uid'], uinfo['gid'])
-            os.chmod(fconfig, 384)
+            if not salt.utils.platform.is_windows():
+                if os.geteuid() == 0:
+                    os.chown(fconfig, uinfo['uid'], uinfo['gid'])
+                os.chmod(fconfig, 384)
             # If SELINUX is available run a restorecon on the file
             rcon = salt.utils.path.which('restorecon')
             if rcon:
@@ -1104,10 +1104,11 @@
     ssh_hostname = _hostname_and_port_to_ssh_hostname(hostname, port)
     cmd = ['ssh-keygen', '-R', ssh_hostname, '-f', full]
     cmd_result = __salt__['cmd.run'](cmd, python_shell=False)
-    # ssh-keygen creates a new file, thus a chown is required.
-    if os.geteuid() == 0 and user:
-        uinfo = __salt__['user.info'](user)
-        os.chown(full, uinfo['uid'], uinfo['gid'])
+    if not salt.utils.platform.is_windows():
+        # ssh-keygen creates a new file, thus a chown is required.
+        if os.geteuid() == 0 and user:
+            uinfo = __salt__['user.info'](user)
+            os.chown(full, uinfo['uid'], uinfo['gid'])
     return {'status': 'removed', 'comment': cmd_result}
 
 
@@ -1317,12 +1318,13 @@
             "Couldn't append to known hosts file: '{0}'".format(exception)
         )
 
-    if os.geteuid() == 0 and user:
-        os.chown(full, uinfo['uid'], uinfo['gid'])
-    if origmode:
-        os.chmod(full, origmode)
-    else:
-        os.chmod(full, 0o600)
+    if not salt.utils.platform.is_windows():
+        if os.geteuid() == 0 and user:
+            os.chown(full, uinfo['uid'], uinfo['gid'])
+        if origmode:
+            os.chmod(full, origmode)
+        else:
+            os.chmod(full, 0o600)
 
     if key and hash_known_hosts:
         cmd_result = __salt__['ssh.hash_known_hosts'](user=user, config=full)
@@ -1446,10 +1448,11 @@
     cmd = ['ssh-keygen', '-H', '-f', full]
     cmd_result = __salt__['cmd.run'](cmd, python_shell=False)
     os.chmod(full, origmode)
-    # ssh-keygen creates a new file, thus a chown is required.
-    if os.geteuid() == 0 and user:
-        uinfo = __salt__['user.info'](user)
-        os.chown(full, uinfo['uid'], uinfo['gid'])
+    if not salt.utils.platform.is_windows():
+        # ssh-keygen creates a new file, thus a chown is required.
+        if os.geteuid() == 0 and user:
+            uinfo = __salt__['user.info'](user)
+            os.chown(full, uinfo['uid'], uinfo['gid'])
     return {'status': 'updated', 'comment': cmd_result}
 
 
diff -Nru --exclude fix-various-spelling-mistakes.patch salt-2018.3.4~git20180207+dfsg1/tests/integration/modules/test_ssh.py salt-2018.3.4+dfsg1/tests/integration/modules/test_ssh.py
--- salt-2018.3.4~git20180207+dfsg1/tests/integration/modules/test_ssh.py	2019-02-07 17:55:37.000000000 +0100
+++ salt-2018.3.4+dfsg1/tests/integration/modules/test_ssh.py	2019-02-25 15:53:14.000000000 +0100
@@ -15,6 +15,7 @@
 
 # Import salt libs
 import salt.utils.files
+import salt.utils.platform
 
 # Import 3rd-party libs
 from tornado.httpclient import HTTPClient
@@ -70,7 +71,10 @@
         shutil.copyfile(
              os.path.join(FILES, 'ssh', 'authorized_keys'),
              AUTHORIZED_KEYS)
-        ret = self.run_function('ssh.auth_keys', ['root', AUTHORIZED_KEYS])
+        user = 'root'
+        if salt.utils.platform.is_windows():
+            user = 'Administrator'
+        ret = self.run_function('ssh.auth_keys', [user, AUTHORIZED_KEYS])
         self.assertEqual(len(list(ret.items())), 1)  # exactly one key is found
         key_data = list(ret.items())[0][1]
         try:

Reply to: