summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToshio Kuratomi <a.badger@gmail.com>2019-06-28 13:09:36 -0700
committerToshio Kuratomi <a.badger@gmail.com>2019-07-01 07:43:51 -0700
commit7d4e9b279e15286b51a8d50fbb80a84cdf1c865a (patch)
tree29eb14678a0ee6e50d55b32e277256e0422c8dbe
parent28816088e4d815d5997d0eaa9f3f4b89c4a149bc (diff)
downloadansible-7d4e9b279e15286b51a8d50fbb80a84cdf1c865a.tar.gz
[stable-2.7] Skip tests with unsatisfied deps (#55853)
* Skip gitlab tests if dependencies aren't met * Skip certain unittests if passlib is not installed * Fix tests with deps on paramiko to skip if paramiko is not installed * Use pytest to skip for cloudstack If either on Python-2.6 or the cs library is not installed we cannot run this test so skip it. (cherry picked from commit 8acf71f78fce89d70a58fc45ee528003c4785e6b) Co-authored-by: Toshio Kuratomi <a.badger@gmail.com>
-rw-r--r--test/units/plugins/filter/test_network.py8
-rw-r--r--test/units/plugins/lookup/test_password.py117
-rw-r--r--test/units/utils/test_encrypt.py31
3 files changed, 103 insertions, 53 deletions
diff --git a/test/units/plugins/filter/test_network.py b/test/units/plugins/filter/test_network.py
index d1f4b49282..b184ab1236 100644
--- a/test/units/plugins/filter/test_network.py
+++ b/test/units/plugins/filter/test_network.py
@@ -23,7 +23,9 @@ import sys
import pytest
from ansible.compat.tests import unittest
-from ansible.plugins.filter.network import parse_xml, type5_pw, hash_salt, comp_type5
+from ansible.plugins.filter.network import (HAS_PASSLIB, parse_xml, type5_pw, hash_salt,
+ comp_type5)
+
from ansible.errors import AnsibleFilterError
fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures', 'network')
@@ -83,6 +85,7 @@ class TestNetworkParseFilter(unittest.TestCase):
self.assertEqual("parse_xml works on string input, but given input of : %s" % type(output), str(e.exception))
+@pytest.mark.skipif(not HAS_PASSLIB, reason="Current type5_pw filter needs passlib to function")
class TestNetworkType5(unittest.TestCase):
def test_defined_salt_success(self):
@@ -146,6 +149,7 @@ class TestHashSalt(unittest.TestCase):
self.assertEqual("Could not parse salt out password correctly from $nTc1$Z28sUTcWfXlvVe2x.3XAa.", str(e.exception))
+@pytest.mark.skipif(not HAS_PASSLIB, reason="Current comp_type5 filter needs passlib to function")
class TestCompareType5(unittest.TestCase):
def test_compare_type5_boolean(self):
@@ -160,7 +164,7 @@ class TestCompareType5(unittest.TestCase):
parsed = comp_type5(unencrypted_password, encrypted_password, True)
self.assertEqual(parsed, '$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.')
- def test_compate_type5_fail(self):
+ def test_compare_type5_fail(self):
unencrypted_password = 'invalid_password'
encrypted_password = '$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.'
parsed = comp_type5(unencrypted_password, encrypted_password)
diff --git a/test/units/plugins/lookup/test_password.py b/test/units/plugins/lookup/test_password.py
index 8f3e31750d..7a11689dee 100644
--- a/test/units/plugins/lookup/test_password.py
+++ b/test/units/plugins/lookup/test_password.py
@@ -20,8 +20,15 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
-import passlib
-from passlib.handlers import pbkdf2
+try:
+ import passlib
+ from passlib.handlers import pbkdf2
+except ImportError:
+ passlib = None
+ pbkdf2 = None
+
+import pytest
+
from units.mock.loader import DictDataLoader
from ansible.compat.tests import unittest
@@ -359,7 +366,7 @@ class TestWritePasswordFile(unittest.TestCase):
m().write.assert_called_once_with(u'Testing Café\n'.encode('utf-8'))
-class TestLookupModule(unittest.TestCase):
+class BaseTestLookupModule(unittest.TestCase):
def setUp(self):
self.fake_loader = DictDataLoader({'/path/to/somewhere': 'sdfsdf'})
self.password_lookup = password.LookupModule(loader=self.fake_loader)
@@ -373,19 +380,15 @@ class TestLookupModule(unittest.TestCase):
self.makedirs_safe = password.makedirs_safe
password.makedirs_safe = lambda path, mode: None
- # Different releases of passlib default to a different number of rounds
- self.sha256 = passlib.registry.get_crypt_handler('pbkdf2_sha256')
- sha256_for_tests = pbkdf2.create_pbkdf2_hash("sha256", 32, 20000)
- passlib.registry.register_crypt_handler(sha256_for_tests, force=True)
-
def tearDown(self):
password.os.path.exists = self.os_path_exists
password.os.open = self.os_open
password.os.close = self.os_close
password.os.remove = self.os_remove
password.makedirs_safe = self.makedirs_safe
- passlib.registry.register_crypt_handler(self.sha256, force=True)
+
+class TestLookupModuleWithoutPasslib(BaseTestLookupModule):
@patch.object(PluginLoader, '_get_paths')
@patch('ansible.plugins.lookup.password._write_password_file')
def test_no_encrypt(self, mock_get_paths, mock_write_file):
@@ -395,46 +398,8 @@ class TestLookupModule(unittest.TestCase):
# FIXME: assert something useful
for result in results:
- self.assertEquals(len(result), password.DEFAULT_LENGTH)
- self.assertIsInstance(result, text_type)
-
- @patch.object(PluginLoader, '_get_paths')
- @patch('ansible.plugins.lookup.password._write_password_file')
- def test_encrypt(self, mock_get_paths, mock_write_file):
- mock_get_paths.return_value = ['/path/one', '/path/two', '/path/three']
-
- results = self.password_lookup.run([u'/path/to/somewhere encrypt=pbkdf2_sha256'], None)
-
- # pbkdf2 format plus hash
- expected_password_length = 76
-
- for result in results:
- self.assertEquals(len(result), expected_password_length)
- # result should have 5 parts split by '$'
- str_parts = result.split('$', 5)
-
- # verify the result is parseable by the passlib
- crypt_parts = passlib.hash.pbkdf2_sha256.parsehash(result)
-
- # verify it used the right algo type
- self.assertEquals(str_parts[1], 'pbkdf2-sha256')
-
- self.assertEquals(len(str_parts), 5)
-
- # verify the string and parsehash agree on the number of rounds
- self.assertEquals(int(str_parts[2]), crypt_parts['rounds'])
- self.assertIsInstance(result, text_type)
-
- @patch.object(PluginLoader, '_get_paths')
- @patch('ansible.plugins.lookup.password._write_password_file')
- def test_password_already_created_encrypt(self, mock_get_paths, mock_write_file):
- mock_get_paths.return_value = ['/path/one', '/path/two', '/path/three']
- password.os.path.exists = lambda x: x == to_bytes('/path/to/somewhere')
-
- with patch.object(builtins, 'open', mock_open(read_data=b'hunter42 salt=87654321\n')) as m:
- results = self.password_lookup.run([u'/path/to/somewhere chars=anything encrypt=pbkdf2_sha256'], None)
- for result in results:
- self.assertEqual(result, u'$pbkdf2-sha256$20000$ODc2NTQzMjE$Uikde0cv0BKaRaAXMrUQB.zvG4GmnjClwjghwIRf2gU')
+ assert len(result) == password.DEFAULT_LENGTH
+ assert isinstance(result, text_type)
@patch.object(PluginLoader, '_get_paths')
@patch('ansible.plugins.lookup.password._write_password_file')
@@ -480,3 +445,57 @@ class TestLookupModule(unittest.TestCase):
for result in results:
self.assertEqual(result, u'hunter42')
+
+
+@pytest.mark.skipif(passlib is None, reason='passlib must be installed to run these tests')
+class TestLookupModuleWithPasslib(BaseTestLookupModule):
+ def setUp(self):
+ super(TestLookupModuleWithPasslib, self).setUp()
+
+ # Different releases of passlib default to a different number of rounds
+ self.sha256 = passlib.registry.get_crypt_handler('pbkdf2_sha256')
+ sha256_for_tests = pbkdf2.create_pbkdf2_hash("sha256", 32, 20000)
+ passlib.registry.register_crypt_handler(sha256_for_tests, force=True)
+
+ def tearDown(self):
+ super(TestLookupModuleWithPasslib, self).tearDown()
+
+ passlib.registry.register_crypt_handler(self.sha256, force=True)
+
+ @patch.object(PluginLoader, '_get_paths')
+ @patch('ansible.plugins.lookup.password._write_password_file')
+ def test_encrypt(self, mock_get_paths, mock_write_file):
+ mock_get_paths.return_value = ['/path/one', '/path/two', '/path/three']
+
+ results = self.password_lookup.run([u'/path/to/somewhere encrypt=pbkdf2_sha256'], None)
+
+ # pbkdf2 format plus hash
+ expected_password_length = 76
+
+ for result in results:
+ self.assertEquals(len(result), expected_password_length)
+ # result should have 5 parts split by '$'
+ str_parts = result.split('$', 5)
+
+ # verify the result is parseable by the passlib
+ crypt_parts = passlib.hash.pbkdf2_sha256.parsehash(result)
+
+ # verify it used the right algo type
+ self.assertEquals(str_parts[1], 'pbkdf2-sha256')
+
+ self.assertEquals(len(str_parts), 5)
+
+ # verify the string and parsehash agree on the number of rounds
+ self.assertEquals(int(str_parts[2]), crypt_parts['rounds'])
+ self.assertIsInstance(result, text_type)
+
+ @patch.object(PluginLoader, '_get_paths')
+ @patch('ansible.plugins.lookup.password._write_password_file')
+ def test_password_already_created_encrypt(self, mock_get_paths, mock_write_file):
+ mock_get_paths.return_value = ['/path/one', '/path/two', '/path/three']
+ password.os.path.exists = lambda x: x == to_bytes('/path/to/somewhere')
+
+ with patch.object(builtins, 'open', mock_open(read_data=b'hunter42 salt=87654321\n')) as m:
+ results = self.password_lookup.run([u'/path/to/somewhere chars=anything encrypt=pbkdf2_sha256'], None)
+ for result in results:
+ self.assertEqual(result, u'$pbkdf2-sha256$20000$ODc2NTQzMjE$Uikde0cv0BKaRaAXMrUQB.zvG4GmnjClwjghwIRf2gU')
diff --git a/test/units/utils/test_encrypt.py b/test/units/utils/test_encrypt.py
index 22dd76287f..64c092f94f 100644
--- a/test/units/utils/test_encrypt.py
+++ b/test/units/utils/test_encrypt.py
@@ -36,16 +36,29 @@ class passlib_off(object):
def assert_hash(expected, secret, algorithm, **settings):
- assert encrypt.CryptHash(algorithm).hash(secret, **settings) == expected
if encrypt.PASSLIB_AVAILABLE:
assert encrypt.passlib_or_crypt(secret, algorithm, **settings) == expected
assert encrypt.PasslibHash(algorithm).hash(secret, **settings) == expected
else:
- with pytest.raises(AnsibleFilterError):
+ assert encrypt.passlib_or_crypt(secret, algorithm, **settings) == expected
+ with pytest.raises(AnsibleError) as excinfo:
encrypt.PasslibHash(algorithm).hash(secret, **settings)
+ assert excinfo.value.args[0] == "passlib must be installed to hash with '%s'" % algorithm
+
+
+def test_encrypt_with_rounds_no_passlib():
+ with passlib_off():
+ assert_hash("$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7",
+ secret="123", algorithm="sha256_crypt", salt="12345678", rounds=5000)
+ assert_hash("$5$rounds=10000$12345678$JBinliYMFEcBeAXKZnLjenhgEhTmJBvZn3aR8l70Oy/",
+ secret="123", algorithm="sha256_crypt", salt="12345678", rounds=10000)
+ assert_hash("$6$12345678$LcV9LQiaPekQxZ.OfkMADjFdSO2k9zfbDQrHPVcYjSLqSdjLYpsgqviYvTEP/R41yPmhH3CCeEDqVhW1VHr3L.",
+ secret="123", algorithm="sha512_crypt", salt="12345678", rounds=5000)
+# If passlib is not installed. this is identical to the test_encrypt_with_rounds_no_passlib() test
+@pytest.mark.skipif(not encrypt.PASSLIB_AVAILABLE, reason='passlib must be installed to run this test')
def test_encrypt_with_rounds():
assert_hash("$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7",
secret="123", algorithm="sha256_crypt", salt="12345678", rounds=5000)
@@ -55,6 +68,20 @@ def test_encrypt_with_rounds():
secret="123", algorithm="sha512_crypt", salt="12345678", rounds=5000)
+def test_encrypt_default_rounds_no_passlib():
+ with passlib_off():
+ assert_hash("$1$12345678$tRy4cXc3kmcfRZVj4iFXr/",
+ secret="123", algorithm="md5_crypt", salt="12345678")
+ assert_hash("$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7",
+ secret="123", algorithm="sha256_crypt", salt="12345678")
+ assert_hash("$6$12345678$LcV9LQiaPekQxZ.OfkMADjFdSO2k9zfbDQrHPVcYjSLqSdjLYpsgqviYvTEP/R41yPmhH3CCeEDqVhW1VHr3L.",
+ secret="123", algorithm="sha512_crypt", salt="12345678")
+
+ assert encrypt.CryptHash("md5_crypt").hash("123")
+
+
+# If passlib is not installed. this is identical to the test_encrypt_default_rounds_no_passlib() test
+@pytest.mark.skipif(not encrypt.PASSLIB_AVAILABLE, reason='passlib must be installed to run this test')
def test_encrypt_default_rounds():
assert_hash("$1$12345678$tRy4cXc3kmcfRZVj4iFXr/",
secret="123", algorithm="md5_crypt", salt="12345678")