mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-04 19:26:58 +00:00
Reformat everything.
This commit is contained in:
parent
3f2213791a
commit
340ff8586d
1008 changed files with 61301 additions and 58309 deletions
|
|
@ -7,15 +7,14 @@ from __future__ import annotations
|
|||
import random
|
||||
import unittest
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.cloud import _exponential_backoff, \
|
||||
_full_jitter_backoff
|
||||
from ansible_collections.community.general.plugins.module_utils.cloud import _exponential_backoff, _full_jitter_backoff
|
||||
|
||||
|
||||
class ExponentialBackoffStrategyTestCase(unittest.TestCase):
|
||||
def test_no_retries(self):
|
||||
strategy = _exponential_backoff(retries=0)
|
||||
result = list(strategy())
|
||||
self.assertEqual(result, [], 'list should be empty')
|
||||
self.assertEqual(result, [], "list should be empty")
|
||||
|
||||
def test_exponential_backoff(self):
|
||||
strategy = _exponential_backoff(retries=5, delay=1, backoff=2)
|
||||
|
|
@ -37,7 +36,7 @@ class FullJitterBackoffStrategyTestCase(unittest.TestCase):
|
|||
def test_no_retries(self):
|
||||
strategy = _full_jitter_backoff(retries=0)
|
||||
result = list(strategy())
|
||||
self.assertEqual(result, [], 'list should be empty')
|
||||
self.assertEqual(result, [], "list should be empty")
|
||||
|
||||
def test_full_jitter(self):
|
||||
retries = 5
|
||||
|
|
@ -46,8 +45,7 @@ class FullJitterBackoffStrategyTestCase(unittest.TestCase):
|
|||
r = random.Random(seed)
|
||||
expected = [r.randint(0, 2**i) for i in range(0, retries)]
|
||||
|
||||
strategy = _full_jitter_backoff(
|
||||
retries=retries, delay=1, _random=random.Random(seed))
|
||||
strategy = _full_jitter_backoff(retries=retries, delay=1, _random=random.Random(seed))
|
||||
result = list(strategy())
|
||||
|
||||
self.assertEqual(result, expected)
|
||||
|
|
|
|||
|
|
@ -11,48 +11,48 @@ from ansible_collections.community.general.plugins.module_utils.scaleway import
|
|||
|
||||
class SecretVariablesTestCase(unittest.TestCase):
|
||||
def test_dict_to_list(self):
|
||||
source = dict(
|
||||
attribute1="value1",
|
||||
attribute2="value2"
|
||||
)
|
||||
expect = [
|
||||
dict(key="attribute1", value="value1"),
|
||||
dict(key="attribute2", value="value2")
|
||||
]
|
||||
source = dict(attribute1="value1", attribute2="value2")
|
||||
expect = [dict(key="attribute1", value="value1"), dict(key="attribute2", value="value2")]
|
||||
|
||||
result = SecretVariables.dict_to_list(source)
|
||||
result = sorted(result, key=lambda el: el['key'])
|
||||
result = sorted(result, key=lambda el: el["key"])
|
||||
self.assertEqual(result, expect)
|
||||
|
||||
def test_list_to_dict(self):
|
||||
source = [
|
||||
dict(key="secret1", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc"),
|
||||
dict(key="secret2", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI")
|
||||
dict(
|
||||
key="secret1",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc",
|
||||
),
|
||||
dict(
|
||||
key="secret2",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI",
|
||||
),
|
||||
]
|
||||
expect = dict(
|
||||
secret1="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc",
|
||||
secret2="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI"
|
||||
secret2="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI",
|
||||
)
|
||||
|
||||
self.assertEqual(SecretVariables.list_to_dict(source, hashed=True), expect)
|
||||
|
||||
def test_list_to_dict_2(self):
|
||||
source = [
|
||||
dict(key="secret1", value="value1"),
|
||||
dict(key="secret2", value="value2")
|
||||
]
|
||||
expect = dict(
|
||||
secret1="value1",
|
||||
secret2="value2"
|
||||
)
|
||||
source = [dict(key="secret1", value="value1"), dict(key="secret2", value="value2")]
|
||||
expect = dict(secret1="value1", secret2="value2")
|
||||
|
||||
self.assertEqual(SecretVariables.list_to_dict(source, hashed=False), expect)
|
||||
|
||||
@unittest.skipIf(argon2 is None, "Missing required 'argon2' library")
|
||||
def test_decode_full(self):
|
||||
source_secret = [
|
||||
dict(key="secret1", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc"),
|
||||
dict(key="secret2", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI"),
|
||||
dict(
|
||||
key="secret1",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc",
|
||||
),
|
||||
dict(
|
||||
key="secret2",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI",
|
||||
),
|
||||
]
|
||||
source_value = [
|
||||
dict(key="secret1", value="value1"),
|
||||
|
|
@ -65,14 +65,20 @@ class SecretVariablesTestCase(unittest.TestCase):
|
|||
]
|
||||
|
||||
result = SecretVariables.decode(source_secret, source_value)
|
||||
result = sorted(result, key=lambda el: el['key'])
|
||||
result = sorted(result, key=lambda el: el["key"])
|
||||
self.assertEqual(result, expect)
|
||||
|
||||
@unittest.skipIf(argon2 is None, "Missing required 'argon2' library")
|
||||
def test_decode_dict_divergent_values(self):
|
||||
source_secret = [
|
||||
dict(key="secret1", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc"),
|
||||
dict(key="secret2", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI"),
|
||||
dict(
|
||||
key="secret1",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc",
|
||||
),
|
||||
dict(
|
||||
key="secret2",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI",
|
||||
),
|
||||
]
|
||||
source_value = [
|
||||
dict(key="secret1", value="value1"),
|
||||
|
|
@ -81,17 +87,23 @@ class SecretVariablesTestCase(unittest.TestCase):
|
|||
|
||||
expect = [
|
||||
dict(key="secret1", value="value1"),
|
||||
dict(key="secret2", value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI"),
|
||||
dict(
|
||||
key="secret2",
|
||||
value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI",
|
||||
),
|
||||
]
|
||||
|
||||
result = SecretVariables.decode(source_secret, source_value)
|
||||
result = sorted(result, key=lambda el: el['key'])
|
||||
result = sorted(result, key=lambda el: el["key"])
|
||||
self.assertEqual(result, expect)
|
||||
|
||||
@unittest.skipIf(argon2 is None, "Missing required 'argon2' library")
|
||||
def test_decode_dict_missing_values_left(self):
|
||||
source_secret = [
|
||||
dict(key="secret1", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc"),
|
||||
dict(
|
||||
key="secret1",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc",
|
||||
),
|
||||
]
|
||||
source_value = [
|
||||
dict(key="secret1", value="value1"),
|
||||
|
|
@ -103,14 +115,20 @@ class SecretVariablesTestCase(unittest.TestCase):
|
|||
]
|
||||
|
||||
result = SecretVariables.decode(source_secret, source_value)
|
||||
result = sorted(result, key=lambda el: el['key'])
|
||||
result = sorted(result, key=lambda el: el["key"])
|
||||
self.assertEqual(result, expect)
|
||||
|
||||
@unittest.skipIf(argon2 is None, "Missing required 'argon2' library")
|
||||
def test_decode_dict_missing_values_right(self):
|
||||
source_secret = [
|
||||
dict(key="secret1", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc"),
|
||||
dict(key="secret2", hashed_value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI"),
|
||||
dict(
|
||||
key="secret1",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$NuZk+6UATHNFV78nFRXFvA$3kivcXfzNHI1c/4ZBpP8BeBSGhhI82NfOh4Dd48JJgc",
|
||||
),
|
||||
dict(
|
||||
key="secret2",
|
||||
hashed_value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI",
|
||||
),
|
||||
]
|
||||
source_value = [
|
||||
dict(key="secret1", value="value1"),
|
||||
|
|
@ -118,9 +136,12 @@ class SecretVariablesTestCase(unittest.TestCase):
|
|||
|
||||
expect = [
|
||||
dict(key="secret1", value="value1"),
|
||||
dict(key="secret2", value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI"),
|
||||
dict(
|
||||
key="secret2",
|
||||
value="$argon2id$v=19$m=65536,t=1,p=2$etGO/Z8ImYDeKr6uFsyPAQ$FbL5+hG/duDEpa8UCYqXpEUQ5EacKg6i2iAs+Dq4dAI",
|
||||
),
|
||||
]
|
||||
|
||||
result = SecretVariables.decode(source_secret, source_value)
|
||||
result = sorted(result, key=lambda el: el['key'])
|
||||
result = sorted(result, key=lambda el: el["key"])
|
||||
self.assertEqual(result, expect)
|
||||
|
|
|
|||
|
|
@ -14,102 +14,50 @@ from ansible_collections.community.general.plugins.module_utils.hwc_utils import
|
|||
|
||||
class HwcDictComparisonTestCase(unittest.TestCase):
|
||||
def test_simple_no_difference(self):
|
||||
value1 = {
|
||||
'foo': 'bar',
|
||||
'test': 'original'
|
||||
}
|
||||
value1 = {"foo": "bar", "test": "original"}
|
||||
|
||||
self.assertFalse(are_different_dicts(value1, value1))
|
||||
|
||||
def test_simple_different(self):
|
||||
value1 = {
|
||||
'foo': 'bar',
|
||||
'test': 'original'
|
||||
}
|
||||
value2 = {
|
||||
'foo': 'bar',
|
||||
'test': 'different'
|
||||
}
|
||||
value3 = {
|
||||
'test': 'original'
|
||||
}
|
||||
value1 = {"foo": "bar", "test": "original"}
|
||||
value2 = {"foo": "bar", "test": "different"}
|
||||
value3 = {"test": "original"}
|
||||
|
||||
self.assertTrue(are_different_dicts(value1, value2))
|
||||
self.assertTrue(are_different_dicts(value1, value3))
|
||||
self.assertTrue(are_different_dicts(value2, value3))
|
||||
|
||||
def test_nested_dictionaries_no_difference(self):
|
||||
value1 = {
|
||||
'foo': {
|
||||
'quiet': {
|
||||
'tree': 'test'
|
||||
},
|
||||
'bar': 'baz'
|
||||
},
|
||||
'test': 'original'
|
||||
}
|
||||
value1 = {"foo": {"quiet": {"tree": "test"}, "bar": "baz"}, "test": "original"}
|
||||
|
||||
self.assertFalse(are_different_dicts(value1, value1))
|
||||
|
||||
def test_nested_dictionaries_with_difference(self):
|
||||
value1 = {
|
||||
'foo': {
|
||||
'quiet': {
|
||||
'tree': 'test'
|
||||
},
|
||||
'bar': 'baz'
|
||||
},
|
||||
'test': 'original'
|
||||
}
|
||||
value2 = {
|
||||
'foo': {
|
||||
'quiet': {
|
||||
'tree': 'baz'
|
||||
},
|
||||
'bar': 'hello'
|
||||
},
|
||||
'test': 'original'
|
||||
}
|
||||
value3 = {
|
||||
'foo': {
|
||||
'quiet': {
|
||||
'tree': 'test'
|
||||
},
|
||||
'bar': 'baz'
|
||||
}
|
||||
}
|
||||
value1 = {"foo": {"quiet": {"tree": "test"}, "bar": "baz"}, "test": "original"}
|
||||
value2 = {"foo": {"quiet": {"tree": "baz"}, "bar": "hello"}, "test": "original"}
|
||||
value3 = {"foo": {"quiet": {"tree": "test"}, "bar": "baz"}}
|
||||
|
||||
self.assertTrue(are_different_dicts(value1, value2))
|
||||
self.assertTrue(are_different_dicts(value1, value3))
|
||||
self.assertTrue(are_different_dicts(value2, value3))
|
||||
|
||||
def test_arrays_strings_no_difference(self):
|
||||
value1 = {
|
||||
'foo': [
|
||||
'baz',
|
||||
'bar'
|
||||
]
|
||||
}
|
||||
value1 = {"foo": ["baz", "bar"]}
|
||||
|
||||
self.assertFalse(are_different_dicts(value1, value1))
|
||||
|
||||
def test_arrays_strings_with_difference(self):
|
||||
value1 = {
|
||||
'foo': [
|
||||
'baz',
|
||||
'bar',
|
||||
"foo": [
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
value2 = {
|
||||
'foo': [
|
||||
'baz',
|
||||
'hello'
|
||||
]
|
||||
}
|
||||
value2 = {"foo": ["baz", "hello"]}
|
||||
value3 = {
|
||||
'foo': [
|
||||
'bar',
|
||||
"foo": [
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -118,48 +66,18 @@ class HwcDictComparisonTestCase(unittest.TestCase):
|
|||
self.assertTrue(are_different_dicts(value2, value3))
|
||||
|
||||
def test_arrays_dicts_with_no_difference(self):
|
||||
value1 = {
|
||||
'foo': [
|
||||
{
|
||||
'test': 'value',
|
||||
'foo': 'bar'
|
||||
},
|
||||
{
|
||||
'different': 'dict'
|
||||
}
|
||||
]
|
||||
}
|
||||
value1 = {"foo": [{"test": "value", "foo": "bar"}, {"different": "dict"}]}
|
||||
|
||||
self.assertFalse(are_different_dicts(value1, value1))
|
||||
|
||||
def test_arrays_dicts_with_difference(self):
|
||||
value1 = {
|
||||
'foo': [
|
||||
{
|
||||
'test': 'value',
|
||||
'foo': 'bar'
|
||||
},
|
||||
{
|
||||
'different': 'dict'
|
||||
}
|
||||
]
|
||||
}
|
||||
value1 = {"foo": [{"test": "value", "foo": "bar"}, {"different": "dict"}]}
|
||||
value2 = {
|
||||
'foo': [
|
||||
{
|
||||
'test': 'value2',
|
||||
'foo': 'bar2'
|
||||
},
|
||||
]
|
||||
}
|
||||
value3 = {
|
||||
'foo': [
|
||||
{
|
||||
'test': 'value',
|
||||
'foo': 'bar'
|
||||
}
|
||||
"foo": [
|
||||
{"test": "value2", "foo": "bar2"},
|
||||
]
|
||||
}
|
||||
value3 = {"foo": [{"test": "value", "foo": "bar"}]}
|
||||
|
||||
self.assertTrue(are_different_dicts(value1, value2))
|
||||
self.assertTrue(are_different_dicts(value1, value3))
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from __future__ import annotations
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.hwc_utils import (HwcModuleException, navigate_value)
|
||||
from ansible_collections.community.general.plugins.module_utils.hwc_utils import HwcModuleException, navigate_value
|
||||
|
||||
|
||||
class HwcUtilsTestCase(unittest.TestCase):
|
||||
|
|
@ -20,28 +20,24 @@ class HwcUtilsTestCase(unittest.TestCase):
|
|||
|
||||
def test_navigate_value(self):
|
||||
value = {
|
||||
'foo': {
|
||||
'quiet': {
|
||||
'tree': 'test',
|
||||
"trees": [0, 1]
|
||||
},
|
||||
"foo": {
|
||||
"quiet": {"tree": "test", "trees": [0, 1]},
|
||||
}
|
||||
}
|
||||
|
||||
self.assertEqual(navigate_value(value, ["foo", "quiet", "tree"]),
|
||||
"test")
|
||||
self.assertEqual(navigate_value(value, ["foo", "quiet", "tree"]), "test")
|
||||
|
||||
self.assertEqual(
|
||||
navigate_value(value, ["foo", "quiet", "trees"],
|
||||
{"foo.quiet.trees": 1}),
|
||||
1)
|
||||
self.assertEqual(navigate_value(value, ["foo", "quiet", "trees"], {"foo.quiet.trees": 1}), 1)
|
||||
|
||||
self.assertRaisesRegex(HwcModuleException,
|
||||
r".* key\(q\) is not exist in dict",
|
||||
navigate_value, value, ["foo", "q", "tree"])
|
||||
self.assertRaisesRegex(
|
||||
HwcModuleException, r".* key\(q\) is not exist in dict", navigate_value, value, ["foo", "q", "tree"]
|
||||
)
|
||||
|
||||
self.assertRaisesRegex(HwcModuleException,
|
||||
r".* the index is out of list",
|
||||
navigate_value, value,
|
||||
["foo", "quiet", "trees"],
|
||||
{"foo.quiet.trees": 2})
|
||||
self.assertRaisesRegex(
|
||||
HwcModuleException,
|
||||
r".* the index is out of list",
|
||||
navigate_value,
|
||||
value,
|
||||
["foo", "quiet", "trees"],
|
||||
{"foo.quiet.trees": 2},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,22 +15,23 @@ from ansible_collections.community.general.plugins.module_utils.identity.keycloa
|
|||
)
|
||||
|
||||
module_params_creds = {
|
||||
'auth_keycloak_url': 'http://keycloak.url/auth',
|
||||
'validate_certs': True,
|
||||
'auth_realm': 'master',
|
||||
'client_id': 'admin-cli',
|
||||
'auth_username': 'admin',
|
||||
'auth_password': 'admin',
|
||||
'client_secret': None,
|
||||
"auth_keycloak_url": "http://keycloak.url/auth",
|
||||
"validate_certs": True,
|
||||
"auth_realm": "master",
|
||||
"client_id": "admin-cli",
|
||||
"auth_username": "admin",
|
||||
"auth_password": "admin",
|
||||
"client_secret": None,
|
||||
}
|
||||
|
||||
|
||||
def build_mocked_request(get_id_user_count, response_dict):
|
||||
def _mocked_requests(*args, **kwargs):
|
||||
url = args[0]
|
||||
method = kwargs['method']
|
||||
method = kwargs["method"]
|
||||
future_response = response_dict.get(url, None)
|
||||
return get_response(future_response, method, get_id_user_count)
|
||||
|
||||
return _mocked_requests
|
||||
|
||||
|
||||
|
|
@ -38,16 +39,14 @@ def get_response(object_with_future_response, method, get_id_call_count):
|
|||
if callable(object_with_future_response):
|
||||
return object_with_future_response()
|
||||
if isinstance(object_with_future_response, dict):
|
||||
return get_response(
|
||||
object_with_future_response[method], method, get_id_call_count)
|
||||
return get_response(object_with_future_response[method], method, get_id_call_count)
|
||||
if isinstance(object_with_future_response, list):
|
||||
try:
|
||||
call_number = get_id_call_count.__next__()
|
||||
except AttributeError:
|
||||
# manage python 2 versions.
|
||||
call_number = get_id_call_count.next()
|
||||
return get_response(
|
||||
object_with_future_response[call_number], method, get_id_call_count)
|
||||
return get_response(object_with_future_response[call_number], method, get_id_call_count)
|
||||
return object_with_future_response
|
||||
|
||||
|
||||
|
|
@ -55,52 +54,52 @@ def create_wrapper(text_as_string):
|
|||
"""Allow to mock many times a call to one address.
|
||||
Without this function, the StringIO is empty for the second call.
|
||||
"""
|
||||
|
||||
def _create_wrapper():
|
||||
return StringIO(text_as_string)
|
||||
|
||||
return _create_wrapper
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def mock_good_connection(mocker):
|
||||
token_response = {
|
||||
'http://keycloak.url/auth/realms/master/protocol/openid-connect/token': create_wrapper('{"access_token": "alongtoken"}'), }
|
||||
"http://keycloak.url/auth/realms/master/protocol/openid-connect/token": create_wrapper(
|
||||
'{"access_token": "alongtoken"}'
|
||||
),
|
||||
}
|
||||
return mocker.patch(
|
||||
'ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url',
|
||||
"ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url",
|
||||
side_effect=build_mocked_request(count(), token_response),
|
||||
autospec=True
|
||||
autospec=True,
|
||||
)
|
||||
|
||||
|
||||
def test_connect_to_keycloak_with_creds(mock_good_connection):
|
||||
keycloak_header = get_token(module_params_creds)
|
||||
assert keycloak_header == {
|
||||
'Authorization': 'Bearer alongtoken',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
assert keycloak_header == {"Authorization": "Bearer alongtoken", "Content-Type": "application/json"}
|
||||
|
||||
|
||||
def test_connect_to_keycloak_with_token(mock_good_connection):
|
||||
module_params_token = {
|
||||
'auth_keycloak_url': 'http://keycloak.url/auth',
|
||||
'validate_certs': True,
|
||||
'client_id': 'admin-cli',
|
||||
'token': "alongtoken"
|
||||
"auth_keycloak_url": "http://keycloak.url/auth",
|
||||
"validate_certs": True,
|
||||
"client_id": "admin-cli",
|
||||
"token": "alongtoken",
|
||||
}
|
||||
keycloak_header = get_token(module_params_token)
|
||||
assert keycloak_header == {
|
||||
'Authorization': 'Bearer alongtoken',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
assert keycloak_header == {"Authorization": "Bearer alongtoken", "Content-Type": "application/json"}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def mock_bad_json_returned(mocker):
|
||||
token_response = {
|
||||
'http://keycloak.url/auth/realms/master/protocol/openid-connect/token': create_wrapper('{"access_token":'), }
|
||||
"http://keycloak.url/auth/realms/master/protocol/openid-connect/token": create_wrapper('{"access_token":'),
|
||||
}
|
||||
return mocker.patch(
|
||||
'ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url',
|
||||
"ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url",
|
||||
side_effect=build_mocked_request(count(), token_response),
|
||||
autospec=True
|
||||
autospec=True,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -110,27 +109,29 @@ def test_bad_json_returned(mock_bad_json_returned):
|
|||
# cannot check all the message, different errors message for the value
|
||||
# error in python 2.6, 2.7 and 3.*.
|
||||
assert (
|
||||
'API returned invalid JSON when trying to obtain access token from '
|
||||
'http://keycloak.url/auth/realms/master/protocol/openid-connect/token: '
|
||||
"API returned invalid JSON when trying to obtain access token from "
|
||||
"http://keycloak.url/auth/realms/master/protocol/openid-connect/token: "
|
||||
) in str(raised_error.value)
|
||||
|
||||
|
||||
def raise_401(url):
|
||||
def _raise_401():
|
||||
raise HTTPError(url=url, code=401, msg='Unauthorized', hdrs='', fp=StringIO(''))
|
||||
raise HTTPError(url=url, code=401, msg="Unauthorized", hdrs="", fp=StringIO(""))
|
||||
|
||||
return _raise_401
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def mock_401_returned(mocker):
|
||||
token_response = {
|
||||
'http://keycloak.url/auth/realms/master/protocol/openid-connect/token': raise_401(
|
||||
'http://keycloak.url/auth/realms/master/protocol/openid-connect/token'),
|
||||
"http://keycloak.url/auth/realms/master/protocol/openid-connect/token": raise_401(
|
||||
"http://keycloak.url/auth/realms/master/protocol/openid-connect/token"
|
||||
),
|
||||
}
|
||||
return mocker.patch(
|
||||
'ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url',
|
||||
"ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url",
|
||||
side_effect=build_mocked_request(count(), token_response),
|
||||
autospec=True
|
||||
autospec=True,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -138,20 +139,23 @@ def test_error_returned(mock_401_returned):
|
|||
with pytest.raises(KeycloakError) as raised_error:
|
||||
get_token(module_params_creds)
|
||||
assert str(raised_error.value) == (
|
||||
'Could not obtain access token from http://keycloak.url'
|
||||
'/auth/realms/master/protocol/openid-connect/token: '
|
||||
'HTTP Error 401: Unauthorized'
|
||||
"Could not obtain access token from http://keycloak.url"
|
||||
"/auth/realms/master/protocol/openid-connect/token: "
|
||||
"HTTP Error 401: Unauthorized"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def mock_json_without_token_returned(mocker):
|
||||
token_response = {
|
||||
'http://keycloak.url/auth/realms/master/protocol/openid-connect/token': create_wrapper('{"not_token": "It is not a token"}'), }
|
||||
"http://keycloak.url/auth/realms/master/protocol/openid-connect/token": create_wrapper(
|
||||
'{"not_token": "It is not a token"}'
|
||||
),
|
||||
}
|
||||
return mocker.patch(
|
||||
'ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url',
|
||||
"ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak.open_url",
|
||||
side_effect=build_mocked_request(count(), token_response),
|
||||
autospec=True
|
||||
autospec=True,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -159,6 +163,6 @@ def test_json_without_token_returned(mock_json_without_token_returned):
|
|||
with pytest.raises(KeycloakError) as raised_error:
|
||||
get_token(module_params_creds)
|
||||
assert str(raised_error.value) == (
|
||||
'API did not include access_token field in response from '
|
||||
'http://keycloak.url/auth/realms/master/protocol/openid-connect/token'
|
||||
"API did not include access_token field in response from "
|
||||
"http://keycloak.url/auth/realms/master/protocol/openid-connect/token"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,74 +11,44 @@ from ansible_collections.community.general.plugins.module_utils.identity.keycloa
|
|||
|
||||
class KeycloakIsStructIncludedTestCase(unittest.TestCase):
|
||||
dict1 = dict(
|
||||
test1='test1',
|
||||
test2=dict(
|
||||
test1='test1',
|
||||
test2='test2'
|
||||
),
|
||||
test3=['test1', dict(test='test1', test2='test2')]
|
||||
test1="test1", test2=dict(test1="test1", test2="test2"), test3=["test1", dict(test="test1", test2="test2")]
|
||||
)
|
||||
dict2 = dict(
|
||||
test1='test1',
|
||||
test2=dict(
|
||||
test1='test1',
|
||||
test2='test2',
|
||||
test3='test3'
|
||||
),
|
||||
test3=['test1', dict(test='test1', test2='test2'), 'test3'],
|
||||
test4='test4'
|
||||
test1="test1",
|
||||
test2=dict(test1="test1", test2="test2", test3="test3"),
|
||||
test3=["test1", dict(test="test1", test2="test2"), "test3"],
|
||||
test4="test4",
|
||||
)
|
||||
dict3 = dict(
|
||||
test1='test1',
|
||||
test2=dict(
|
||||
test1='test1',
|
||||
test2='test23',
|
||||
test3='test3'
|
||||
),
|
||||
test3=['test1', dict(test='test1', test2='test23'), 'test3'],
|
||||
test4='test4'
|
||||
test1="test1",
|
||||
test2=dict(test1="test1", test2="test23", test3="test3"),
|
||||
test3=["test1", dict(test="test1", test2="test23"), "test3"],
|
||||
test4="test4",
|
||||
)
|
||||
|
||||
dict5 = dict(
|
||||
test1='test1',
|
||||
test2=dict(
|
||||
test1=True,
|
||||
test2='test23',
|
||||
test3='test3'
|
||||
),
|
||||
test3=['test1', dict(test='test1', test2='test23'), 'test3'],
|
||||
test4='test4'
|
||||
test1="test1",
|
||||
test2=dict(test1=True, test2="test23", test3="test3"),
|
||||
test3=["test1", dict(test="test1", test2="test23"), "test3"],
|
||||
test4="test4",
|
||||
)
|
||||
|
||||
dict6 = dict(
|
||||
test1='test1',
|
||||
test2=dict(
|
||||
test1='true',
|
||||
test2='test23',
|
||||
test3='test3'
|
||||
),
|
||||
test3=['test1', dict(test='test1', test2='test23'), 'test3'],
|
||||
test4='test4'
|
||||
test1="test1",
|
||||
test2=dict(test1="true", test2="test23", test3="test3"),
|
||||
test3=["test1", dict(test="test1", test2="test23"), "test3"],
|
||||
test4="test4",
|
||||
)
|
||||
dict7 = [
|
||||
{
|
||||
'roles': ['view-clients', 'view-identity-providers', 'view-users', 'query-realms', 'manage-users'],
|
||||
'clientid': 'master-realm'
|
||||
"roles": ["view-clients", "view-identity-providers", "view-users", "query-realms", "manage-users"],
|
||||
"clientid": "master-realm",
|
||||
},
|
||||
{
|
||||
'roles': ['manage-account', 'view-profile', 'manage-account-links'],
|
||||
'clientid': 'account'
|
||||
}
|
||||
{"roles": ["manage-account", "view-profile", "manage-account-links"], "clientid": "account"},
|
||||
]
|
||||
dict8 = [
|
||||
{
|
||||
'roles': ['view-clients', 'query-realms', 'view-users'],
|
||||
'clientid': 'master-realm'
|
||||
},
|
||||
{
|
||||
'roles': ['manage-account-links', 'view-profile', 'manage-account'],
|
||||
'clientid': 'account'
|
||||
}
|
||||
{"roles": ["view-clients", "query-realms", "view-users"], "clientid": "master-realm"},
|
||||
{"roles": ["manage-account-links", "view-profile", "manage-account"], "clientid": "account"},
|
||||
]
|
||||
|
||||
def test_trivial(self):
|
||||
|
|
|
|||
|
|
@ -459,9 +459,7 @@ class TestPritunlApi:
|
|||
):
|
||||
api._get_pritunl_organizations = get_pritunl_organization_mock()
|
||||
|
||||
response = api.list_pritunl_organizations(
|
||||
**dict_merge(pritunl_settings, {"filters": org_filters})
|
||||
)
|
||||
response = api.list_pritunl_organizations(**dict_merge(pritunl_settings, {"filters": org_filters}))
|
||||
|
||||
assert len(response) == 1
|
||||
assert response[0]["name"] == org_expected
|
||||
|
|
@ -470,14 +468,10 @@ class TestPritunlApi:
|
|||
"org_id,org_user_count",
|
||||
[("58070daee63f3b2e6e472c36", 3)],
|
||||
)
|
||||
def test_list_all_pritunl_user(
|
||||
self, pritunl_settings, get_pritunl_user_mock, org_id, org_user_count
|
||||
):
|
||||
def test_list_all_pritunl_user(self, pritunl_settings, get_pritunl_user_mock, org_id, org_user_count):
|
||||
api._get_pritunl_users = get_pritunl_user_mock()
|
||||
|
||||
response = api.list_pritunl_users(
|
||||
**dict_merge(pritunl_settings, {"organization_id": org_id})
|
||||
)
|
||||
response = api.list_pritunl_users(**dict_merge(pritunl_settings, {"organization_id": org_id}))
|
||||
|
||||
assert len(response) == org_user_count
|
||||
|
||||
|
|
@ -499,9 +493,7 @@ class TestPritunlApi:
|
|||
api._get_pritunl_users = get_pritunl_user_mock()
|
||||
|
||||
response = api.list_pritunl_users(
|
||||
**dict_merge(
|
||||
pritunl_settings, {"organization_id": org_id, "filters": user_filters}
|
||||
)
|
||||
**dict_merge(pritunl_settings, {"organization_id": org_id, "filters": user_filters})
|
||||
)
|
||||
|
||||
assert len(response) > 0
|
||||
|
|
@ -586,9 +578,7 @@ class TestPritunlApi:
|
|||
# Test for DELETE operation on Pritunl API
|
||||
|
||||
@pytest.mark.parametrize("org_id", [("58070daee63f3b2e6e472c36")])
|
||||
def test_delete_pritunl_organization(
|
||||
self, pritunl_settings, org_id, delete_pritunl_organization_mock
|
||||
):
|
||||
def test_delete_pritunl_organization(self, pritunl_settings, org_id, delete_pritunl_organization_mock):
|
||||
api._delete_pritunl_organization = delete_pritunl_organization_mock()
|
||||
|
||||
response = api.delete_pritunl_organization(
|
||||
|
|
@ -602,12 +592,8 @@ class TestPritunlApi:
|
|||
|
||||
assert response == {}
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"org_id,user_id", [("58070daee63f3b2e6e472c36", "590add71e63f3b72d8bb951a")]
|
||||
)
|
||||
def test_delete_pritunl_user(
|
||||
self, pritunl_settings, org_id, user_id, delete_pritunl_user_mock
|
||||
):
|
||||
@pytest.mark.parametrize("org_id,user_id", [("58070daee63f3b2e6e472c36", "590add71e63f3b72d8bb951a")])
|
||||
def test_delete_pritunl_user(self, pritunl_settings, org_id, user_id, delete_pritunl_user_mock):
|
||||
api._delete_pritunl_user = delete_pritunl_user_mock()
|
||||
|
||||
response = api.delete_pritunl_user(
|
||||
|
|
|
|||
|
|
@ -16,9 +16,24 @@ TC_FORMATS = dict(
|
|||
simple_boolean__true=(partial(cmd_runner_fmt.as_bool, "--superflag"), True, ["--superflag"], None),
|
||||
simple_boolean__false=(partial(cmd_runner_fmt.as_bool, "--superflag"), False, [], None),
|
||||
simple_boolean__none=(partial(cmd_runner_fmt.as_bool, "--superflag"), None, [], None),
|
||||
simple_boolean_both__true=(partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"), True, ["--superflag"], None),
|
||||
simple_boolean_both__false=(partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"), False, ["--falseflag"], None),
|
||||
simple_boolean_both__none=(partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"), None, ["--falseflag"], None),
|
||||
simple_boolean_both__true=(
|
||||
partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"),
|
||||
True,
|
||||
["--superflag"],
|
||||
None,
|
||||
),
|
||||
simple_boolean_both__false=(
|
||||
partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"),
|
||||
False,
|
||||
["--falseflag"],
|
||||
None,
|
||||
),
|
||||
simple_boolean_both__none=(
|
||||
partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"),
|
||||
None,
|
||||
["--falseflag"],
|
||||
None,
|
||||
),
|
||||
simple_boolean_both__none_ig=(partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag", True), None, [], None),
|
||||
simple_boolean_not__true=(partial(cmd_runner_fmt.as_bool_not, "--superflag"), True, [], None),
|
||||
simple_boolean_not__false=(partial(cmd_runner_fmt.as_bool_not, "--superflag"), False, ["--superflag"], None),
|
||||
|
|
@ -36,21 +51,56 @@ TC_FORMATS = dict(
|
|||
simple_list_min_len_fail=(partial(cmd_runner_fmt.as_list, min_len=10), 42, None, ValueError),
|
||||
simple_list_max_len_ok=(partial(cmd_runner_fmt.as_list, max_len=1), 42, ["42"], None),
|
||||
simple_list_max_len_fail=(partial(cmd_runner_fmt.as_list, max_len=2), [42, 42, 42], None, ValueError),
|
||||
simple_map=(partial(cmd_runner_fmt.as_map, {'a': 1, 'b': 2, 'c': 3}), 'b', ["2"], None),
|
||||
simple_fixed_true=(partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]), True, ["--always-here", "--forever"], None),
|
||||
simple_fixed_false=(partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]), False, ["--always-here", "--forever"], None),
|
||||
simple_fixed_none=(partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]), None, ["--always-here", "--forever"], None),
|
||||
simple_fixed_str=(partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]), "something", ["--always-here", "--forever"], None),
|
||||
stack_optval__str=(partial(cmd_runner_fmt.stack(cmd_runner_fmt.as_optval), "-t"), ["potatoes", "bananas"], ["-tpotatoes", "-tbananas"], None),
|
||||
stack_opt_val__str=(partial(cmd_runner_fmt.stack(cmd_runner_fmt.as_opt_val), "-t"), ["potatoes", "bananas"], ["-t", "potatoes", "-t", "bananas"], None),
|
||||
stack_opt_eq_val__int=(partial(cmd_runner_fmt.stack(cmd_runner_fmt.as_opt_eq_val), "--answer"), [42, 17], ["--answer=42", "--answer=17"], None),
|
||||
simple_map=(partial(cmd_runner_fmt.as_map, {"a": 1, "b": 2, "c": 3}), "b", ["2"], None),
|
||||
simple_fixed_true=(
|
||||
partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]),
|
||||
True,
|
||||
["--always-here", "--forever"],
|
||||
None,
|
||||
),
|
||||
simple_fixed_false=(
|
||||
partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]),
|
||||
False,
|
||||
["--always-here", "--forever"],
|
||||
None,
|
||||
),
|
||||
simple_fixed_none=(
|
||||
partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]),
|
||||
None,
|
||||
["--always-here", "--forever"],
|
||||
None,
|
||||
),
|
||||
simple_fixed_str=(
|
||||
partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]),
|
||||
"something",
|
||||
["--always-here", "--forever"],
|
||||
None,
|
||||
),
|
||||
stack_optval__str=(
|
||||
partial(cmd_runner_fmt.stack(cmd_runner_fmt.as_optval), "-t"),
|
||||
["potatoes", "bananas"],
|
||||
["-tpotatoes", "-tbananas"],
|
||||
None,
|
||||
),
|
||||
stack_opt_val__str=(
|
||||
partial(cmd_runner_fmt.stack(cmd_runner_fmt.as_opt_val), "-t"),
|
||||
["potatoes", "bananas"],
|
||||
["-t", "potatoes", "-t", "bananas"],
|
||||
None,
|
||||
),
|
||||
stack_opt_eq_val__int=(
|
||||
partial(cmd_runner_fmt.stack(cmd_runner_fmt.as_opt_eq_val), "--answer"),
|
||||
[42, 17],
|
||||
["--answer=42", "--answer=17"],
|
||||
None,
|
||||
),
|
||||
)
|
||||
TC_FORMATS_IDS = sorted(TC_FORMATS.keys())
|
||||
|
||||
|
||||
@pytest.mark.parametrize('func, value, expected, exception',
|
||||
(TC_FORMATS[tc] for tc in TC_FORMATS_IDS),
|
||||
ids=TC_FORMATS_IDS)
|
||||
@pytest.mark.parametrize(
|
||||
"func, value, expected, exception", (TC_FORMATS[tc] for tc in TC_FORMATS_IDS), ids=TC_FORMATS_IDS
|
||||
)
|
||||
def test_arg_format(func, value, expected, exception):
|
||||
fmt_func = func()
|
||||
try:
|
||||
|
|
@ -120,14 +170,14 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--answer=11', '--bb-here'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/mock/bin/testing", "--answer=11", "--bb-here"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -137,15 +187,15 @@ TC_RUNNER = dict(
|
|||
aa=dict(type="int", value=11, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
|
||||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(default_args_order=['bb', 'aa']),
|
||||
runner_init_args=dict(default_args_order=["bb", "aa"]),
|
||||
runner_ctx_args=dict(),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--bb-here', '--answer=11'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('bb', 'aa'),
|
||||
cmd=["/mock/bin/testing", "--bb-here", "--answer=11"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("bb", "aa"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -155,15 +205,15 @@ TC_RUNNER = dict(
|
|||
aa=dict(type="int", value=11, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
|
||||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(default_args_order=['bb', 'aa']),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_init_args=dict(default_args_order=["bb", "aa"]),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--answer=11', '--bb-here'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/mock/bin/testing", "--answer=11", "--bb-here"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -174,12 +224,12 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb', 'aa']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb", "aa"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--answer=11', '--bb-here', '--answer=11'],
|
||||
cmd=["/mock/bin/testing", "--answer=11", "--bb-here", "--answer=11"],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -189,18 +239,17 @@ TC_RUNNER = dict(
|
|||
aa=dict(type="int", value=11, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
|
||||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(default_args_order=['bb', 'aa']),
|
||||
runner_init_args=dict(default_args_order=["bb", "aa"]),
|
||||
runner_ctx_args=dict(
|
||||
args_order=['aa', 'bb'],
|
||||
output_process=lambda rc, out, err: f"{rc!s}-/-{out}-/-{err}"
|
||||
args_order=["aa", "bb"], output_process=lambda rc, out, err: f"{rc!s}-/-{out}-/-{err}"
|
||||
),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="ni", err="nu"),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--answer=11', '--bb-here'],
|
||||
cmd=["/mock/bin/testing", "--answer=11", "--bb-here"],
|
||||
),
|
||||
results="0-/-ni-/-nu"
|
||||
results="0-/-ni-/-nu",
|
||||
),
|
||||
),
|
||||
aa_bb_with_none=(
|
||||
|
|
@ -209,15 +258,15 @@ TC_RUNNER = dict(
|
|||
aa=dict(type="int", value=49, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
|
||||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(default_args_order=['bb', 'aa']),
|
||||
runner_init_args=dict(default_args_order=["bb", "aa"]),
|
||||
runner_ctx_args=dict(
|
||||
args_order=['aa', 'bb'],
|
||||
args_order=["aa", "bb"],
|
||||
),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=None), rc=0, out="ni", err="nu"),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--answer=49'],
|
||||
cmd=["/mock/bin/testing", "--answer=49"],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -228,14 +277,14 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_fixed, fmt_arg=["fixed", "args"]),
|
||||
),
|
||||
runner_init_args=dict(),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--answer=11', 'fixed', 'args'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/mock/bin/testing", "--answer=11", "fixed", "args"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -246,14 +295,14 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_map, fmt_arg={"v1": 111, "v2": 222}),
|
||||
),
|
||||
runner_init_args=dict(),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb="v2"), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--answer=11', '222'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/mock/bin/testing", "--answer=11", "222"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -264,14 +313,14 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_map, fmt_arg={"v1": 111, "v2": 222}),
|
||||
),
|
||||
runner_init_args=dict(),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb="v123456789"), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/testing', '--answer=11'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/mock/bin/testing", "--answer=11"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -279,69 +328,64 @@ TC_RUNNER = dict(
|
|||
TC_RUNNER_IDS = sorted(TC_RUNNER.keys())
|
||||
|
||||
|
||||
@pytest.mark.parametrize('runner_input, cmd_execution, expected',
|
||||
(TC_RUNNER[tc] for tc in TC_RUNNER_IDS),
|
||||
ids=TC_RUNNER_IDS)
|
||||
@pytest.mark.parametrize(
|
||||
"runner_input, cmd_execution, expected", (TC_RUNNER[tc] for tc in TC_RUNNER_IDS), ids=TC_RUNNER_IDS
|
||||
)
|
||||
def test_runner_context(runner_input, cmd_execution, expected):
|
||||
arg_spec = {}
|
||||
params = {}
|
||||
arg_formats = {}
|
||||
for k, v in runner_input['args_bundle'].items():
|
||||
for k, v in runner_input["args_bundle"].items():
|
||||
try:
|
||||
arg_spec[k] = {'type': v['type']}
|
||||
arg_spec[k] = {"type": v["type"]}
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
params[k] = v['value']
|
||||
params[k] = v["value"]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
arg_formats[k] = v['fmt_func'](v['fmt_arg'])
|
||||
arg_formats[k] = v["fmt_func"](v["fmt_arg"])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
orig_results = tuple(cmd_execution[x] for x in ('rc', 'out', 'err'))
|
||||
orig_results = tuple(cmd_execution[x] for x in ("rc", "out", "err"))
|
||||
|
||||
print(f"arg_spec={arg_spec}\nparams={params}\narg_formats={arg_formats}\n")
|
||||
|
||||
module = MagicMock()
|
||||
type(module).argument_spec = PropertyMock(return_value=arg_spec)
|
||||
type(module).params = PropertyMock(return_value=params)
|
||||
module.get_bin_path.return_value = '/mock/bin/testing'
|
||||
module.get_bin_path.return_value = "/mock/bin/testing"
|
||||
module.run_command.return_value = orig_results
|
||||
|
||||
runner = CmdRunner(
|
||||
module=module,
|
||||
command="testing",
|
||||
arg_formats=arg_formats,
|
||||
**runner_input['runner_init_args']
|
||||
)
|
||||
runner = CmdRunner(module=module, command="testing", arg_formats=arg_formats, **runner_input["runner_init_args"])
|
||||
|
||||
def _assert_run_info(actual, expected):
|
||||
reduced = {k: actual[k] for k in expected.keys()}
|
||||
assert reduced == expected, f"{reduced}"
|
||||
|
||||
def _assert_run(runner_input, cmd_execution, expected, ctx, results):
|
||||
_assert_run_info(ctx.run_info, expected['run_info'])
|
||||
assert results == expected.get('results', orig_results)
|
||||
_assert_run_info(ctx.run_info, expected["run_info"])
|
||||
assert results == expected.get("results", orig_results)
|
||||
|
||||
exc = expected.get("exc")
|
||||
if exc:
|
||||
with pytest.raises(exc):
|
||||
with runner.context(**runner_input['runner_ctx_args']) as ctx:
|
||||
results = ctx.run(**cmd_execution['runner_ctx_run_args'])
|
||||
with runner.context(**runner_input["runner_ctx_args"]) as ctx:
|
||||
results = ctx.run(**cmd_execution["runner_ctx_run_args"])
|
||||
_assert_run(runner_input, cmd_execution, expected, ctx, results)
|
||||
|
||||
with pytest.raises(exc):
|
||||
with runner(**runner_input['runner_ctx_args']) as ctx2:
|
||||
results2 = ctx2.run(**cmd_execution['runner_ctx_run_args'])
|
||||
with runner(**runner_input["runner_ctx_args"]) as ctx2:
|
||||
results2 = ctx2.run(**cmd_execution["runner_ctx_run_args"])
|
||||
_assert_run(runner_input, cmd_execution, expected, ctx2, results2)
|
||||
|
||||
else:
|
||||
with runner.context(**runner_input['runner_ctx_args']) as ctx:
|
||||
results = ctx.run(**cmd_execution['runner_ctx_run_args'])
|
||||
with runner.context(**runner_input["runner_ctx_args"]) as ctx:
|
||||
results = ctx.run(**cmd_execution["runner_ctx_run_args"])
|
||||
_assert_run(runner_input, cmd_execution, expected, ctx, results)
|
||||
|
||||
with runner(**runner_input['runner_ctx_args']) as ctx2:
|
||||
results2 = ctx2.run(**cmd_execution['runner_ctx_run_args'])
|
||||
with runner(**runner_input["runner_ctx_args"]) as ctx2:
|
||||
results2 = ctx2.run(**cmd_execution["runner_ctx_run_args"])
|
||||
_assert_run(runner_input, cmd_execution, expected, ctx2, results2)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# Copyright (c) Ansible project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
|
@ -14,7 +13,7 @@ from ansible_collections.community.general.plugins.module_utils import csv
|
|||
|
||||
VALID_CSV = [
|
||||
(
|
||||
'excel',
|
||||
"excel",
|
||||
{},
|
||||
None,
|
||||
"id,name,role\n1,foo,bar\n2,bar,baz",
|
||||
|
|
@ -29,10 +28,10 @@ VALID_CSV = [
|
|||
"name": "bar",
|
||||
"role": "baz",
|
||||
},
|
||||
]
|
||||
],
|
||||
),
|
||||
(
|
||||
'excel',
|
||||
"excel",
|
||||
{"skipinitialspace": True},
|
||||
None,
|
||||
"id,name,role\n1, foo, bar\n2, bar, baz",
|
||||
|
|
@ -47,11 +46,11 @@ VALID_CSV = [
|
|||
"name": "bar",
|
||||
"role": "baz",
|
||||
},
|
||||
]
|
||||
],
|
||||
),
|
||||
(
|
||||
'excel',
|
||||
{"delimiter": '|'},
|
||||
"excel",
|
||||
{"delimiter": "|"},
|
||||
None,
|
||||
"id|name|role\n1|foo|bar\n2|bar|baz",
|
||||
[
|
||||
|
|
@ -65,10 +64,10 @@ VALID_CSV = [
|
|||
"name": "bar",
|
||||
"role": "baz",
|
||||
},
|
||||
]
|
||||
],
|
||||
),
|
||||
(
|
||||
'unix',
|
||||
"unix",
|
||||
{},
|
||||
None,
|
||||
"id,name,role\n1,foo,bar\n2,bar,baz",
|
||||
|
|
@ -83,12 +82,12 @@ VALID_CSV = [
|
|||
"name": "bar",
|
||||
"role": "baz",
|
||||
},
|
||||
]
|
||||
],
|
||||
),
|
||||
(
|
||||
'excel',
|
||||
"excel",
|
||||
{},
|
||||
['id', 'name', 'role'],
|
||||
["id", "name", "role"],
|
||||
"1,foo,bar\n2,bar,baz",
|
||||
[
|
||||
{
|
||||
|
|
@ -101,14 +100,14 @@ VALID_CSV = [
|
|||
"name": "bar",
|
||||
"role": "baz",
|
||||
},
|
||||
]
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
INVALID_CSV = [
|
||||
(
|
||||
'excel',
|
||||
{'strict': True},
|
||||
"excel",
|
||||
{"strict": True},
|
||||
None,
|
||||
'id,name,role\n1,"f"oo",bar\n2,bar,baz',
|
||||
),
|
||||
|
|
@ -116,7 +115,7 @@ INVALID_CSV = [
|
|||
|
||||
INVALID_DIALECT: list[tuple[str, t.Any, t.Any, str]] = [
|
||||
(
|
||||
'invalid',
|
||||
"invalid",
|
||||
{},
|
||||
None,
|
||||
"id,name,role\n1,foo,bar\n2,bar,baz",
|
||||
|
|
|
|||
|
|
@ -19,15 +19,13 @@ VALID = {
|
|||
'"public.table"': '"public.table"',
|
||||
'"public"."table"': '"public"."table"',
|
||||
'"schema test"."table test"': '"schema test"."table test"',
|
||||
|
||||
# We quote part
|
||||
'public.table': '"public"."table"',
|
||||
"public.table": '"public"."table"',
|
||||
'"public".table': '"public"."table"',
|
||||
'public."table"': '"public"."table"',
|
||||
'schema test.table test': '"schema test"."table test"',
|
||||
"schema test.table test": '"schema test"."table test"',
|
||||
'"schema test".table test': '"schema test"."table test"',
|
||||
'schema test."table test"': '"schema test"."table test"',
|
||||
|
||||
# Embedded double quotes
|
||||
'table "test"': '"table ""test"""',
|
||||
'public."table ""test"""': '"public"."table ""test"""',
|
||||
|
|
@ -40,7 +38,6 @@ VALID = {
|
|||
'schema."table': '"schema"."""table"',
|
||||
'"schema.table': '"""schema"."table"',
|
||||
'schema."table.something': '"schema"."""table"."something"',
|
||||
|
||||
# Embedded dots
|
||||
'"schema.test"."table.test"': '"schema.test"."table.test"',
|
||||
'"schema.".table': '"schema."."table"',
|
||||
|
|
@ -50,61 +47,61 @@ VALID = {
|
|||
'"schema.".".table"': '"schema.".".table"',
|
||||
# These are valid but maybe not what the user intended
|
||||
'."table"': '".""table"""',
|
||||
'table.': '"table."',
|
||||
"table.": '"table."',
|
||||
}
|
||||
|
||||
INVALID = {
|
||||
('test.too.many.dots', 'table'): 'PostgreSQL does not support table with more than 3 dots',
|
||||
('"test.too".many.dots', 'database'): 'PostgreSQL does not support database with more than 1 dots',
|
||||
('test.too."many.dots"', 'database'): 'PostgreSQL does not support database with more than 1 dots',
|
||||
('"test"."too"."many"."dots"', 'database'): "PostgreSQL does not support database with more than 1 dots",
|
||||
('"test"."too"."many"."dots"', 'schema'): "PostgreSQL does not support schema with more than 2 dots",
|
||||
('"test"."too"."many"."dots"', 'table'): "PostgreSQL does not support table with more than 3 dots",
|
||||
('"test"."too"."many"."dots"."for"."column"', 'column'): "PostgreSQL does not support column with more than 4 dots",
|
||||
('"table "invalid" double quote"', 'table'): 'User escaped identifiers must escape extra quotes',
|
||||
('"schema "invalid"""."table "invalid"', 'table'): 'User escaped identifiers must escape extra quotes',
|
||||
('"schema."table"', 'table'): 'User escaped identifiers must escape extra quotes',
|
||||
('"schema".', 'table'): 'Identifier name unspecified or unquoted trailing dot',
|
||||
("test.too.many.dots", "table"): "PostgreSQL does not support table with more than 3 dots",
|
||||
('"test.too".many.dots', "database"): "PostgreSQL does not support database with more than 1 dots",
|
||||
('test.too."many.dots"', "database"): "PostgreSQL does not support database with more than 1 dots",
|
||||
('"test"."too"."many"."dots"', "database"): "PostgreSQL does not support database with more than 1 dots",
|
||||
('"test"."too"."many"."dots"', "schema"): "PostgreSQL does not support schema with more than 2 dots",
|
||||
('"test"."too"."many"."dots"', "table"): "PostgreSQL does not support table with more than 3 dots",
|
||||
('"test"."too"."many"."dots"."for"."column"', "column"): "PostgreSQL does not support column with more than 4 dots",
|
||||
('"table "invalid" double quote"', "table"): "User escaped identifiers must escape extra quotes",
|
||||
('"schema "invalid"""."table "invalid"', "table"): "User escaped identifiers must escape extra quotes",
|
||||
('"schema."table"', "table"): "User escaped identifiers must escape extra quotes",
|
||||
('"schema".', "table"): "Identifier name unspecified or unquoted trailing dot",
|
||||
}
|
||||
|
||||
HOW_MANY_DOTS = (
|
||||
('role', 'role', '"role"',
|
||||
'PostgreSQL does not support role with more than 1 dots'),
|
||||
('db', 'database', '"db"',
|
||||
'PostgreSQL does not support database with more than 1 dots'),
|
||||
('db.schema', 'schema', '"db"."schema"',
|
||||
'PostgreSQL does not support schema with more than 2 dots'),
|
||||
('db.schema.table', 'table', '"db"."schema"."table"',
|
||||
'PostgreSQL does not support table with more than 3 dots'),
|
||||
('db.schema.table.column', 'column', '"db"."schema"."table"."column"',
|
||||
'PostgreSQL does not support column with more than 4 dots'),
|
||||
("role", "role", '"role"', "PostgreSQL does not support role with more than 1 dots"),
|
||||
("db", "database", '"db"', "PostgreSQL does not support database with more than 1 dots"),
|
||||
("db.schema", "schema", '"db"."schema"', "PostgreSQL does not support schema with more than 2 dots"),
|
||||
("db.schema.table", "table", '"db"."schema"."table"', "PostgreSQL does not support table with more than 3 dots"),
|
||||
(
|
||||
"db.schema.table.column",
|
||||
"column",
|
||||
'"db"."schema"."table"."column"',
|
||||
"PostgreSQL does not support column with more than 4 dots",
|
||||
),
|
||||
)
|
||||
|
||||
VALID_QUOTES = ((test, VALID[test]) for test in sorted(VALID))
|
||||
INVALID_QUOTES = ((test[0], test[1], INVALID[test]) for test in sorted(INVALID))
|
||||
|
||||
IS_STRINGS_DANGEROUS = (
|
||||
('', False),
|
||||
(' ', False),
|
||||
('alternative database', False),
|
||||
('backup of TRUNCATED table', False),
|
||||
('bob.dropper', False),
|
||||
('d\'artagnan', False),
|
||||
('user_with_select_update_truncate_right', False),
|
||||
(';DROP DATABASE fluffy_pets_photos', True),
|
||||
(';drop DATABASE fluffy_pets_photos', True),
|
||||
('; TRUNCATE TABLE his_valuable_table', True),
|
||||
('; truncate TABLE his_valuable_table', True),
|
||||
('\'--', True),
|
||||
("", False),
|
||||
(" ", False),
|
||||
("alternative database", False),
|
||||
("backup of TRUNCATED table", False),
|
||||
("bob.dropper", False),
|
||||
("d'artagnan", False),
|
||||
("user_with_select_update_truncate_right", False),
|
||||
(";DROP DATABASE fluffy_pets_photos", True),
|
||||
(";drop DATABASE fluffy_pets_photos", True),
|
||||
("; TRUNCATE TABLE his_valuable_table", True),
|
||||
("; truncate TABLE his_valuable_table", True),
|
||||
("'--", True),
|
||||
('"--', True),
|
||||
('\' union select username, password from admin_credentials', True),
|
||||
('\' UNION SELECT username, password from admin_credentials', True),
|
||||
('\' intersect select', True),
|
||||
('\' INTERSECT select', True),
|
||||
('\' except select', True),
|
||||
('\' EXCEPT select', True),
|
||||
(';ALTER TABLE prices', True),
|
||||
(';alter table prices', True),
|
||||
("' union select username, password from admin_credentials", True),
|
||||
("' UNION SELECT username, password from admin_credentials", True),
|
||||
("' intersect select", True),
|
||||
("' INTERSECT select", True),
|
||||
("' except select", True),
|
||||
("' EXCEPT select", True),
|
||||
(";ALTER TABLE prices", True),
|
||||
(";alter table prices", True),
|
||||
("; UPDATE products SET price = '0'", True),
|
||||
(";update products SET price = '0'", True),
|
||||
("; DELETE FROM products", True),
|
||||
|
|
@ -116,7 +113,7 @@ IS_STRINGS_DANGEROUS = (
|
|||
|
||||
@pytest.mark.parametrize("identifier, quoted_identifier", VALID_QUOTES)
|
||||
def test_valid_quotes(identifier, quoted_identifier):
|
||||
assert pg_quote_identifier(identifier, 'table') == quoted_identifier
|
||||
assert pg_quote_identifier(identifier, "table") == quoted_identifier
|
||||
|
||||
|
||||
@pytest.mark.parametrize("identifier, id_type, msg", INVALID_QUOTES)
|
||||
|
|
@ -132,7 +129,7 @@ def test_how_many_dots(identifier, id_type, quoted_identifier, msg):
|
|||
assert pg_quote_identifier(identifier, id_type) == quoted_identifier
|
||||
|
||||
with pytest.raises(SQLParseError) as ex:
|
||||
pg_quote_identifier(f'{identifier}.more', id_type)
|
||||
pg_quote_identifier(f"{identifier}.more", id_type)
|
||||
|
||||
ex.match(msg)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,89 +11,94 @@ from ansible_collections.community.general.plugins.module_utils import known_hos
|
|||
|
||||
|
||||
URLS = {
|
||||
'ssh://one.example.org/example.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': 'one.example.org',
|
||||
'add_host_key_cmd': " -t rsa one.example.org",
|
||||
'port': None,
|
||||
"ssh://one.example.org/example.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "one.example.org",
|
||||
"add_host_key_cmd": " -t rsa one.example.org",
|
||||
"port": None,
|
||||
},
|
||||
'ssh+git://two.example.org/example.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': 'two.example.org',
|
||||
'add_host_key_cmd': " -t rsa two.example.org",
|
||||
'port': None,
|
||||
"ssh+git://two.example.org/example.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "two.example.org",
|
||||
"add_host_key_cmd": " -t rsa two.example.org",
|
||||
"port": None,
|
||||
},
|
||||
'rsync://three.example.org/user/example.git': {
|
||||
'is_ssh_url': False,
|
||||
'get_fqdn': 'three.example.org',
|
||||
'add_host_key_cmd': None, # not called for non-ssh urls
|
||||
'port': None,
|
||||
"rsync://three.example.org/user/example.git": {
|
||||
"is_ssh_url": False,
|
||||
"get_fqdn": "three.example.org",
|
||||
"add_host_key_cmd": None, # not called for non-ssh urls
|
||||
"port": None,
|
||||
},
|
||||
'git@four.example.org:user/example.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': 'four.example.org',
|
||||
'add_host_key_cmd': " -t rsa four.example.org",
|
||||
'port': None,
|
||||
"git@four.example.org:user/example.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "four.example.org",
|
||||
"add_host_key_cmd": " -t rsa four.example.org",
|
||||
"port": None,
|
||||
},
|
||||
'git+ssh://five.example.org/example.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': 'five.example.org',
|
||||
'add_host_key_cmd': " -t rsa five.example.org",
|
||||
'port': None,
|
||||
"git+ssh://five.example.org/example.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "five.example.org",
|
||||
"add_host_key_cmd": " -t rsa five.example.org",
|
||||
"port": None,
|
||||
},
|
||||
'ssh://six.example.org:21/example.org': {
|
||||
"ssh://six.example.org:21/example.org": {
|
||||
# ssh on FTP Port?
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': 'six.example.org',
|
||||
'add_host_key_cmd': " -t rsa -p 21 six.example.org",
|
||||
'port': '21',
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "six.example.org",
|
||||
"add_host_key_cmd": " -t rsa -p 21 six.example.org",
|
||||
"port": "21",
|
||||
},
|
||||
'ssh://[2001:DB8::abcd:abcd]/example.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': '[2001:DB8::abcd:abcd]',
|
||||
'add_host_key_cmd': " -t rsa [2001:DB8::abcd:abcd]",
|
||||
'port': None,
|
||||
"ssh://[2001:DB8::abcd:abcd]/example.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "[2001:DB8::abcd:abcd]",
|
||||
"add_host_key_cmd": " -t rsa [2001:DB8::abcd:abcd]",
|
||||
"port": None,
|
||||
},
|
||||
'ssh://[2001:DB8::abcd:abcd]:22/example.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': '[2001:DB8::abcd:abcd]',
|
||||
'add_host_key_cmd': " -t rsa -p 22 [2001:DB8::abcd:abcd]",
|
||||
'port': '22',
|
||||
"ssh://[2001:DB8::abcd:abcd]:22/example.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "[2001:DB8::abcd:abcd]",
|
||||
"add_host_key_cmd": " -t rsa -p 22 [2001:DB8::abcd:abcd]",
|
||||
"port": "22",
|
||||
},
|
||||
'username@[2001:DB8::abcd:abcd]/example.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': '[2001:DB8::abcd:abcd]',
|
||||
'add_host_key_cmd': " -t rsa [2001:DB8::abcd:abcd]",
|
||||
'port': None,
|
||||
"username@[2001:DB8::abcd:abcd]/example.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "[2001:DB8::abcd:abcd]",
|
||||
"add_host_key_cmd": " -t rsa [2001:DB8::abcd:abcd]",
|
||||
"port": None,
|
||||
},
|
||||
'username@[2001:DB8::abcd:abcd]:path/example.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': '[2001:DB8::abcd:abcd]',
|
||||
'add_host_key_cmd': " -t rsa [2001:DB8::abcd:abcd]",
|
||||
'port': None,
|
||||
"username@[2001:DB8::abcd:abcd]:path/example.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "[2001:DB8::abcd:abcd]",
|
||||
"add_host_key_cmd": " -t rsa [2001:DB8::abcd:abcd]",
|
||||
"port": None,
|
||||
},
|
||||
'ssh://internal.git.server:7999/repos/repo.git': {
|
||||
'is_ssh_url': True,
|
||||
'get_fqdn': 'internal.git.server',
|
||||
'add_host_key_cmd': " -t rsa -p 7999 internal.git.server",
|
||||
'port': '7999',
|
||||
"ssh://internal.git.server:7999/repos/repo.git": {
|
||||
"is_ssh_url": True,
|
||||
"get_fqdn": "internal.git.server",
|
||||
"add_host_key_cmd": " -t rsa -p 7999 internal.git.server",
|
||||
"port": "7999",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('url, is_ssh_url', ((k, URLS[k]['is_ssh_url']) for k in sorted(URLS)))
|
||||
@pytest.mark.parametrize("url, is_ssh_url", ((k, URLS[k]["is_ssh_url"]) for k in sorted(URLS)))
|
||||
def test_is_ssh_url(url, is_ssh_url):
|
||||
assert known_hosts.is_ssh_url(url) == is_ssh_url
|
||||
|
||||
|
||||
@pytest.mark.parametrize('url, fqdn, port', ((k, URLS[k]['get_fqdn'], URLS[k]['port']) for k in sorted(URLS)))
|
||||
@pytest.mark.parametrize("url, fqdn, port", ((k, URLS[k]["get_fqdn"], URLS[k]["port"]) for k in sorted(URLS)))
|
||||
def test_get_fqdn_and_port(url, fqdn, port):
|
||||
assert known_hosts.get_fqdn_and_port(url) == (fqdn, port)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fqdn, port, add_host_key_cmd',
|
||||
((URLS[k]['get_fqdn'], URLS[k]['port'], URLS[k]['add_host_key_cmd'])
|
||||
for k in sorted(URLS) if URLS[k]['is_ssh_url']))
|
||||
@pytest.mark.parametrize(
|
||||
"fqdn, port, add_host_key_cmd",
|
||||
(
|
||||
(URLS[k]["get_fqdn"], URLS[k]["port"], URLS[k]["add_host_key_cmd"])
|
||||
for k in sorted(URLS)
|
||||
if URLS[k]["is_ssh_url"]
|
||||
),
|
||||
)
|
||||
def test_add_host_key(mocker, fqdn, port, add_host_key_cmd):
|
||||
am = mocker.MagicMock()
|
||||
|
||||
|
|
@ -109,8 +114,8 @@ def test_add_host_key(mocker, fqdn, port, add_host_key_cmd):
|
|||
append_to_file.return_value = (None,)
|
||||
am.append_to_file = append_to_file
|
||||
|
||||
mocker.patch('os.path.isdir', return_value=True)
|
||||
mocker.patch('os.path.exists', return_value=True)
|
||||
mocker.patch("os.path.isdir", return_value=True)
|
||||
mocker.patch("os.path.exists", return_value=True)
|
||||
|
||||
known_hosts.add_host_key(am, fqdn, port=port)
|
||||
run_command.assert_called_with(keyscan_cmd + add_host_key_cmd)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,7 @@ from __future__ import annotations
|
|||
|
||||
import pytest
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.module_helper import (
|
||||
cause_changes
|
||||
)
|
||||
from ansible_collections.community.general.plugins.module_utils.module_helper import cause_changes
|
||||
|
||||
|
||||
#
|
||||
|
|
@ -17,7 +15,7 @@ from ansible_collections.community.general.plugins.module_utils.module_helper im
|
|||
# Parameters on_success and on_failure are deprecated and will be removed in community.general 12.0.0
|
||||
# Remove testcases with those params when releasing 12.0.0
|
||||
#
|
||||
CAUSE_CHG_DECO_PARAMS = ['deco_args', 'expect_exception', 'expect_changed']
|
||||
CAUSE_CHG_DECO_PARAMS = ["deco_args", "expect_exception", "expect_changed"]
|
||||
CAUSE_CHG_DECO = dict(
|
||||
none_succ=dict(deco_args={}, expect_exception=False, expect_changed=None),
|
||||
none_fail=dict(deco_args={}, expect_exception=True, expect_changed=None),
|
||||
|
|
@ -31,13 +29,12 @@ CAUSE_CHG_DECO = dict(
|
|||
CAUSE_CHG_DECO_IDS = sorted(CAUSE_CHG_DECO.keys())
|
||||
|
||||
|
||||
@pytest.mark.parametrize(CAUSE_CHG_DECO_PARAMS,
|
||||
[[CAUSE_CHG_DECO[tc][param]
|
||||
for param in CAUSE_CHG_DECO_PARAMS]
|
||||
for tc in CAUSE_CHG_DECO_IDS],
|
||||
ids=CAUSE_CHG_DECO_IDS)
|
||||
@pytest.mark.parametrize(
|
||||
CAUSE_CHG_DECO_PARAMS,
|
||||
[[CAUSE_CHG_DECO[tc][param] for param in CAUSE_CHG_DECO_PARAMS] for tc in CAUSE_CHG_DECO_IDS],
|
||||
ids=CAUSE_CHG_DECO_IDS,
|
||||
)
|
||||
def test_cause_changes_deco(deco_args, expect_exception, expect_changed):
|
||||
|
||||
class MockMH:
|
||||
changed = None
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@ from ansible_collections.community.general.plugins.module_utils.ocapi_utils impo
|
|||
class TestOcapiUtils(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tempdir = tempfile.mkdtemp()
|
||||
self.utils = OcapiUtils(creds={"user": "a_user", "pswd": "a_password"},
|
||||
base_uri="fakeUri",
|
||||
proxy_slot_number=None,
|
||||
timeout=30,
|
||||
module=None)
|
||||
self.utils = OcapiUtils(
|
||||
creds={"user": "a_user", "pswd": "a_password"},
|
||||
base_uri="fakeUri",
|
||||
proxy_slot_number=None,
|
||||
timeout=30,
|
||||
module=None,
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tempdir)
|
||||
|
|
@ -29,8 +31,8 @@ class TestOcapiUtils(unittest.TestCase):
|
|||
# Generate a binary file and save it
|
||||
filename = "fake_firmware.bin"
|
||||
filepath = os.path.join(self.tempdir, filename)
|
||||
file_contents = b'\x00\x01\x02\x03\x04'
|
||||
with open(filepath, 'wb+') as f:
|
||||
file_contents = b"\x00\x01\x02\x03\x04"
|
||||
with open(filepath, "wb+") as f:
|
||||
f.write(file_contents)
|
||||
|
||||
# Call prepare_mutipart_firmware_upload
|
||||
|
|
@ -43,10 +45,10 @@ class TestOcapiUtils(unittest.TestCase):
|
|||
|
||||
# Check the returned binary data
|
||||
boundary = m.group(1)
|
||||
expected_content_text = f'--{boundary}\r\n'
|
||||
expected_content_text = f"--{boundary}\r\n"
|
||||
expected_content_text += f'Content-Disposition: form-data; name="FirmwareFile"; filename="{filename}"\r\n'
|
||||
expected_content_text += 'Content-Type: application/octet-stream\r\n\r\n'
|
||||
expected_content_bytes = bytearray(expected_content_text, 'utf-8')
|
||||
expected_content_text += "Content-Type: application/octet-stream\r\n\r\n"
|
||||
expected_content_bytes = bytearray(expected_content_text, "utf-8")
|
||||
expected_content_bytes += file_contents
|
||||
expected_content_bytes += bytearray(f'\r\n--{boundary}--', 'utf-8')
|
||||
expected_content_bytes += bytearray(f"\r\n--{boundary}--", "utf-8")
|
||||
self.assertEqual(expected_content_bytes, b_form_data)
|
||||
|
|
|
|||
|
|
@ -12,36 +12,12 @@ from ansible_collections.community.general.plugins.module_utils.opennebula impor
|
|||
|
||||
|
||||
FLATTEN_VALID = [
|
||||
(
|
||||
[[[1]], [2], 3],
|
||||
False,
|
||||
[1, 2, 3]
|
||||
),
|
||||
(
|
||||
[[[1]], [2], 3],
|
||||
True,
|
||||
[1, 2, 3]
|
||||
),
|
||||
(
|
||||
[[1]],
|
||||
False,
|
||||
[1]
|
||||
),
|
||||
(
|
||||
[[1]],
|
||||
True,
|
||||
1
|
||||
),
|
||||
(
|
||||
1,
|
||||
False,
|
||||
[1]
|
||||
),
|
||||
(
|
||||
1,
|
||||
True,
|
||||
1
|
||||
),
|
||||
([[[1]], [2], 3], False, [1, 2, 3]),
|
||||
([[[1]], [2], 3], True, [1, 2, 3]),
|
||||
([[1]], False, [1]),
|
||||
([[1]], True, 1),
|
||||
(1, False, [1]),
|
||||
(1, True, 1),
|
||||
]
|
||||
|
||||
RENDER_VALID = [
|
||||
|
|
@ -51,11 +27,11 @@ RENDER_VALID = [
|
|||
"CPU": 1,
|
||||
"MEMORY": 1024,
|
||||
},
|
||||
textwrap.dedent('''
|
||||
textwrap.dedent("""
|
||||
CPU="1"
|
||||
MEMORY="1024"
|
||||
NIC=[NAME="NIC0",NETWORK_ID="0"]
|
||||
''').strip()
|
||||
""").strip(),
|
||||
),
|
||||
(
|
||||
{
|
||||
|
|
@ -66,35 +42,35 @@ RENDER_VALID = [
|
|||
"CPU": 1,
|
||||
"MEMORY": 1024,
|
||||
},
|
||||
textwrap.dedent('''
|
||||
textwrap.dedent("""
|
||||
CPU="1"
|
||||
MEMORY="1024"
|
||||
NIC=[NAME="NIC0",NETWORK_ID="0"]
|
||||
NIC=[NAME="NIC1",NETWORK_ID="1"]
|
||||
''').strip()
|
||||
""").strip(),
|
||||
),
|
||||
(
|
||||
{
|
||||
'EMPTY_VALUE': None,
|
||||
'SCHED_REQUIREMENTS': 'CLUSTER_ID="100"',
|
||||
'BACKSLASH_ESCAPED': "this is escaped: \\n; this isn't: \"\nend",
|
||||
"EMPTY_VALUE": None,
|
||||
"SCHED_REQUIREMENTS": 'CLUSTER_ID="100"',
|
||||
"BACKSLASH_ESCAPED": "this is escaped: \\n; this isn't: \"\nend",
|
||||
},
|
||||
textwrap.dedent('''
|
||||
textwrap.dedent("""
|
||||
BACKSLASH_ESCAPED="this is escaped: \\\\n; this isn't: \\"
|
||||
end"
|
||||
SCHED_REQUIREMENTS="CLUSTER_ID=\\"100\\""
|
||||
''').strip()
|
||||
""").strip(),
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('to_flatten,extract,expected_result', FLATTEN_VALID)
|
||||
@pytest.mark.parametrize("to_flatten,extract,expected_result", FLATTEN_VALID)
|
||||
def test_flatten(to_flatten, extract, expected_result):
|
||||
result = flatten(to_flatten, extract)
|
||||
assert result == expected_result, repr(result)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('to_render,expected_result', RENDER_VALID)
|
||||
@pytest.mark.parametrize("to_render,expected_result", RENDER_VALID)
|
||||
def test_render(to_render, expected_result):
|
||||
result = render(to_render)
|
||||
assert result == expected_result, repr(result)
|
||||
|
|
|
|||
|
|
@ -70,14 +70,14 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(command="testing"),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/python', 'testing', '--answer=11', '--bb-here'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/mock/bin/python", "testing", "--answer=11", "--bb-here"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -88,14 +88,14 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(command="toasting", python="python3"),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/mock/bin/python3', 'toasting', '--answer=11', '--bb-here'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/mock/bin/python3", "toasting", "--answer=11", "--bb-here"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -106,14 +106,14 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(command="toasting", python="/crazy/local/bin/python3"),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/crazy/local/bin/python3', 'toasting', '--answer=11', '--bb-here'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/crazy/local/bin/python3", "toasting", "--answer=11", "--bb-here"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -124,14 +124,14 @@ TC_RUNNER = dict(
|
|||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
||||
),
|
||||
runner_init_args=dict(command="toasting", venv="/venv"),
|
||||
runner_ctx_args=dict(args_order=['aa', 'bb']),
|
||||
runner_ctx_args=dict(args_order=["aa", "bb"]),
|
||||
),
|
||||
dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
|
||||
dict(
|
||||
run_info=dict(
|
||||
cmd=['/venv/bin/python', 'toasting', '--answer=11', '--bb-here'],
|
||||
environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C', 'VIRTUAL_ENV': '/venv', 'PATH': '/venv/bin'},
|
||||
args_order=('aa', 'bb'),
|
||||
cmd=["/venv/bin/python", "toasting", "--answer=11", "--bb-here"],
|
||||
environ_update={"LANGUAGE": "C", "LC_ALL": "C", "VIRTUAL_ENV": "/venv", "PATH": "/venv/bin"},
|
||||
args_order=("aa", "bb"),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -139,28 +139,28 @@ TC_RUNNER = dict(
|
|||
TC_RUNNER_IDS = sorted(TC_RUNNER.keys())
|
||||
|
||||
|
||||
@pytest.mark.parametrize('runner_input, cmd_execution, expected',
|
||||
(TC_RUNNER[tc] for tc in TC_RUNNER_IDS),
|
||||
ids=TC_RUNNER_IDS)
|
||||
@pytest.mark.parametrize(
|
||||
"runner_input, cmd_execution, expected", (TC_RUNNER[tc] for tc in TC_RUNNER_IDS), ids=TC_RUNNER_IDS
|
||||
)
|
||||
def test_runner_context(runner_input, cmd_execution, expected):
|
||||
arg_spec = {}
|
||||
params = {}
|
||||
arg_formats = {}
|
||||
for k, v in runner_input['args_bundle'].items():
|
||||
for k, v in runner_input["args_bundle"].items():
|
||||
try:
|
||||
arg_spec[k] = {'type': v['type']}
|
||||
arg_spec[k] = {"type": v["type"]}
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
params[k] = v['value']
|
||||
params[k] = v["value"]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
arg_formats[k] = v['fmt_func'](v['fmt_arg'])
|
||||
arg_formats[k] = v["fmt_func"](v["fmt_arg"])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
orig_results = tuple(cmd_execution[x] for x in ('rc', 'out', 'err'))
|
||||
orig_results = tuple(cmd_execution[x] for x in ("rc", "out", "err"))
|
||||
|
||||
print(f"arg_spec={arg_spec}\nparams={params}\narg_formats={arg_formats}\n")
|
||||
|
||||
|
|
@ -170,24 +170,16 @@ def test_runner_context(runner_input, cmd_execution, expected):
|
|||
module.get_bin_path.return_value = os.path.join(
|
||||
runner_input["runner_init_args"].get("venv", "/mock"),
|
||||
"bin",
|
||||
runner_input["runner_init_args"].get("python", "python")
|
||||
runner_input["runner_init_args"].get("python", "python"),
|
||||
)
|
||||
module.run_command.return_value = orig_results
|
||||
|
||||
runner = PythonRunner(
|
||||
module=module,
|
||||
arg_formats=arg_formats,
|
||||
**runner_input['runner_init_args']
|
||||
)
|
||||
runner = PythonRunner(module=module, arg_formats=arg_formats, **runner_input["runner_init_args"])
|
||||
|
||||
def _extract_path(run_info):
|
||||
path = run_info.get("environ_update", {}).get("PATH")
|
||||
if path is not None:
|
||||
run_info["environ_update"] = {
|
||||
k: v
|
||||
for k, v in run_info["environ_update"].items()
|
||||
if k != "PATH"
|
||||
}
|
||||
run_info["environ_update"] = {k: v for k, v in run_info["environ_update"].items() if k != "PATH"}
|
||||
return run_info, path
|
||||
|
||||
def _assert_run_info_env_path(actual, expected):
|
||||
|
|
@ -203,17 +195,17 @@ def test_runner_context(runner_input, cmd_execution, expected):
|
|||
assert reduced == expected, f"{reduced}"
|
||||
|
||||
def _assert_run(expected, ctx, results):
|
||||
_assert_run_info(ctx.run_info, expected['run_info'])
|
||||
assert results == expected.get('results', orig_results)
|
||||
_assert_run_info(ctx.run_info, expected["run_info"])
|
||||
assert results == expected.get("results", orig_results)
|
||||
|
||||
exc = expected.get("exc")
|
||||
if exc:
|
||||
with pytest.raises(exc):
|
||||
with runner.context(**runner_input['runner_ctx_args']) as ctx:
|
||||
results = ctx.run(**cmd_execution['runner_ctx_run_args'])
|
||||
with runner.context(**runner_input["runner_ctx_args"]) as ctx:
|
||||
results = ctx.run(**cmd_execution["runner_ctx_run_args"])
|
||||
_assert_run(expected, ctx, results)
|
||||
|
||||
else:
|
||||
with runner.context(**runner_input['runner_ctx_args']) as ctx:
|
||||
results = ctx.run(**cmd_execution['runner_ctx_run_args'])
|
||||
with runner.context(**runner_input["runner_ctx_args"]) as ctx:
|
||||
results = ctx.run(**cmd_execution["runner_ctx_run_args"])
|
||||
_assert_run(expected, ctx, results)
|
||||
|
|
|
|||
|
|
@ -11,45 +11,45 @@ from ansible_collections.community.general.plugins.module_utils.saslprep import
|
|||
|
||||
|
||||
VALID = [
|
||||
('', ''),
|
||||
('\u00A0', ' '),
|
||||
('a', 'a'),
|
||||
('й', 'й'),
|
||||
('\u30DE\u30C8\u30EA\u30C3\u30AF\u30B9', '\u30DE\u30C8\u30EA\u30C3\u30AF\u30B9'),
|
||||
('The\u00ADM\u00AAtr\u2168', 'TheMatrIX'),
|
||||
('I\u00ADX', 'IX'),
|
||||
('user', 'user'),
|
||||
('USER', 'USER'),
|
||||
('\u00AA', 'a'),
|
||||
('\u2168', 'IX'),
|
||||
('\u05BE\u00A0\u05BE', '\u05BE\u0020\u05BE'),
|
||||
("", ""),
|
||||
("\u00a0", " "),
|
||||
("a", "a"),
|
||||
("й", "й"),
|
||||
("\u30de\u30c8\u30ea\u30c3\u30af\u30b9", "\u30de\u30c8\u30ea\u30c3\u30af\u30b9"),
|
||||
("The\u00adM\u00aatr\u2168", "TheMatrIX"),
|
||||
("I\u00adX", "IX"),
|
||||
("user", "user"),
|
||||
("USER", "USER"),
|
||||
("\u00aa", "a"),
|
||||
("\u2168", "IX"),
|
||||
("\u05be\u00a0\u05be", "\u05be\u0020\u05be"),
|
||||
]
|
||||
|
||||
INVALID = [
|
||||
(None, TypeError),
|
||||
(b'', TypeError),
|
||||
('\u0221', ValueError),
|
||||
('\u0007', ValueError),
|
||||
('\u0627\u0031', ValueError),
|
||||
('\uE0001', ValueError),
|
||||
('\uE0020', ValueError),
|
||||
('\uFFF9', ValueError),
|
||||
('\uFDD0', ValueError),
|
||||
('\u0000', ValueError),
|
||||
('\u06DD', ValueError),
|
||||
('\uFFFFD', ValueError),
|
||||
('\uD800', ValueError),
|
||||
('\u200E', ValueError),
|
||||
('\u05BE\u00AA\u05BE', ValueError),
|
||||
(b"", TypeError),
|
||||
("\u0221", ValueError),
|
||||
("\u0007", ValueError),
|
||||
("\u0627\u0031", ValueError),
|
||||
("\ue0001", ValueError),
|
||||
("\ue0020", ValueError),
|
||||
("\ufff9", ValueError),
|
||||
("\ufdd0", ValueError),
|
||||
("\u0000", ValueError),
|
||||
("\u06dd", ValueError),
|
||||
("\uffffD", ValueError),
|
||||
("\ud800", ValueError),
|
||||
("\u200e", ValueError),
|
||||
("\u05be\u00aa\u05be", ValueError),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('source,target', VALID)
|
||||
@pytest.mark.parametrize("source,target", VALID)
|
||||
def test_saslprep_conversions(source, target):
|
||||
assert saslprep(source) == target
|
||||
|
||||
|
||||
@pytest.mark.parametrize('source,exception', INVALID)
|
||||
@pytest.mark.parametrize("source,exception", INVALID)
|
||||
def test_saslprep_exceptions(source, exception):
|
||||
with pytest.raises(exception) as ex:
|
||||
saslprep(source)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,15 @@ class FakeModule:
|
|||
def test_combine_headers_returns_only_default():
|
||||
expected = {"Accept": "application/json", "Content-type": "application/json"}
|
||||
module = FakeModule(
|
||||
params={'utm_protocol': 'utm_protocol', 'utm_host': 'utm_host', 'utm_port': 1234, 'utm_token': 'utm_token',
|
||||
'name': 'FakeName', 'headers': {}})
|
||||
params={
|
||||
"utm_protocol": "utm_protocol",
|
||||
"utm_host": "utm_host",
|
||||
"utm_port": 1234,
|
||||
"utm_token": "utm_token",
|
||||
"name": "FakeName",
|
||||
"headers": {},
|
||||
}
|
||||
)
|
||||
result = UTM(module, "endpoint", [])._combine_headers()
|
||||
assert result == expected
|
||||
|
||||
|
|
@ -31,17 +38,29 @@ def test_combine_headers_returns_only_default():
|
|||
def test_combine_headers_returns_only_default2():
|
||||
expected = {"Accept": "application/json", "Content-type": "application/json"}
|
||||
module = FakeModule(
|
||||
params={'utm_protocol': 'utm_protocol', 'utm_host': 'utm_host', 'utm_port': 1234, 'utm_token': 'utm_token',
|
||||
'name': 'FakeName'})
|
||||
params={
|
||||
"utm_protocol": "utm_protocol",
|
||||
"utm_host": "utm_host",
|
||||
"utm_port": 1234,
|
||||
"utm_token": "utm_token",
|
||||
"name": "FakeName",
|
||||
}
|
||||
)
|
||||
result = UTM(module, "endpoint", [])._combine_headers()
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_combine_headers_returns_combined():
|
||||
expected = {"Accept": "application/json", "Content-type": "application/json",
|
||||
"extraHeader": "extraHeaderValue"}
|
||||
module = FakeModule(params={'utm_protocol': 'utm_protocol', 'utm_host': 'utm_host', 'utm_port': 1234,
|
||||
'utm_token': 'utm_token', 'name': 'FakeName',
|
||||
"headers": {"extraHeader": "extraHeaderValue"}})
|
||||
expected = {"Accept": "application/json", "Content-type": "application/json", "extraHeader": "extraHeaderValue"}
|
||||
module = FakeModule(
|
||||
params={
|
||||
"utm_protocol": "utm_protocol",
|
||||
"utm_host": "utm_host",
|
||||
"utm_port": 1234,
|
||||
"utm_token": "utm_token",
|
||||
"name": "FakeName",
|
||||
"headers": {"extraHeader": "extraHeaderValue"},
|
||||
}
|
||||
)
|
||||
result = UTM(module, "endpoint", [])._combine_headers()
|
||||
assert result == expected
|
||||
|
|
|
|||
|
|
@ -80,7 +80,9 @@ def test_var_diff_dict():
|
|||
|
||||
vd.set("aa", 123, diff=True)
|
||||
vd.aa = 456
|
||||
assert vd.diff() == {"before": {"aa": 123, "dd": val_before}, "after": {"aa": 456, "dd": val_after}}, f"actual={vd.diff()}"
|
||||
assert vd.diff() == {"before": {"aa": 123, "dd": val_before}, "after": {"aa": 456, "dd": val_after}}, (
|
||||
f"actual={vd.diff()}"
|
||||
)
|
||||
|
||||
|
||||
def test_vardict_set_meta():
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@ class Failure(Exception):
|
|||
|
||||
|
||||
class Session:
|
||||
def __init__(self, uri, transport=None, encoding=None, verbose=0,
|
||||
allow_none=1, ignore_ssl=False):
|
||||
|
||||
def __init__(self, uri, transport=None, encoding=None, verbose=0, allow_none=1, ignore_ssl=False):
|
||||
self.transport = transport
|
||||
self._session = None
|
||||
self.last_login_method = None
|
||||
|
|
@ -42,10 +40,10 @@ class Session:
|
|||
self.API_version = FAKE_API_VERSION
|
||||
|
||||
def xenapi_request(self, methodname, params):
|
||||
if methodname.startswith('login'):
|
||||
if methodname.startswith("login"):
|
||||
self._login(methodname, params)
|
||||
return None
|
||||
elif methodname == 'logout' or methodname == 'session.logout':
|
||||
elif methodname == "logout" or methodname == "session.logout":
|
||||
self._logout()
|
||||
return None
|
||||
else:
|
||||
|
|
@ -53,14 +51,14 @@ class Session:
|
|||
return None
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == 'handle':
|
||||
if name == "handle":
|
||||
return self._session
|
||||
elif name == 'xenapi':
|
||||
elif name == "xenapi":
|
||||
# Should be patched with mocker.patch().
|
||||
return None
|
||||
elif name.startswith('login') or name.startswith('slave_local'):
|
||||
elif name.startswith("login") or name.startswith("slave_local"):
|
||||
return lambda *params: self._login(name, params)
|
||||
elif name == 'logout':
|
||||
elif name == "logout":
|
||||
return self._logout
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ def fake_xenapi_ref(xenapi_class):
|
|||
testcase_bad_xenapi_refs = {
|
||||
"params": [
|
||||
None,
|
||||
'',
|
||||
'OpaqueRef:NULL',
|
||||
"",
|
||||
"OpaqueRef:NULL",
|
||||
],
|
||||
"ids": [
|
||||
'none',
|
||||
'empty',
|
||||
'ref-null',
|
||||
"none",
|
||||
"empty",
|
||||
"ref-null",
|
||||
],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from .FakeAnsibleModule import FakeAnsibleModule
|
|||
@pytest.fixture
|
||||
def fake_ansible_module(request):
|
||||
"""Returns fake AnsibleModule with fake module params."""
|
||||
if hasattr(request, 'param'):
|
||||
if hasattr(request, "param"):
|
||||
return FakeAnsibleModule(request.param)
|
||||
else:
|
||||
params = {
|
||||
|
|
@ -42,12 +42,14 @@ def XenAPI():
|
|||
|
||||
# First we use importlib.import_module() to import the module and assign
|
||||
# it to a local symbol.
|
||||
fake_xenapi = importlib.import_module('ansible_collections.community.general.tests.unit.plugins.module_utils.xenserver.FakeXenAPI')
|
||||
fake_xenapi = importlib.import_module(
|
||||
"ansible_collections.community.general.tests.unit.plugins.module_utils.xenserver.FakeXenAPI"
|
||||
)
|
||||
|
||||
# Now we populate Python module cache with imported fake module using the
|
||||
# original module name (XenAPI). That way, any 'import XenAPI' statement
|
||||
# will just load already imported fake module from the cache.
|
||||
sys.modules['XenAPI'] = fake_xenapi
|
||||
sys.modules["XenAPI"] = fake_xenapi
|
||||
|
||||
return fake_xenapi
|
||||
|
||||
|
|
@ -83,7 +85,7 @@ def mock_xenapi_failure(XenAPI, mocker):
|
|||
child_mock.side_effect = self.side_effect
|
||||
return child_mock
|
||||
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', new=MagicMockSideEffect(), create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", new=MagicMockSideEffect(), create=True)
|
||||
mocked_xenapi.side_effect = XenAPI.Failure(fake_error_msg)
|
||||
|
||||
return mocked_xenapi, fake_error_msg
|
||||
|
|
@ -92,10 +94,10 @@ def mock_xenapi_failure(XenAPI, mocker):
|
|||
@pytest.fixture
|
||||
def fixture_data_from_file(request):
|
||||
"""Loads fixture data from files."""
|
||||
if not hasattr(request, 'param'):
|
||||
if not hasattr(request, "param"):
|
||||
return {}
|
||||
|
||||
fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
|
||||
fixture_path = os.path.join(os.path.dirname(__file__), "fixtures")
|
||||
fixture_data = {}
|
||||
|
||||
if isinstance(request.param, str):
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ testcase_gather_vm_params_and_facts = {
|
|||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('vm_ref', testcase_bad_xenapi_refs['params'], ids=testcase_bad_xenapi_refs['ids']) # type: ignore
|
||||
@pytest.mark.parametrize("vm_ref", testcase_bad_xenapi_refs["params"], ids=testcase_bad_xenapi_refs["ids"]) # type: ignore
|
||||
def test_gather_vm_params_bad_vm_ref(fake_ansible_module, xenserver, vm_ref):
|
||||
"""Tests return of empty dict on bad vm_ref."""
|
||||
assert xenserver.gather_vm_params(fake_ansible_module, vm_ref) == {}
|
||||
|
|
@ -37,13 +37,15 @@ def test_gather_vm_facts_no_vm_params(fake_ansible_module, xenserver):
|
|||
assert xenserver.gather_vm_facts(fake_ansible_module, {}) == {}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fixture_data_from_file',
|
||||
testcase_gather_vm_params_and_facts['params'], # type: ignore
|
||||
ids=testcase_gather_vm_params_and_facts['ids'], # type: ignore
|
||||
indirect=True)
|
||||
@pytest.mark.parametrize(
|
||||
"fixture_data_from_file",
|
||||
testcase_gather_vm_params_and_facts["params"], # type: ignore
|
||||
ids=testcase_gather_vm_params_and_facts["ids"], # type: ignore
|
||||
indirect=True,
|
||||
)
|
||||
def test_gather_vm_params_and_facts(mocker, fake_ansible_module, XenAPI, xenserver, fixture_data_from_file):
|
||||
"""Tests proper parsing of VM parameters and facts."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
if "params" in list(fixture_data_from_file.keys())[0]:
|
||||
params_file = list(fixture_data_from_file.keys())[0]
|
||||
|
|
@ -53,21 +55,29 @@ def test_gather_vm_params_and_facts(mocker, fake_ansible_module, XenAPI, xenserv
|
|||
facts_file = list(fixture_data_from_file.keys())[0]
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['VM'][obj_ref],
|
||||
"VM_metrics.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['VM_metrics'][obj_ref],
|
||||
"VM_guest_metrics.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['VM_guest_metrics'][obj_ref],
|
||||
"VBD.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['VBD'][obj_ref],
|
||||
"VDI.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['VDI'][obj_ref],
|
||||
"SR.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['SR'][obj_ref],
|
||||
"VIF.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['VIF'][obj_ref],
|
||||
"network.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['network'][obj_ref],
|
||||
"host.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]['host'][obj_ref],
|
||||
"VM.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]["VM"][obj_ref],
|
||||
"VM_metrics.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]["VM_metrics"][obj_ref],
|
||||
"VM_guest_metrics.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file][
|
||||
"VM_guest_metrics"
|
||||
][obj_ref],
|
||||
"VBD.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]["VBD"][obj_ref],
|
||||
"VDI.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]["VDI"][obj_ref],
|
||||
"SR.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]["SR"][obj_ref],
|
||||
"VIF.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]["VIF"][obj_ref],
|
||||
"network.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]["network"][obj_ref],
|
||||
"host.get_record.side_effect": lambda obj_ref: fixture_data_from_file[params_file]["host"][obj_ref],
|
||||
}
|
||||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
mocker.patch('ansible_collections.community.general.plugins.module_utils.xenserver.get_xenserver_version', return_value=[7, 2, 0])
|
||||
mocker.patch(
|
||||
"ansible_collections.community.general.plugins.module_utils.xenserver.get_xenserver_version",
|
||||
return_value=[7, 2, 0],
|
||||
)
|
||||
|
||||
vm_ref = list(fixture_data_from_file[params_file]['VM'].keys())[0]
|
||||
vm_ref = list(fixture_data_from_file[params_file]["VM"].keys())[0]
|
||||
|
||||
assert xenserver.gather_vm_facts(fake_ansible_module, xenserver.gather_vm_params(fake_ansible_module, vm_ref)) == fixture_data_from_file[facts_file]
|
||||
assert (
|
||||
xenserver.gather_vm_facts(fake_ansible_module, xenserver.gather_vm_params(fake_ansible_module, vm_ref))
|
||||
== fixture_data_from_file[facts_file]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,59 +14,67 @@ from .common import fake_xenapi_ref
|
|||
|
||||
def test_get_object_ref_xenapi_failure(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests catching of XenAPI failures."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi_request', side_effect=XenAPI.Failure('Fake XAPI method call error!'))
|
||||
mocked_xenapi = mocker.patch.object(
|
||||
XenAPI.Session, "xenapi_request", side_effect=XenAPI.Failure("Fake XAPI method call error!")
|
||||
)
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.get_object_ref(fake_ansible_module, "name")
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == "XAPI ERROR: Fake XAPI method call error!"
|
||||
assert exc_info.value.kwargs["msg"] == "XAPI ERROR: Fake XAPI method call error!"
|
||||
|
||||
|
||||
def test_get_object_ref_bad_uuid_and_name(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests failure on bad object uuid and/or name."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi_request')
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi_request")
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.get_object_ref(fake_ansible_module, None, msg_prefix="Test: ")
|
||||
|
||||
mocked_xenapi.xenapi_request.assert_not_called()
|
||||
assert exc_info.value.kwargs['msg'] == "Test: no valid name or UUID supplied for VM!"
|
||||
assert exc_info.value.kwargs["msg"] == "Test: no valid name or UUID supplied for VM!"
|
||||
|
||||
|
||||
def test_get_object_ref_uuid_not_found(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests when object is not found by uuid."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi_request', side_effect=XenAPI.Failure('Fake XAPI not found error!'))
|
||||
mocked_xenapi = mocker.patch.object(
|
||||
XenAPI.Session, "xenapi_request", side_effect=XenAPI.Failure("Fake XAPI not found error!")
|
||||
)
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.get_object_ref(fake_ansible_module, "name", uuid="fake-uuid", msg_prefix="Test: ")
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == "Test: VM with UUID 'fake-uuid' not found!"
|
||||
assert xenserver.get_object_ref(fake_ansible_module, "name", uuid="fake-uuid", fail=False, msg_prefix="Test: ") is None
|
||||
assert exc_info.value.kwargs["msg"] == "Test: VM with UUID 'fake-uuid' not found!"
|
||||
assert (
|
||||
xenserver.get_object_ref(fake_ansible_module, "name", uuid="fake-uuid", fail=False, msg_prefix="Test: ") is None
|
||||
)
|
||||
|
||||
|
||||
def test_get_object_ref_name_not_found(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests when object is not found by name."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi_request', return_value=[])
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi_request", return_value=[])
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.get_object_ref(fake_ansible_module, "name", msg_prefix="Test: ")
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == "Test: VM with name 'name' not found!"
|
||||
assert exc_info.value.kwargs["msg"] == "Test: VM with name 'name' not found!"
|
||||
assert xenserver.get_object_ref(fake_ansible_module, "name", fail=False, msg_prefix="Test: ") is None
|
||||
|
||||
|
||||
def test_get_object_ref_name_multiple_found(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests when multiple objects are found by name."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi_request', return_value=[fake_xenapi_ref('VM'), fake_xenapi_ref('VM')])
|
||||
mocked_xenapi = mocker.patch.object(
|
||||
XenAPI.Session, "xenapi_request", return_value=[fake_xenapi_ref("VM"), fake_xenapi_ref("VM")]
|
||||
)
|
||||
|
||||
error_msg = "Test: multiple VMs with name 'name' found! Please use UUID."
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.get_object_ref(fake_ansible_module, "name", msg_prefix="Test: ")
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == error_msg
|
||||
assert exc_info.value.kwargs["msg"] == error_msg
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.get_object_ref(fake_ansible_module, "name", fail=False, msg_prefix="Test: ")
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == error_msg
|
||||
assert exc_info.value.kwargs["msg"] == error_msg
|
||||
|
|
|
|||
|
|
@ -11,171 +11,179 @@ import pytest
|
|||
from ansible.module_utils.common.network import is_mac
|
||||
|
||||
testcase_is_valid_mac_addr = [
|
||||
('A4-23-8D-F8-C9-E5', True),
|
||||
('35:71:F4:11:0B:D8', True),
|
||||
('b3-bd-20-59-0c-cf', True),
|
||||
('32:61:ca:65:f1:f4', True),
|
||||
('asdf', False),
|
||||
('A4-23-8D-G8-C9-E5', False),
|
||||
('A4-3-8D-F8-C9-E5', False),
|
||||
('A4-23-88D-F8-C9-E5', False),
|
||||
('A4-23-8D-F8-C9_E5', False),
|
||||
('A4-23--8D-F8-C9-E5', False),
|
||||
("A4-23-8D-F8-C9-E5", True),
|
||||
("35:71:F4:11:0B:D8", True),
|
||||
("b3-bd-20-59-0c-cf", True),
|
||||
("32:61:ca:65:f1:f4", True),
|
||||
("asdf", False),
|
||||
("A4-23-8D-G8-C9-E5", False),
|
||||
("A4-3-8D-F8-C9-E5", False),
|
||||
("A4-23-88D-F8-C9-E5", False),
|
||||
("A4-23-8D-F8-C9_E5", False),
|
||||
("A4-23--8D-F8-C9-E5", False),
|
||||
]
|
||||
|
||||
testcase_is_valid_ip_addr = [
|
||||
('0.0.0.0', True),
|
||||
('10.0.0.1', True),
|
||||
('192.168.0.1', True),
|
||||
('255.255.255.255', True),
|
||||
('asdf', False),
|
||||
('a.b.c.d', False),
|
||||
('345.345.345.345', False),
|
||||
('-10.0.0.1', False),
|
||||
("0.0.0.0", True),
|
||||
("10.0.0.1", True),
|
||||
("192.168.0.1", True),
|
||||
("255.255.255.255", True),
|
||||
("asdf", False),
|
||||
("a.b.c.d", False),
|
||||
("345.345.345.345", False),
|
||||
("-10.0.0.1", False),
|
||||
]
|
||||
|
||||
testcase_is_valid_ip_netmask = [
|
||||
('240.0.0.0', True),
|
||||
('255.224.0.0', True),
|
||||
('255.255.248.0', True),
|
||||
('255.255.255.255', True),
|
||||
('asdf', False),
|
||||
('a.b.c.d', False),
|
||||
('192.168.0.1', False),
|
||||
('255.0.248.0', False),
|
||||
("240.0.0.0", True),
|
||||
("255.224.0.0", True),
|
||||
("255.255.248.0", True),
|
||||
("255.255.255.255", True),
|
||||
("asdf", False),
|
||||
("a.b.c.d", False),
|
||||
("192.168.0.1", False),
|
||||
("255.0.248.0", False),
|
||||
]
|
||||
|
||||
testcase_is_valid_ip_prefix = [
|
||||
('0', True),
|
||||
('16', True),
|
||||
('24', True),
|
||||
('32', True),
|
||||
('asdf', False),
|
||||
('-10', False),
|
||||
('60', False),
|
||||
('60s', False),
|
||||
("0", True),
|
||||
("16", True),
|
||||
("24", True),
|
||||
("32", True),
|
||||
("asdf", False),
|
||||
("-10", False),
|
||||
("60", False),
|
||||
("60s", False),
|
||||
]
|
||||
|
||||
testcase_ip_prefix_to_netmask = {
|
||||
"params": [
|
||||
('0', '0.0.0.0'),
|
||||
('8', '255.0.0.0'),
|
||||
('11', '255.224.0.0'),
|
||||
('16', '255.255.0.0'),
|
||||
('21', '255.255.248.0'),
|
||||
('24', '255.255.255.0'),
|
||||
('26', '255.255.255.192'),
|
||||
('32', '255.255.255.255'),
|
||||
('a', ''),
|
||||
('60', ''),
|
||||
("0", "0.0.0.0"),
|
||||
("8", "255.0.0.0"),
|
||||
("11", "255.224.0.0"),
|
||||
("16", "255.255.0.0"),
|
||||
("21", "255.255.248.0"),
|
||||
("24", "255.255.255.0"),
|
||||
("26", "255.255.255.192"),
|
||||
("32", "255.255.255.255"),
|
||||
("a", ""),
|
||||
("60", ""),
|
||||
],
|
||||
"ids": [
|
||||
'0',
|
||||
'8',
|
||||
'11',
|
||||
'16',
|
||||
'21',
|
||||
'24',
|
||||
'26',
|
||||
'32',
|
||||
'a',
|
||||
'60',
|
||||
"0",
|
||||
"8",
|
||||
"11",
|
||||
"16",
|
||||
"21",
|
||||
"24",
|
||||
"26",
|
||||
"32",
|
||||
"a",
|
||||
"60",
|
||||
],
|
||||
}
|
||||
|
||||
testcase_ip_netmask_to_prefix = {
|
||||
"params": [
|
||||
('0.0.0.0', '0'),
|
||||
('255.0.0.0', '8'),
|
||||
('255.224.0.0', '11'),
|
||||
('255.255.0.0', '16'),
|
||||
('255.255.248.0', '21'),
|
||||
('255.255.255.0', '24'),
|
||||
('255.255.255.192', '26'),
|
||||
('255.255.255.255', '32'),
|
||||
('a', ''),
|
||||
('60', ''),
|
||||
("0.0.0.0", "0"),
|
||||
("255.0.0.0", "8"),
|
||||
("255.224.0.0", "11"),
|
||||
("255.255.0.0", "16"),
|
||||
("255.255.248.0", "21"),
|
||||
("255.255.255.0", "24"),
|
||||
("255.255.255.192", "26"),
|
||||
("255.255.255.255", "32"),
|
||||
("a", ""),
|
||||
("60", ""),
|
||||
],
|
||||
"ids": [
|
||||
'0.0.0.0',
|
||||
'255.0.0.0',
|
||||
'255.224.0.0',
|
||||
'255.255.0.0',
|
||||
'255.255.248.0',
|
||||
'255.255.255.0',
|
||||
'255.255.255.192',
|
||||
'255.255.255.255',
|
||||
'a',
|
||||
'60',
|
||||
"0.0.0.0",
|
||||
"255.0.0.0",
|
||||
"255.224.0.0",
|
||||
"255.255.0.0",
|
||||
"255.255.248.0",
|
||||
"255.255.255.0",
|
||||
"255.255.255.192",
|
||||
"255.255.255.255",
|
||||
"a",
|
||||
"60",
|
||||
],
|
||||
}
|
||||
|
||||
testcase_is_valid_ip6_addr = [
|
||||
('::1', True),
|
||||
('2001:DB8:0:0:8:800:200C:417A', True),
|
||||
('2001:DB8::8:800:200C:417A', True),
|
||||
('FF01::101', True),
|
||||
('asdf', False),
|
||||
('2001:DB8:0:0:8:800:200C:417A:221', False),
|
||||
('FF01::101::2', False),
|
||||
('2001:db8:85a3::8a2e:370k:7334', False),
|
||||
("::1", True),
|
||||
("2001:DB8:0:0:8:800:200C:417A", True),
|
||||
("2001:DB8::8:800:200C:417A", True),
|
||||
("FF01::101", True),
|
||||
("asdf", False),
|
||||
("2001:DB8:0:0:8:800:200C:417A:221", False),
|
||||
("FF01::101::2", False),
|
||||
("2001:db8:85a3::8a2e:370k:7334", False),
|
||||
]
|
||||
|
||||
testcase_is_valid_ip6_prefix = [
|
||||
('0', True),
|
||||
('56', True),
|
||||
('78', True),
|
||||
('128', True),
|
||||
('asdf', False),
|
||||
('-10', False),
|
||||
('345', False),
|
||||
('60s', False),
|
||||
("0", True),
|
||||
("56", True),
|
||||
("78", True),
|
||||
("128", True),
|
||||
("asdf", False),
|
||||
("-10", False),
|
||||
("345", False),
|
||||
("60s", False),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('mac_addr, result', testcase_is_valid_mac_addr)
|
||||
@pytest.mark.parametrize("mac_addr, result", testcase_is_valid_mac_addr)
|
||||
def test_is_valid_mac_addr(xenserver, mac_addr, result):
|
||||
"""Tests against examples of valid and invalid mac addresses."""
|
||||
assert is_mac(mac_addr) is result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ip_addr, result', testcase_is_valid_ip_addr)
|
||||
@pytest.mark.parametrize("ip_addr, result", testcase_is_valid_ip_addr)
|
||||
def test_is_valid_ip_addr(xenserver, ip_addr, result):
|
||||
"""Tests against examples of valid and invalid ip addresses."""
|
||||
assert xenserver.is_valid_ip_addr(ip_addr) is result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ip_netmask, result', testcase_is_valid_ip_netmask)
|
||||
@pytest.mark.parametrize("ip_netmask, result", testcase_is_valid_ip_netmask)
|
||||
def test_is_valid_ip_netmask(xenserver, ip_netmask, result):
|
||||
"""Tests against examples of valid and invalid ip netmasks."""
|
||||
assert xenserver.is_valid_ip_netmask(ip_netmask) is result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ip_prefix, result', testcase_is_valid_ip_prefix)
|
||||
@pytest.mark.parametrize("ip_prefix, result", testcase_is_valid_ip_prefix)
|
||||
def test_is_valid_ip_prefix(xenserver, ip_prefix, result):
|
||||
"""Tests against examples of valid and invalid ip prefixes."""
|
||||
assert xenserver.is_valid_ip_prefix(ip_prefix) is result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ip_prefix, ip_netmask', testcase_ip_prefix_to_netmask['params'], ids=testcase_ip_prefix_to_netmask['ids']) # type: ignore
|
||||
@pytest.mark.parametrize(
|
||||
"ip_prefix, ip_netmask",
|
||||
testcase_ip_prefix_to_netmask["params"], # type: ignore
|
||||
ids=testcase_ip_prefix_to_netmask["ids"], # type: ignore
|
||||
)
|
||||
def test_ip_prefix_to_netmask(xenserver, ip_prefix, ip_netmask):
|
||||
"""Tests ip prefix to netmask conversion."""
|
||||
assert xenserver.ip_prefix_to_netmask(ip_prefix) == ip_netmask
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ip_netmask, ip_prefix', testcase_ip_netmask_to_prefix['params'], ids=testcase_ip_netmask_to_prefix['ids']) # type: ignore
|
||||
@pytest.mark.parametrize(
|
||||
"ip_netmask, ip_prefix",
|
||||
testcase_ip_netmask_to_prefix["params"], # type: ignore
|
||||
ids=testcase_ip_netmask_to_prefix["ids"], # type: ignore
|
||||
)
|
||||
def test_ip_netmask_to_prefix(xenserver, ip_netmask, ip_prefix):
|
||||
"""Tests ip netmask to prefix conversion."""
|
||||
assert xenserver.ip_netmask_to_prefix(ip_netmask) == ip_prefix
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ip6_addr, result', testcase_is_valid_ip6_addr)
|
||||
@pytest.mark.parametrize("ip6_addr, result", testcase_is_valid_ip6_addr)
|
||||
def test_is_valid_ip6_addr(xenserver, ip6_addr, result):
|
||||
"""Tests against examples of valid and invalid ip6 addresses."""
|
||||
assert xenserver.is_valid_ip6_addr(ip6_addr) is result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ip6_prefix, result', testcase_is_valid_ip6_prefix)
|
||||
@pytest.mark.parametrize("ip6_prefix, result", testcase_is_valid_ip6_prefix)
|
||||
def test_is_valid_ip6_prefix(xenserver, ip6_prefix, result):
|
||||
"""Tests against examples of valid and invalid ip6 prefixes."""
|
||||
assert xenserver.is_valid_ip6_prefix(ip6_prefix) is result
|
||||
|
|
|
|||
|
|
@ -14,16 +14,16 @@ from .common import fake_xenapi_ref, testcase_bad_xenapi_refs
|
|||
|
||||
testcase_set_vm_power_state_bad_transitions = {
|
||||
"params": [
|
||||
('restarted', 'Halted', "Cannot restart VM in state 'poweredoff'!"),
|
||||
('restarted', 'Suspended', "Cannot restart VM in state 'suspended'!"),
|
||||
('suspended', 'Halted', "Cannot suspend VM in state 'poweredoff'!"),
|
||||
('suspended', 'Paused', "Cannot suspend VM in state 'paused'!"),
|
||||
('shutdownguest', 'Halted', "Cannot shutdown guest when VM is in state 'poweredoff'!"),
|
||||
('shutdownguest', 'Suspended', "Cannot shutdown guest when VM is in state 'suspended'!"),
|
||||
('shutdownguest', 'Paused', "Cannot shutdown guest when VM is in state 'paused'!"),
|
||||
('rebootguest', 'Halted', "Cannot reboot guest when VM is in state 'poweredoff'!"),
|
||||
('rebootguest', 'Suspended', "Cannot reboot guest when VM is in state 'suspended'!"),
|
||||
('rebootguest', 'Paused', "Cannot reboot guest when VM is in state 'paused'!"),
|
||||
("restarted", "Halted", "Cannot restart VM in state 'poweredoff'!"),
|
||||
("restarted", "Suspended", "Cannot restart VM in state 'suspended'!"),
|
||||
("suspended", "Halted", "Cannot suspend VM in state 'poweredoff'!"),
|
||||
("suspended", "Paused", "Cannot suspend VM in state 'paused'!"),
|
||||
("shutdownguest", "Halted", "Cannot shutdown guest when VM is in state 'poweredoff'!"),
|
||||
("shutdownguest", "Suspended", "Cannot shutdown guest when VM is in state 'suspended'!"),
|
||||
("shutdownguest", "Paused", "Cannot shutdown guest when VM is in state 'paused'!"),
|
||||
("rebootguest", "Halted", "Cannot reboot guest when VM is in state 'poweredoff'!"),
|
||||
("rebootguest", "Suspended", "Cannot reboot guest when VM is in state 'suspended'!"),
|
||||
("rebootguest", "Paused", "Cannot reboot guest when VM is in state 'paused'!"),
|
||||
],
|
||||
"ids": [
|
||||
"poweredoff->restarted",
|
||||
|
|
@ -41,8 +41,8 @@ testcase_set_vm_power_state_bad_transitions = {
|
|||
|
||||
testcase_set_vm_power_state_task_timeout = {
|
||||
"params": [
|
||||
('shutdownguest', "Guest shutdown task failed: 'timeout'!"),
|
||||
('rebootguest', "Guest reboot task failed: 'timeout'!"),
|
||||
("shutdownguest", "Guest shutdown task failed: 'timeout'!"),
|
||||
("rebootguest", "Guest reboot task failed: 'timeout'!"),
|
||||
],
|
||||
"ids": [
|
||||
"shutdownguest-timeout",
|
||||
|
|
@ -52,16 +52,16 @@ testcase_set_vm_power_state_task_timeout = {
|
|||
|
||||
testcase_set_vm_power_state_no_transitions = {
|
||||
"params": [
|
||||
('poweredon', "Running"),
|
||||
('Poweredon', "Running"),
|
||||
('powered-on', "Running"),
|
||||
('Powered_on', "Running"),
|
||||
('poweredoff', "Halted"),
|
||||
('Poweredoff', "Halted"),
|
||||
('powered-off', "Halted"),
|
||||
('powered_off', "Halted"),
|
||||
('suspended', "Suspended"),
|
||||
('Suspended', "Suspended"),
|
||||
("poweredon", "Running"),
|
||||
("Poweredon", "Running"),
|
||||
("powered-on", "Running"),
|
||||
("Powered_on", "Running"),
|
||||
("poweredoff", "Halted"),
|
||||
("Poweredoff", "Halted"),
|
||||
("powered-off", "Halted"),
|
||||
("powered_off", "Halted"),
|
||||
("suspended", "Suspended"),
|
||||
("Suspended", "Suspended"),
|
||||
],
|
||||
"ids": [
|
||||
"poweredon",
|
||||
|
|
@ -79,44 +79,44 @@ testcase_set_vm_power_state_no_transitions = {
|
|||
|
||||
testcase_set_vm_power_state_transitions = {
|
||||
"params": [
|
||||
('poweredon', 'Halted', 'running', 'VM.start'),
|
||||
('Poweredon', 'Halted', 'running', 'VM.start'),
|
||||
('powered-on', 'Halted', 'running', 'VM.start'),
|
||||
('Powered_on', 'Halted', 'running', 'VM.start'),
|
||||
('poweredon', 'Suspended', 'running', 'VM.resume'),
|
||||
('Poweredon', 'Suspended', 'running', 'VM.resume'),
|
||||
('powered-on', 'Suspended', 'running', 'VM.resume'),
|
||||
('Powered_on', 'Suspended', 'running', 'VM.resume'),
|
||||
('poweredon', 'Paused', 'running', 'VM.unpause'),
|
||||
('Poweredon', 'Paused', 'running', 'VM.unpause'),
|
||||
('powered-on', 'Paused', 'running', 'VM.unpause'),
|
||||
('Powered_on', 'Paused', 'running', 'VM.unpause'),
|
||||
('poweredoff', 'Running', 'halted', 'VM.hard_shutdown'),
|
||||
('Poweredoff', 'Running', 'halted', 'VM.hard_shutdown'),
|
||||
('powered-off', 'Running', 'halted', 'VM.hard_shutdown'),
|
||||
('powered_off', 'Running', 'halted', 'VM.hard_shutdown'),
|
||||
('poweredoff', 'Suspended', 'halted', 'VM.hard_shutdown'),
|
||||
('Poweredoff', 'Suspended', 'halted', 'VM.hard_shutdown'),
|
||||
('powered-off', 'Suspended', 'halted', 'VM.hard_shutdown'),
|
||||
('powered_off', 'Suspended', 'halted', 'VM.hard_shutdown'),
|
||||
('poweredoff', 'Paused', 'halted', 'VM.hard_shutdown'),
|
||||
('Poweredoff', 'Paused', 'halted', 'VM.hard_shutdown'),
|
||||
('powered-off', 'Paused', 'halted', 'VM.hard_shutdown'),
|
||||
('powered_off', 'Paused', 'halted', 'VM.hard_shutdown'),
|
||||
('restarted', 'Running', 'running', 'VM.hard_reboot'),
|
||||
('Restarted', 'Running', 'running', 'VM.hard_reboot'),
|
||||
('restarted', 'Paused', 'running', 'VM.hard_reboot'),
|
||||
('Restarted', 'Paused', 'running', 'VM.hard_reboot'),
|
||||
('suspended', 'Running', 'suspended', 'VM.suspend'),
|
||||
('Suspended', 'Running', 'suspended', 'VM.suspend'),
|
||||
('shutdownguest', 'Running', 'halted', 'VM.clean_shutdown'),
|
||||
('Shutdownguest', 'Running', 'halted', 'VM.clean_shutdown'),
|
||||
('shutdown-guest', 'Running', 'halted', 'VM.clean_shutdown'),
|
||||
('shutdown_guest', 'Running', 'halted', 'VM.clean_shutdown'),
|
||||
('rebootguest', 'Running', 'running', 'VM.clean_reboot'),
|
||||
('rebootguest', 'Running', 'running', 'VM.clean_reboot'),
|
||||
('reboot-guest', 'Running', 'running', 'VM.clean_reboot'),
|
||||
('reboot_guest', 'Running', 'running', 'VM.clean_reboot'),
|
||||
("poweredon", "Halted", "running", "VM.start"),
|
||||
("Poweredon", "Halted", "running", "VM.start"),
|
||||
("powered-on", "Halted", "running", "VM.start"),
|
||||
("Powered_on", "Halted", "running", "VM.start"),
|
||||
("poweredon", "Suspended", "running", "VM.resume"),
|
||||
("Poweredon", "Suspended", "running", "VM.resume"),
|
||||
("powered-on", "Suspended", "running", "VM.resume"),
|
||||
("Powered_on", "Suspended", "running", "VM.resume"),
|
||||
("poweredon", "Paused", "running", "VM.unpause"),
|
||||
("Poweredon", "Paused", "running", "VM.unpause"),
|
||||
("powered-on", "Paused", "running", "VM.unpause"),
|
||||
("Powered_on", "Paused", "running", "VM.unpause"),
|
||||
("poweredoff", "Running", "halted", "VM.hard_shutdown"),
|
||||
("Poweredoff", "Running", "halted", "VM.hard_shutdown"),
|
||||
("powered-off", "Running", "halted", "VM.hard_shutdown"),
|
||||
("powered_off", "Running", "halted", "VM.hard_shutdown"),
|
||||
("poweredoff", "Suspended", "halted", "VM.hard_shutdown"),
|
||||
("Poweredoff", "Suspended", "halted", "VM.hard_shutdown"),
|
||||
("powered-off", "Suspended", "halted", "VM.hard_shutdown"),
|
||||
("powered_off", "Suspended", "halted", "VM.hard_shutdown"),
|
||||
("poweredoff", "Paused", "halted", "VM.hard_shutdown"),
|
||||
("Poweredoff", "Paused", "halted", "VM.hard_shutdown"),
|
||||
("powered-off", "Paused", "halted", "VM.hard_shutdown"),
|
||||
("powered_off", "Paused", "halted", "VM.hard_shutdown"),
|
||||
("restarted", "Running", "running", "VM.hard_reboot"),
|
||||
("Restarted", "Running", "running", "VM.hard_reboot"),
|
||||
("restarted", "Paused", "running", "VM.hard_reboot"),
|
||||
("Restarted", "Paused", "running", "VM.hard_reboot"),
|
||||
("suspended", "Running", "suspended", "VM.suspend"),
|
||||
("Suspended", "Running", "suspended", "VM.suspend"),
|
||||
("shutdownguest", "Running", "halted", "VM.clean_shutdown"),
|
||||
("Shutdownguest", "Running", "halted", "VM.clean_shutdown"),
|
||||
("shutdown-guest", "Running", "halted", "VM.clean_shutdown"),
|
||||
("shutdown_guest", "Running", "halted", "VM.clean_shutdown"),
|
||||
("rebootguest", "Running", "running", "VM.clean_reboot"),
|
||||
("rebootguest", "Running", "running", "VM.clean_reboot"),
|
||||
("reboot-guest", "Running", "running", "VM.clean_reboot"),
|
||||
("reboot_guest", "Running", "running", "VM.clean_reboot"),
|
||||
],
|
||||
"ids": [
|
||||
"poweredoff->poweredon",
|
||||
|
|
@ -162,14 +162,14 @@ testcase_set_vm_power_state_transitions = {
|
|||
|
||||
testcase_set_vm_power_state_transitions_async = {
|
||||
"params": [
|
||||
('shutdownguest', 'Running', 'halted', 'Async.VM.clean_shutdown'),
|
||||
('Shutdownguest', 'Running', 'halted', 'Async.VM.clean_shutdown'),
|
||||
('shutdown-guest', 'Running', 'halted', 'Async.VM.clean_shutdown'),
|
||||
('shutdown_guest', 'Running', 'halted', 'Async.VM.clean_shutdown'),
|
||||
('rebootguest', 'Running', 'running', 'Async.VM.clean_reboot'),
|
||||
('rebootguest', 'Running', 'running', 'Async.VM.clean_reboot'),
|
||||
('reboot-guest', 'Running', 'running', 'Async.VM.clean_reboot'),
|
||||
('reboot_guest', 'Running', 'running', 'Async.VM.clean_reboot'),
|
||||
("shutdownguest", "Running", "halted", "Async.VM.clean_shutdown"),
|
||||
("Shutdownguest", "Running", "halted", "Async.VM.clean_shutdown"),
|
||||
("shutdown-guest", "Running", "halted", "Async.VM.clean_shutdown"),
|
||||
("shutdown_guest", "Running", "halted", "Async.VM.clean_shutdown"),
|
||||
("rebootguest", "Running", "running", "Async.VM.clean_reboot"),
|
||||
("rebootguest", "Running", "running", "Async.VM.clean_reboot"),
|
||||
("reboot-guest", "Running", "running", "Async.VM.clean_reboot"),
|
||||
("reboot_guest", "Running", "running", "Async.VM.clean_reboot"),
|
||||
],
|
||||
"ids": [
|
||||
"poweredon->shutdownguest",
|
||||
|
|
@ -184,26 +184,26 @@ testcase_set_vm_power_state_transitions_async = {
|
|||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('vm_ref', testcase_bad_xenapi_refs['params'], ids=testcase_bad_xenapi_refs['ids']) # type: ignore
|
||||
@pytest.mark.parametrize("vm_ref", testcase_bad_xenapi_refs["params"], ids=testcase_bad_xenapi_refs["ids"]) # type: ignore
|
||||
def test_set_vm_power_state_bad_vm_ref(fake_ansible_module, xenserver, vm_ref):
|
||||
"""Tests failure on bad vm_ref."""
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.set_vm_power_state(fake_ansible_module, vm_ref, None)
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == "Cannot set VM power state. Invalid VM reference supplied!"
|
||||
assert exc_info.value.kwargs["msg"] == "Cannot set VM power state. Invalid VM reference supplied!"
|
||||
|
||||
|
||||
def test_set_vm_power_state_xenapi_failure(mock_xenapi_failure, fake_ansible_module, xenserver):
|
||||
"""Tests catching of XenAPI failures."""
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref('VM'), "poweredon")
|
||||
xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref("VM"), "poweredon")
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == f"XAPI ERROR: {mock_xenapi_failure[1]}"
|
||||
assert exc_info.value.kwargs["msg"] == f"XAPI ERROR: {mock_xenapi_failure[1]}"
|
||||
|
||||
|
||||
def test_set_vm_power_state_bad_power_state(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests failure on unsupported power state."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": "Running",
|
||||
|
|
@ -212,21 +212,25 @@ def test_set_vm_power_state_bad_power_state(mocker, fake_ansible_module, XenAPI,
|
|||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref('VM'), "bad")
|
||||
xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref("VM"), "bad")
|
||||
|
||||
# Beside VM.get_power_state() no other method should have been
|
||||
# called additionally.
|
||||
assert len(mocked_xenapi.method_calls) == 1
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == "Requested VM power state 'bad' is unsupported!"
|
||||
assert exc_info.value.kwargs["msg"] == "Requested VM power state 'bad' is unsupported!"
|
||||
|
||||
|
||||
@pytest.mark.parametrize('power_state_desired, power_state_current, error_msg',
|
||||
testcase_set_vm_power_state_bad_transitions['params'], # type: ignore
|
||||
ids=testcase_set_vm_power_state_bad_transitions['ids']) # type: ignore
|
||||
def test_set_vm_power_state_bad_transition(mocker, fake_ansible_module, XenAPI, xenserver, power_state_desired, power_state_current, error_msg):
|
||||
@pytest.mark.parametrize(
|
||||
"power_state_desired, power_state_current, error_msg",
|
||||
testcase_set_vm_power_state_bad_transitions["params"], # type: ignore
|
||||
ids=testcase_set_vm_power_state_bad_transitions["ids"], # type: ignore
|
||||
)
|
||||
def test_set_vm_power_state_bad_transition(
|
||||
mocker, fake_ansible_module, XenAPI, xenserver, power_state_desired, power_state_current, error_msg
|
||||
):
|
||||
"""Tests failure on bad power state transition."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": power_state_current,
|
||||
|
|
@ -235,48 +239,56 @@ def test_set_vm_power_state_bad_transition(mocker, fake_ansible_module, XenAPI,
|
|||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref('VM'), power_state_desired)
|
||||
xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref("VM"), power_state_desired)
|
||||
|
||||
# Beside VM.get_power_state() no other method should have been
|
||||
# called additionally.
|
||||
assert len(mocked_xenapi.method_calls) == 1
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == error_msg
|
||||
assert exc_info.value.kwargs["msg"] == error_msg
|
||||
|
||||
|
||||
@pytest.mark.parametrize('power_state, error_msg',
|
||||
testcase_set_vm_power_state_task_timeout['params'], # type: ignore
|
||||
ids=testcase_set_vm_power_state_task_timeout['ids']) # type: ignore
|
||||
@pytest.mark.parametrize(
|
||||
"power_state, error_msg",
|
||||
testcase_set_vm_power_state_task_timeout["params"], # type: ignore
|
||||
ids=testcase_set_vm_power_state_task_timeout["ids"], # type: ignore
|
||||
)
|
||||
def test_set_vm_power_state_task_timeout(mocker, fake_ansible_module, XenAPI, xenserver, power_state, error_msg):
|
||||
"""Tests failure on async task timeout."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": "Running",
|
||||
"Async.VM.clean_shutdown.return_value": fake_xenapi_ref('task'),
|
||||
"Async.VM.clean_reboot.return_value": fake_xenapi_ref('task'),
|
||||
"Async.VM.clean_shutdown.return_value": fake_xenapi_ref("task"),
|
||||
"Async.VM.clean_reboot.return_value": fake_xenapi_ref("task"),
|
||||
}
|
||||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
mocker.patch('ansible_collections.community.general.plugins.module_utils.xenserver.wait_for_task', return_value="timeout")
|
||||
mocker.patch(
|
||||
"ansible_collections.community.general.plugins.module_utils.xenserver.wait_for_task", return_value="timeout"
|
||||
)
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref('VM'), power_state, timeout=1)
|
||||
xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref("VM"), power_state, timeout=1)
|
||||
|
||||
# Beside VM.get_power_state() only one of Async.VM.clean_shutdown or
|
||||
# Async.VM.clean_reboot should have been called additionally.
|
||||
assert len(mocked_xenapi.method_calls) == 2
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == error_msg
|
||||
assert exc_info.value.kwargs["msg"] == error_msg
|
||||
|
||||
|
||||
@pytest.mark.parametrize('power_state_desired, power_state_current',
|
||||
testcase_set_vm_power_state_no_transitions['params'], # type: ignore
|
||||
ids=testcase_set_vm_power_state_no_transitions['ids']) # type: ignore
|
||||
def test_set_vm_power_state_no_transition(mocker, fake_ansible_module, XenAPI, xenserver, power_state_desired, power_state_current):
|
||||
@pytest.mark.parametrize(
|
||||
"power_state_desired, power_state_current",
|
||||
testcase_set_vm_power_state_no_transitions["params"], # type: ignore
|
||||
ids=testcase_set_vm_power_state_no_transitions["ids"], # type: ignore
|
||||
)
|
||||
def test_set_vm_power_state_no_transition(
|
||||
mocker, fake_ansible_module, XenAPI, xenserver, power_state_desired, power_state_current
|
||||
):
|
||||
"""Tests regular invocation without power state transition."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": power_state_current,
|
||||
|
|
@ -284,7 +296,7 @@ def test_set_vm_power_state_no_transition(mocker, fake_ansible_module, XenAPI, x
|
|||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
result = xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref('VM'), power_state_desired)
|
||||
result = xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref("VM"), power_state_desired)
|
||||
|
||||
# Beside VM.get_power_state() no other method should have been
|
||||
# called additionally.
|
||||
|
|
@ -294,19 +306,23 @@ def test_set_vm_power_state_no_transition(mocker, fake_ansible_module, XenAPI, x
|
|||
assert result[1] == power_state_current.lower()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('power_state_desired, power_state_current, power_state_resulting, activated_xenapi_method',
|
||||
testcase_set_vm_power_state_transitions['params'], # type: ignore
|
||||
ids=testcase_set_vm_power_state_transitions['ids']) # type: ignore
|
||||
def test_set_vm_power_state_transition(mocker,
|
||||
fake_ansible_module,
|
||||
XenAPI,
|
||||
xenserver,
|
||||
power_state_desired,
|
||||
power_state_current,
|
||||
power_state_resulting,
|
||||
activated_xenapi_method):
|
||||
@pytest.mark.parametrize(
|
||||
"power_state_desired, power_state_current, power_state_resulting, activated_xenapi_method",
|
||||
testcase_set_vm_power_state_transitions["params"], # type: ignore
|
||||
ids=testcase_set_vm_power_state_transitions["ids"], # type: ignore
|
||||
)
|
||||
def test_set_vm_power_state_transition(
|
||||
mocker,
|
||||
fake_ansible_module,
|
||||
XenAPI,
|
||||
xenserver,
|
||||
power_state_desired,
|
||||
power_state_current,
|
||||
power_state_resulting,
|
||||
activated_xenapi_method,
|
||||
):
|
||||
"""Tests regular invocation with power state transition."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": power_state_current,
|
||||
|
|
@ -314,11 +330,11 @@ def test_set_vm_power_state_transition(mocker,
|
|||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
result = xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref('VM'), power_state_desired, timeout=0)
|
||||
result = xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref("VM"), power_state_desired, timeout=0)
|
||||
|
||||
mocked_xenapi_method = mocked_xenapi
|
||||
|
||||
for activated_xenapi_class in activated_xenapi_method.split('.'):
|
||||
for activated_xenapi_class in activated_xenapi_method.split("."):
|
||||
mocked_xenapi_method = getattr(mocked_xenapi_method, activated_xenapi_class)
|
||||
|
||||
mocked_xenapi_method.assert_called_once()
|
||||
|
|
@ -331,37 +347,41 @@ def test_set_vm_power_state_transition(mocker,
|
|||
assert result[1] == power_state_resulting
|
||||
|
||||
|
||||
@pytest.mark.parametrize('power_state_desired, power_state_current, power_state_resulting, activated_xenapi_method',
|
||||
testcase_set_vm_power_state_transitions_async['params'], # type: ignore
|
||||
ids=testcase_set_vm_power_state_transitions_async['ids']) # type: ignore
|
||||
def test_set_vm_power_state_transition_async(mocker,
|
||||
fake_ansible_module,
|
||||
XenAPI,
|
||||
xenserver,
|
||||
power_state_desired,
|
||||
power_state_current,
|
||||
power_state_resulting,
|
||||
activated_xenapi_method):
|
||||
@pytest.mark.parametrize(
|
||||
"power_state_desired, power_state_current, power_state_resulting, activated_xenapi_method",
|
||||
testcase_set_vm_power_state_transitions_async["params"], # type: ignore
|
||||
ids=testcase_set_vm_power_state_transitions_async["ids"], # type: ignore
|
||||
)
|
||||
def test_set_vm_power_state_transition_async(
|
||||
mocker,
|
||||
fake_ansible_module,
|
||||
XenAPI,
|
||||
xenserver,
|
||||
power_state_desired,
|
||||
power_state_current,
|
||||
power_state_resulting,
|
||||
activated_xenapi_method,
|
||||
):
|
||||
"""
|
||||
Tests regular invocation with async power state transition
|
||||
(shutdownguest and rebootguest only).
|
||||
"""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": power_state_current,
|
||||
f"{activated_xenapi_method}.return_value": fake_xenapi_ref('task'),
|
||||
f"{activated_xenapi_method}.return_value": fake_xenapi_ref("task"),
|
||||
}
|
||||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
mocker.patch('ansible_collections.community.general.plugins.module_utils.xenserver.wait_for_task', return_value="")
|
||||
mocker.patch("ansible_collections.community.general.plugins.module_utils.xenserver.wait_for_task", return_value="")
|
||||
|
||||
result = xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref('VM'), power_state_desired, timeout=1)
|
||||
result = xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref("VM"), power_state_desired, timeout=1)
|
||||
|
||||
mocked_xenapi_method = mocked_xenapi
|
||||
|
||||
for activated_xenapi_class in activated_xenapi_method.split('.'):
|
||||
for activated_xenapi_class in activated_xenapi_method.split("."):
|
||||
mocked_xenapi_method = getattr(mocked_xenapi_method, activated_xenapi_class)
|
||||
|
||||
mocked_xenapi_method.assert_called_once()
|
||||
|
|
@ -374,19 +394,23 @@ def test_set_vm_power_state_transition_async(mocker,
|
|||
assert result[1] == power_state_resulting
|
||||
|
||||
|
||||
@pytest.mark.parametrize('power_state_desired, power_state_current, power_state_resulting, activated_xenapi_method',
|
||||
testcase_set_vm_power_state_transitions['params'], # type: ignore
|
||||
ids=testcase_set_vm_power_state_transitions['ids']) # type: ignore
|
||||
def test_set_vm_power_state_transition_check_mode(mocker,
|
||||
fake_ansible_module,
|
||||
XenAPI,
|
||||
xenserver,
|
||||
power_state_desired,
|
||||
power_state_current,
|
||||
power_state_resulting,
|
||||
activated_xenapi_method):
|
||||
@pytest.mark.parametrize(
|
||||
"power_state_desired, power_state_current, power_state_resulting, activated_xenapi_method",
|
||||
testcase_set_vm_power_state_transitions["params"], # type: ignore
|
||||
ids=testcase_set_vm_power_state_transitions["ids"], # type: ignore
|
||||
)
|
||||
def test_set_vm_power_state_transition_check_mode(
|
||||
mocker,
|
||||
fake_ansible_module,
|
||||
XenAPI,
|
||||
xenserver,
|
||||
power_state_desired,
|
||||
power_state_current,
|
||||
power_state_resulting,
|
||||
activated_xenapi_method,
|
||||
):
|
||||
"""Tests regular invocation with power state transition in check mode."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": power_state_current,
|
||||
|
|
@ -395,11 +419,11 @@ def test_set_vm_power_state_transition_check_mode(mocker,
|
|||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
fake_ansible_module.check_mode = True
|
||||
result = xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref('VM'), power_state_desired, timeout=0)
|
||||
result = xenserver.set_vm_power_state(fake_ansible_module, fake_xenapi_ref("VM"), power_state_desired, timeout=0)
|
||||
|
||||
mocked_xenapi_method = mocked_xenapi
|
||||
|
||||
for activated_xenapi_class in activated_xenapi_method.split('.'):
|
||||
for activated_xenapi_class in activated_xenapi_method.split("."):
|
||||
mocked_xenapi_method = getattr(mocked_xenapi_method, activated_xenapi_class)
|
||||
|
||||
mocked_xenapi_method.assert_not_called()
|
||||
|
|
|
|||
|
|
@ -14,71 +14,73 @@ from .common import fake_xenapi_ref, testcase_bad_xenapi_refs
|
|||
|
||||
testcase_wait_for_vm_ip_address_bad_power_states = {
|
||||
"params": [
|
||||
'Halted',
|
||||
'Paused',
|
||||
'Suspended',
|
||||
'Other',
|
||||
"Halted",
|
||||
"Paused",
|
||||
"Suspended",
|
||||
"Other",
|
||||
],
|
||||
"ids": [
|
||||
'state-halted',
|
||||
'state-paused',
|
||||
'state-suspended',
|
||||
'state-other',
|
||||
]
|
||||
"state-halted",
|
||||
"state-paused",
|
||||
"state-suspended",
|
||||
"state-other",
|
||||
],
|
||||
}
|
||||
|
||||
testcase_wait_for_vm_ip_address_bad_guest_metrics = {
|
||||
"params": [
|
||||
('OpaqueRef:NULL', {"networks": {}}),
|
||||
(fake_xenapi_ref('VM_guest_metrics'), {"networks": {}}),
|
||||
("OpaqueRef:NULL", {"networks": {}}),
|
||||
(fake_xenapi_ref("VM_guest_metrics"), {"networks": {}}),
|
||||
],
|
||||
"ids": [
|
||||
'vm_guest_metrics_ref-null, no-ip',
|
||||
'vm_guest_metrics_ref-ok, no-ip',
|
||||
"vm_guest_metrics_ref-null, no-ip",
|
||||
"vm_guest_metrics_ref-ok, no-ip",
|
||||
],
|
||||
}
|
||||
|
||||
testcase_wait_for_task_all_statuses = {
|
||||
"params": [
|
||||
('Success', ''),
|
||||
('Failure', 'failure'),
|
||||
('Cancelling', 'cancelling'),
|
||||
('Cancelled', 'cancelled'),
|
||||
('Other', 'other'),
|
||||
("Success", ""),
|
||||
("Failure", "failure"),
|
||||
("Cancelling", "cancelling"),
|
||||
("Cancelled", "cancelled"),
|
||||
("Other", "other"),
|
||||
],
|
||||
"ids": [
|
||||
'task-success',
|
||||
'task-failure',
|
||||
'task-cancelling',
|
||||
'task-cancelled',
|
||||
'task-other',
|
||||
]
|
||||
"task-success",
|
||||
"task-failure",
|
||||
"task-cancelling",
|
||||
"task-cancelled",
|
||||
"task-other",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('vm_ref', testcase_bad_xenapi_refs['params'], ids=testcase_bad_xenapi_refs['ids']) # type: ignore
|
||||
@pytest.mark.parametrize("vm_ref", testcase_bad_xenapi_refs["params"], ids=testcase_bad_xenapi_refs["ids"]) # type: ignore
|
||||
def test_wait_for_vm_ip_address_bad_vm_ref(fake_ansible_module, xenserver, vm_ref):
|
||||
"""Tests failure on bad vm_ref."""
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.wait_for_vm_ip_address(fake_ansible_module, vm_ref)
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == "Cannot wait for VM IP address. Invalid VM reference supplied!"
|
||||
assert exc_info.value.kwargs["msg"] == "Cannot wait for VM IP address. Invalid VM reference supplied!"
|
||||
|
||||
|
||||
def test_wait_for_vm_ip_address_xenapi_failure(mock_xenapi_failure, xenserver, fake_ansible_module):
|
||||
"""Tests catching of XenAPI failures."""
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.wait_for_vm_ip_address(fake_ansible_module, fake_xenapi_ref('VM'))
|
||||
xenserver.wait_for_vm_ip_address(fake_ansible_module, fake_xenapi_ref("VM"))
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == f"XAPI ERROR: {mock_xenapi_failure[1]}"
|
||||
assert exc_info.value.kwargs["msg"] == f"XAPI ERROR: {mock_xenapi_failure[1]}"
|
||||
|
||||
|
||||
@pytest.mark.parametrize('bad_power_state',
|
||||
testcase_wait_for_vm_ip_address_bad_power_states['params'],
|
||||
ids=testcase_wait_for_vm_ip_address_bad_power_states['ids'])
|
||||
@pytest.mark.parametrize(
|
||||
"bad_power_state",
|
||||
testcase_wait_for_vm_ip_address_bad_power_states["params"],
|
||||
ids=testcase_wait_for_vm_ip_address_bad_power_states["ids"],
|
||||
)
|
||||
def test_wait_for_vm_ip_address_bad_power_state(mocker, fake_ansible_module, XenAPI, xenserver, bad_power_state):
|
||||
"""Tests failure on bad power state."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": bad_power_state,
|
||||
|
|
@ -87,18 +89,23 @@ def test_wait_for_vm_ip_address_bad_power_state(mocker, fake_ansible_module, Xen
|
|||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.wait_for_vm_ip_address(fake_ansible_module, fake_xenapi_ref('VM'))
|
||||
xenserver.wait_for_vm_ip_address(fake_ansible_module, fake_xenapi_ref("VM"))
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == (
|
||||
f"Cannot wait for VM IP address when VM is in state '{xenserver.xapi_to_module_vm_power_state(bad_power_state.lower())}'!")
|
||||
assert exc_info.value.kwargs["msg"] == (
|
||||
f"Cannot wait for VM IP address when VM is in state '{xenserver.xapi_to_module_vm_power_state(bad_power_state.lower())}'!"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('bad_guest_metrics_ref, bad_guest_metrics',
|
||||
testcase_wait_for_vm_ip_address_bad_guest_metrics['params'], # type: ignore
|
||||
ids=testcase_wait_for_vm_ip_address_bad_guest_metrics['ids']) # type: ignore
|
||||
def test_wait_for_vm_ip_address_timeout(mocker, fake_ansible_module, XenAPI, xenserver, bad_guest_metrics_ref, bad_guest_metrics):
|
||||
@pytest.mark.parametrize(
|
||||
"bad_guest_metrics_ref, bad_guest_metrics",
|
||||
testcase_wait_for_vm_ip_address_bad_guest_metrics["params"], # type: ignore
|
||||
ids=testcase_wait_for_vm_ip_address_bad_guest_metrics["ids"], # type: ignore
|
||||
)
|
||||
def test_wait_for_vm_ip_address_timeout(
|
||||
mocker, fake_ansible_module, XenAPI, xenserver, bad_guest_metrics_ref, bad_guest_metrics
|
||||
):
|
||||
"""Tests timeout."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": "Running",
|
||||
|
|
@ -108,17 +115,17 @@ def test_wait_for_vm_ip_address_timeout(mocker, fake_ansible_module, XenAPI, xen
|
|||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
mocker.patch('time.sleep')
|
||||
mocker.patch("time.sleep")
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.wait_for_vm_ip_address(fake_ansible_module, fake_xenapi_ref('VM'), timeout=1)
|
||||
xenserver.wait_for_vm_ip_address(fake_ansible_module, fake_xenapi_ref("VM"), timeout=1)
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == "Timed out waiting for VM IP address!"
|
||||
assert exc_info.value.kwargs["msg"] == "Timed out waiting for VM IP address!"
|
||||
|
||||
|
||||
def test_wait_for_vm_ip_address(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests regular invocation."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
# This mock simulates regular VM IP acquirement lifecycle:
|
||||
#
|
||||
|
|
@ -130,9 +137,9 @@ def test_wait_for_vm_ip_address(mocker, fake_ansible_module, XenAPI, xenserver):
|
|||
mocked_returns = {
|
||||
"VM.get_power_state.return_value": "Running",
|
||||
"VM.get_guest_metrics.side_effect": [
|
||||
'OpaqueRef:NULL',
|
||||
fake_xenapi_ref('VM_guest_metrics'),
|
||||
fake_xenapi_ref('VM_guest_metrics'),
|
||||
"OpaqueRef:NULL",
|
||||
fake_xenapi_ref("VM_guest_metrics"),
|
||||
fake_xenapi_ref("VM_guest_metrics"),
|
||||
],
|
||||
"VM_guest_metrics.get_record.side_effect": [
|
||||
{
|
||||
|
|
@ -149,33 +156,33 @@ def test_wait_for_vm_ip_address(mocker, fake_ansible_module, XenAPI, xenserver):
|
|||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
mocker.patch('time.sleep')
|
||||
mocker.patch("time.sleep")
|
||||
|
||||
fake_guest_metrics = xenserver.wait_for_vm_ip_address(fake_ansible_module, fake_xenapi_ref('VM'))
|
||||
fake_guest_metrics = xenserver.wait_for_vm_ip_address(fake_ansible_module, fake_xenapi_ref("VM"))
|
||||
|
||||
assert fake_guest_metrics == mocked_returns['VM_guest_metrics.get_record.side_effect'][1]
|
||||
assert fake_guest_metrics == mocked_returns["VM_guest_metrics.get_record.side_effect"][1]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('task_ref', testcase_bad_xenapi_refs['params'], ids=testcase_bad_xenapi_refs['ids']) # type: ignore
|
||||
@pytest.mark.parametrize("task_ref", testcase_bad_xenapi_refs["params"], ids=testcase_bad_xenapi_refs["ids"]) # type: ignore
|
||||
def test_wait_for_task_bad_task_ref(fake_ansible_module, xenserver, task_ref):
|
||||
"""Tests failure on bad task_ref."""
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.wait_for_task(fake_ansible_module, task_ref)
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == "Cannot wait for task. Invalid task reference supplied!"
|
||||
assert exc_info.value.kwargs["msg"] == "Cannot wait for task. Invalid task reference supplied!"
|
||||
|
||||
|
||||
def test_wait_for_task_xenapi_failure(mock_xenapi_failure, fake_ansible_module, xenserver):
|
||||
"""Tests catching of XenAPI failures."""
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.wait_for_task(fake_ansible_module, fake_xenapi_ref('task'))
|
||||
xenserver.wait_for_task(fake_ansible_module, fake_xenapi_ref("task"))
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == f"XAPI ERROR: {mock_xenapi_failure[1]}"
|
||||
assert exc_info.value.kwargs["msg"] == f"XAPI ERROR: {mock_xenapi_failure[1]}"
|
||||
|
||||
|
||||
def test_wait_for_task_timeout(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests timeout."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"task.get_status.return_value": "Pending",
|
||||
|
|
@ -184,26 +191,28 @@ def test_wait_for_task_timeout(mocker, fake_ansible_module, XenAPI, xenserver):
|
|||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
mocker.patch('time.sleep')
|
||||
mocker.patch("time.sleep")
|
||||
|
||||
fake_result = xenserver.wait_for_task(fake_ansible_module, fake_xenapi_ref('task'), timeout=1)
|
||||
fake_result = xenserver.wait_for_task(fake_ansible_module, fake_xenapi_ref("task"), timeout=1)
|
||||
|
||||
mocked_xenapi.task.destroy.assert_called_once()
|
||||
assert fake_result == "timeout"
|
||||
|
||||
|
||||
@pytest.mark.parametrize('task_status, result',
|
||||
testcase_wait_for_task_all_statuses['params'], # type: ignore
|
||||
ids=testcase_wait_for_task_all_statuses['ids']) # type: ignore
|
||||
@pytest.mark.parametrize(
|
||||
"task_status, result",
|
||||
testcase_wait_for_task_all_statuses["params"], # type: ignore
|
||||
ids=testcase_wait_for_task_all_statuses["ids"], # type: ignore
|
||||
)
|
||||
def test_wait_for_task(mocker, fake_ansible_module, XenAPI, xenserver, task_status, result):
|
||||
"""Tests regular invocation."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
# Mock will first return Pending status and on second invocation it will
|
||||
# return one of possible final statuses.
|
||||
mocked_returns = {
|
||||
"task.get_status.side_effect": [
|
||||
'Pending',
|
||||
"Pending",
|
||||
task_status,
|
||||
],
|
||||
"task.destroy.return_value": None,
|
||||
|
|
@ -211,9 +220,9 @@ def test_wait_for_task(mocker, fake_ansible_module, XenAPI, xenserver, task_stat
|
|||
|
||||
mocked_xenapi.configure_mock(**mocked_returns)
|
||||
|
||||
mocker.patch('time.sleep')
|
||||
mocker.patch("time.sleep")
|
||||
|
||||
fake_result = xenserver.wait_for_task(fake_ansible_module, fake_xenapi_ref('task'))
|
||||
fake_result = xenserver.wait_for_task(fake_ansible_module, fake_xenapi_ref("task"))
|
||||
|
||||
mocked_xenapi.task.destroy.assert_called_once()
|
||||
assert fake_result == result
|
||||
|
|
|
|||
|
|
@ -63,24 +63,34 @@ testcase_module_remote_conn_scheme = {
|
|||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fake_ansible_module', testcase_module_local_conn['params'], ids=testcase_module_local_conn['ids'], indirect=True) # type: ignore
|
||||
@pytest.mark.parametrize(
|
||||
"fake_ansible_module",
|
||||
testcase_module_local_conn["params"], # type: ignore
|
||||
ids=testcase_module_local_conn["ids"], # type: ignore
|
||||
indirect=True,
|
||||
)
|
||||
def test_xapi_connect_local_session(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests that connection to localhost uses XenAPI.xapi_local() function."""
|
||||
mocker.patch('XenAPI.xapi_local')
|
||||
mocker.patch("XenAPI.xapi_local")
|
||||
|
||||
xapi_session = xenserver.XAPI.connect(fake_ansible_module)
|
||||
|
||||
XenAPI.xapi_local.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fake_ansible_module', testcase_module_local_conn['params'], ids=testcase_module_local_conn['ids'], indirect=True) # type: ignore
|
||||
@pytest.mark.parametrize(
|
||||
"fake_ansible_module",
|
||||
testcase_module_local_conn["params"], # type: ignore
|
||||
ids=testcase_module_local_conn["ids"], # type: ignore
|
||||
indirect=True,
|
||||
)
|
||||
def test_xapi_connect_local_login(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests that connection to localhost uses empty username and password."""
|
||||
mocker.patch.object(XenAPI.Session, 'login_with_password', create=True)
|
||||
mocker.patch.object(XenAPI.Session, "login_with_password", create=True)
|
||||
|
||||
xapi_session = xenserver.XAPI.connect(fake_ansible_module)
|
||||
|
||||
XenAPI.Session.login_with_password.assert_called_once_with('', '', ANSIBLE_VERSION, 'Ansible')
|
||||
XenAPI.Session.login_with_password.assert_called_once_with("", "", ANSIBLE_VERSION, "Ansible")
|
||||
|
||||
|
||||
def test_xapi_connect_login(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
|
|
@ -88,80 +98,88 @@ def test_xapi_connect_login(mocker, fake_ansible_module, XenAPI, xenserver):
|
|||
Tests that username and password are properly propagated to
|
||||
XenAPI.Session.login_with_password() function.
|
||||
"""
|
||||
mocker.patch.object(XenAPI.Session, 'login_with_password', create=True)
|
||||
mocker.patch.object(XenAPI.Session, "login_with_password", create=True)
|
||||
|
||||
xapi_session = xenserver.XAPI.connect(fake_ansible_module)
|
||||
|
||||
username = fake_ansible_module.params['username']
|
||||
password = fake_ansible_module.params['password']
|
||||
username = fake_ansible_module.params["username"]
|
||||
password = fake_ansible_module.params["password"]
|
||||
|
||||
XenAPI.Session.login_with_password.assert_called_once_with(username, password, ANSIBLE_VERSION, 'Ansible')
|
||||
XenAPI.Session.login_with_password.assert_called_once_with(username, password, ANSIBLE_VERSION, "Ansible")
|
||||
|
||||
|
||||
def test_xapi_connect_login_failure(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests that login failure is properly handled."""
|
||||
fake_error_msg = "Fake XAPI login error!"
|
||||
|
||||
mocked_login = mocker.patch.object(XenAPI.Session, 'login_with_password', create=True)
|
||||
mocked_login = mocker.patch.object(XenAPI.Session, "login_with_password", create=True)
|
||||
mocked_login.side_effect = XenAPI.Failure(fake_error_msg)
|
||||
|
||||
hostname = fake_ansible_module.params['hostname']
|
||||
username = fake_ansible_module.params['username']
|
||||
hostname = fake_ansible_module.params["hostname"]
|
||||
username = fake_ansible_module.params["username"]
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xapi_session = xenserver.XAPI.connect(fake_ansible_module)
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == f"Unable to log on to XenServer at http://{hostname} as {username}: {fake_error_msg}"
|
||||
assert (
|
||||
exc_info.value.kwargs["msg"]
|
||||
== f"Unable to log on to XenServer at http://{hostname} as {username}: {fake_error_msg}"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'fake_ansible_module',
|
||||
testcase_module_remote_conn_scheme['params'], # type: ignore
|
||||
ids=testcase_module_remote_conn_scheme['ids'], # type: ignore
|
||||
"fake_ansible_module",
|
||||
testcase_module_remote_conn_scheme["params"], # type: ignore
|
||||
ids=testcase_module_remote_conn_scheme["ids"], # type: ignore
|
||||
indirect=True,
|
||||
)
|
||||
def test_xapi_connect_remote_scheme(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests that explicit scheme in hostname param is preserved."""
|
||||
mocker.patch('XenAPI.Session')
|
||||
mocker.patch("XenAPI.Session")
|
||||
|
||||
xapi_session = xenserver.XAPI.connect(fake_ansible_module)
|
||||
|
||||
hostname = fake_ansible_module.params['hostname']
|
||||
ignore_ssl = not fake_ansible_module.params['validate_certs']
|
||||
hostname = fake_ansible_module.params["hostname"]
|
||||
ignore_ssl = not fake_ansible_module.params["validate_certs"]
|
||||
|
||||
XenAPI.Session.assert_called_once_with(hostname, ignore_ssl=ignore_ssl)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fake_ansible_module', testcase_module_remote_conn['params'], ids=testcase_module_remote_conn['ids'], indirect=True) # type: ignore
|
||||
@pytest.mark.parametrize(
|
||||
"fake_ansible_module",
|
||||
testcase_module_remote_conn["params"], # type: ignore
|
||||
ids=testcase_module_remote_conn["ids"], # type: ignore
|
||||
indirect=True,
|
||||
)
|
||||
def test_xapi_connect_remote_no_scheme(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests that proper scheme is prepended to hostname without scheme."""
|
||||
mocker.patch('XenAPI.Session')
|
||||
mocker.patch("XenAPI.Session")
|
||||
|
||||
xapi_session = xenserver.XAPI.connect(fake_ansible_module)
|
||||
|
||||
hostname = fake_ansible_module.params['hostname']
|
||||
ignore_ssl = not fake_ansible_module.params['validate_certs']
|
||||
hostname = fake_ansible_module.params["hostname"]
|
||||
ignore_ssl = not fake_ansible_module.params["validate_certs"]
|
||||
|
||||
XenAPI.Session.assert_called_once_with(f"http://{hostname}", ignore_ssl=ignore_ssl)
|
||||
|
||||
|
||||
def test_xapi_connect_support_ignore_ssl(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests proper handling of ignore_ssl support."""
|
||||
mocked_session = mocker.patch('XenAPI.Session')
|
||||
mocked_session = mocker.patch("XenAPI.Session")
|
||||
mocked_session.side_effect = TypeError()
|
||||
|
||||
with pytest.raises(TypeError) as exc_info:
|
||||
xapi_session = xenserver.XAPI.connect(fake_ansible_module)
|
||||
|
||||
hostname = fake_ansible_module.params['hostname']
|
||||
ignore_ssl = not fake_ansible_module.params['validate_certs']
|
||||
hostname = fake_ansible_module.params["hostname"]
|
||||
ignore_ssl = not fake_ansible_module.params["validate_certs"]
|
||||
|
||||
XenAPI.Session.assert_called_with(f"http://{hostname}")
|
||||
|
||||
|
||||
def test_xapi_connect_no_disconnect_atexit(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests skipping registration of atexit disconnect handler."""
|
||||
mocker.patch('atexit.register')
|
||||
mocker.patch("atexit.register")
|
||||
|
||||
xapi_session = xenserver.XAPI.connect(fake_ansible_module, disconnect_atexit=False)
|
||||
|
||||
|
|
@ -170,7 +188,7 @@ def test_xapi_connect_no_disconnect_atexit(mocker, fake_ansible_module, XenAPI,
|
|||
|
||||
def test_xapi_connect_singleton(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests if XAPI.connect() returns singleton."""
|
||||
mocker.patch('XenAPI.Session')
|
||||
mocker.patch("XenAPI.Session")
|
||||
|
||||
xapi_session1 = xenserver.XAPI.connect(fake_ansible_module)
|
||||
xapi_session2 = xenserver.XAPI.connect(fake_ansible_module)
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ from .common import fake_xenapi_ref
|
|||
|
||||
def test_xenserverobject_xenapi_lib_detection(mocker, fake_ansible_module, xenserver):
|
||||
"""Tests XenAPI lib detection code."""
|
||||
mocker.patch('ansible_collections.community.general.plugins.module_utils.xenserver.HAS_XENAPI', new=False)
|
||||
mocker.patch("ansible_collections.community.general.plugins.module_utils.xenserver.HAS_XENAPI", new=False)
|
||||
|
||||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.XenServerObject(fake_ansible_module)
|
||||
|
||||
assert 'Failed to import the required Python library (XenAPI) on' in exc_info.value.kwargs['msg']
|
||||
assert "Failed to import the required Python library (XenAPI) on" in exc_info.value.kwargs["msg"]
|
||||
|
||||
|
||||
def test_xenserverobject_xenapi_failure(mock_xenapi_failure, fake_ansible_module, xenserver):
|
||||
|
|
@ -27,17 +27,17 @@ def test_xenserverobject_xenapi_failure(mock_xenapi_failure, fake_ansible_module
|
|||
with pytest.raises(FailJsonException) as exc_info:
|
||||
xenserver.XenServerObject(fake_ansible_module)
|
||||
|
||||
assert exc_info.value.kwargs['msg'] == f"XAPI ERROR: {mock_xenapi_failure[1]}"
|
||||
assert exc_info.value.kwargs["msg"] == f"XAPI ERROR: {mock_xenapi_failure[1]}"
|
||||
|
||||
|
||||
def test_xenserverobject(mocker, fake_ansible_module, XenAPI, xenserver):
|
||||
"""Tests successful creation of XenServerObject."""
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', create=True)
|
||||
mocked_xenapi = mocker.patch.object(XenAPI.Session, "xenapi", create=True)
|
||||
|
||||
mocked_returns = {
|
||||
"pool.get_all.return_value": [fake_xenapi_ref('pool')],
|
||||
"pool.get_default_SR.return_value": fake_xenapi_ref('SR'),
|
||||
"session.get_this_host.return_value": fake_xenapi_ref('host'),
|
||||
"pool.get_all.return_value": [fake_xenapi_ref("pool")],
|
||||
"pool.get_default_SR.return_value": fake_xenapi_ref("SR"),
|
||||
"session.get_this_host.return_value": fake_xenapi_ref("host"),
|
||||
"host.get_software_version.return_value": {"product_version": "7.2.0"},
|
||||
}
|
||||
|
||||
|
|
@ -45,5 +45,5 @@ def test_xenserverobject(mocker, fake_ansible_module, XenAPI, xenserver):
|
|||
|
||||
xso = xenserver.XenServerObject(fake_ansible_module)
|
||||
|
||||
assert xso.pool_ref == fake_xenapi_ref('pool')
|
||||
assert xso.pool_ref == fake_xenapi_ref("pool")
|
||||
assert xso.xenserver_version == [7, 2, 0]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue