1
0
Fork 0
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:
Felix Fontein 2025-11-01 12:08:41 +01:00
parent 3f2213791a
commit 340ff8586d
1008 changed files with 61301 additions and 58309 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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))

View file

@ -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},
)

View file

@ -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"
)

View file

@ -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):

View file

@ -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(

View file

@ -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)

View file

@ -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",

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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():

View file

@ -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

View file

@ -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",
],
}

View file

@ -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):

View file

@ -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]
)

View 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

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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)

View file

@ -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]