salt/tests/unit/states/boto_cognitoidentity_test.py
Erik Johnson 20ed2c6bcf Remove repr formatting flag in places where it is used solely for quoting (#34183)
* salt/cloud/__init__.py: remove repr formatting

* salt/cloud/clouds/azurearm.py: remove repr formatting

* salt/cloud/clouds/ec2.py: remove repr formatting

* salt/cloud/clouds/profitbricks.py: remove repr formatting

* salt/loader.py: remove repr formatting

* salt/modules/win_file.py: remove repr formatting

* salt/modules/zypper.py: remove repr formatting

* salt/pillar/consul_pillar.py: remove repr formatting

* salt/renderers/pyobjects.py: remove repr formatting

* salt/returners/sentry_return.py: remove repr formatting

* salt/states/bower.py: remove repr formatting

* salt/states/cabal.py: remove repr formatting

* salt/states/cmd.py: remove repr formatting

* salt/states/composer.py: remove repr formatting

* salt/states/win_network.py: remove repr formatting

* salt/states/eselect.py: remove repr formatting

* salt/states/file.py: remove repr formatting

* salt/states/htpasswd.py: remove repr formatting

* salt/states/memcached.py: remove repr formatting

* salt/states/npm.py: remove repr formatting

* salt/states/pip_state.py: remove repr formatting

* salt/states/pkg.py: remove repr formatting

* salt/states/pkgrepo.py: remove repr formatting

* salt/states/supervisord.py: remove repr formatting

* salt/states/timezone.py: remove repr formatting

* salt/states/virtualenv_mod.py: remove repr formatting

* salt/states/dockerio.py: remove repr formatting

* salt/states/win_system.py: remove repr formatting

* salt/utils/nb_popen.py: remove repr formatting

* salt/utils/cloud.py: remove repr formatting

* Add pylint disable due to legit usage of repr flag

See https://github.com/saltstack/salt-pylint/pull/6

* Fix composer tests

These tests needed to be updated because quoting was changed in the
state module in 9dc9146. There was an unnecessary !r used for the
exception class there, which means that instead of the exception class
being passed through the formatter and coming out with the equivalent
value of err.__str__(), we get a repr'ed instance of the exception class
(i.e.  SaltException('',)) in the state output.

The unit test was asserting that we have that repr'ed instance of
SaltException in the output, a case of writing the test to confirm the
badly-conceived output in the state. This has also been corrected.

* salt/cloud/clouds/azurearm.py: lint fixes

* salt/modules/boto_s3_bucket.py: lint fixes

* salt/modules/minion.py: lint fixes

* salt/modules/reg.py: lint fixes

* salt/modules/testinframod.py: lint fixes

* salt/modules/win_iis.py: lint fixes

* salt/pillar/csvpillar.py: lint fixes

* salt/utils/win_functions.py: lint fixes

* salt/states/nxos.py: lint fixes

* salt/returners/mongo_future_return.py: lint fixes

* tests/integration/__init__.py: lint fixes

* tests/unit/context_test.py: lint fixes

* tests/integration/states/file.py: lint fixes

* tests/integration/utils/test_reactor.py: lint fixes

* tests/integration/utils/testprogram.py: lint fixes

* tests/unit/__init__.py: lint fixes

* tests/integration/shell/minion.py: lint fixes

* tests/unit/modules/boto_apigateway_test.py: lint fixes

* tests/unit/modules/boto_cognitoidentity_test.py: lint fixes

* tests/unit/modules/boto_elasticsearch_domain_test.py: lint fixes

* tests/unit/modules/k8s_test.py: lint fixes

* tests/unit/modules/reg_win_test.py: lint fixes

* tests/unit/states/boto_apigateway_test.py: lint fixes

* tests/unit/states/boto_cognitoidentity_test.py: lint fixes

* tests/unit/states/boto_elasticsearch_domain_test.py: lint fixes
2016-06-29 16:30:18 -04:00

453 lines
22 KiB
Python

# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import
from distutils.version import LooseVersion # pylint: disable=import-error,no-name-in-module
import random
import string
# Import Salt Testing libs
from salttesting.unit import skipIf, TestCase
from salttesting.mock import NO_MOCK, NO_MOCK_REASON, patch
from salttesting.helpers import ensure_in_syspath
ensure_in_syspath('../../')
# Import Salt libs
import salt.config
import salt.loader
# Import 3rd-party libs
import logging
# Import Mock libraries
from salttesting.mock import NO_MOCK, NO_MOCK_REASON, MagicMock, patch
# pylint: disable=import-error,no-name-in-module
from unit.modules.boto_cognitoidentity_test import BotoCognitoIdentityTestCaseMixin
# Import 3rd-party libs
try:
import boto3
from botocore.exceptions import ClientError
HAS_BOTO = True
except ImportError:
HAS_BOTO = False
from salt.ext.six.moves import range
# pylint: enable=import-error,no-name-in-module
# the boto_cognitoidentity module relies on the connect_to_region() method
# which was added in boto 2.8.0
# https://github.com/boto/boto/commit/33ac26b416fbb48a60602542b4ce15dcc7029f12
required_boto3_version = '1.2.1'
region = 'us-east-1'
access_key = 'GKTADJGHEIQSXMKKRBJ08H'
secret_key = 'askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs'
conn_parameters = {'region': region, 'key': access_key, 'keyid': secret_key, 'profile': {}}
error_message = 'An error occurred (101) when calling the {0} operation: Test-defined error'
error_content = {
'Error': {
'Code': 101,
'Message': "Test-defined error"
}
}
first_pool_id = 'first_pool_id'
first_pool_name = 'first_pool'
second_pool_id = 'second_pool_id'
second_pool_name = 'second_pool'
second_pool_name_updated = 'second_pool_updated'
third_pool_id = 'third_pool_id'
third_pool_name = first_pool_name
default_pool_name = 'default_pool_name'
default_pool_id = 'default_pool_id'
default_dev_provider = 'test_provider_default'
identity_pools_ret = dict(IdentityPools=[dict(IdentityPoolId=first_pool_id,
IdentityPoolName=first_pool_name),
dict(IdentityPoolId=second_pool_id,
IdentityPoolName=second_pool_name),
dict(IdentityPoolId=third_pool_id,
IdentityPoolName=third_pool_name)])
first_pool_ret = dict(IdentityPoolId=first_pool_id,
IdentityPoolName=first_pool_name,
AllowUnauthenticatedIdentities=False,
SupportedLoginProviders={'accounts.google.com': 'testing123',
'api.twitter.com': 'testing123',
'graph.facebook.com': 'testing123',
'www.amazon.com': 'testing123'},
DeveloperProviderName='test_provider',
OpenIdConnectProviderARNs=['some_provider_arn',
'another_provider_arn'])
first_pool_role_ret = dict(IdentityPoolId=first_pool_id,
Roles=dict(authenticated='first_pool_auth_role',
unauthenticated='first_pool_unauth_role'))
second_pool_ret = dict(IdentityPoolId=second_pool_id,
IdentityPoolName=second_pool_name,
AllowUnauthenticatedIdentities=False)
second_pool_role_ret = dict(IdentityPoolId=second_pool_id,
Roles=dict(authenticated='second_pool_auth_role'))
second_pool_update_ret = dict(IdentityPoolId=second_pool_id,
IdentityPoolName=second_pool_name,
AllowUnauthenticatedIdentities=True)
third_pool_ret = dict(IdentityPoolId=third_pool_id,
IdentityPoolName=third_pool_name,
AllowUnauthenticatedIdentities=False,
DeveloperProviderName='test_provider2')
third_pool_role_ret = dict(IdentityPoolId=third_pool_id)
default_pool_ret = dict(IdentityPoolId=default_pool_id,
IdentityPoolName=default_pool_name,
AllowUnauthenticatedIdentities=False,
DeveloperProviderName=default_dev_provider)
default_pool_role_ret = dict(IdentityPoolId=default_pool_id)
log = logging.getLogger(__name__)
opts = salt.config.DEFAULT_MINION_OPTS
context = {}
utils = salt.loader.utils(opts, whitelist=['boto3'], context=context)
serializers = salt.loader.serializers(opts)
funcs = salt.loader.minion_mods(opts, context=context, utils=utils, whitelist=['boto_cognitoidentity'])
salt_states = salt.loader.states(opts=opts, functions=funcs, utils=utils, whitelist=['boto_cognitoidentity'], serializers=serializers)
def _has_required_boto():
'''
Returns True/False boolean depending on if Boto is installed and correct
version.
'''
if not HAS_BOTO:
return False
elif LooseVersion(boto3.__version__) < LooseVersion(required_boto3_version):
return False
else:
return True
class BotoCognitoIdentityStateTestCaseBase(TestCase):
conn = None
# Set up MagicMock to replace the boto3 session
def setUp(self):
context.clear()
# connections keep getting cached from prior tests, can't find the
# correct context object to clear it. So randomize the cache key, to prevent any
# cache hits
conn_parameters['key'] = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(50))
self.patcher = patch('boto3.session.Session')
self.addCleanup(self.patcher.stop)
mock_session = self.patcher.start()
session_instance = mock_session.return_value
self.conn = MagicMock()
session_instance.client.return_value = self.conn
@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
' or equal to version {0}'
.format(required_boto3_version))
@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoCognitoIdentityTestCase(BotoCognitoIdentityStateTestCaseBase, BotoCognitoIdentityTestCaseMixin):
'''
TestCase for salt.states.boto_cognitoidentity state.module
'''
def _describe_identity_pool_side_effect(self, *args, **kwargs):
if kwargs.get('IdentityPoolId') == first_pool_id:
return first_pool_ret
elif kwargs.get('IdentityPoolId') == second_pool_id:
return second_pool_ret
elif kwargs.get('IdentityPoolId') == third_pool_id:
return third_pool_ret
else:
return default_pool_ret
def test_present_when_failing_to_describe_identity_pools(self):
'''
Tests exceptions when describing identity pools
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = ClientError(error_content, 'error on describe identity pool')
result = salt_states['boto_cognitoidentity.pool_present'](
name='test pool present',
IdentityPoolName=first_pool_name,
AuthenticatedRole='my_auth_role',
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertTrue('error on describe identity pool' in result.get('comment', {}))
def test_present_when_multiple_pools_with_same_name_exist(self):
'''
Tests present on an identity pool name where it matched
multiple pools. The result should fail.
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
result = salt_states['boto_cognitoidentity.pool_present'](
name='test pool present',
IdentityPoolName=first_pool_name,
AuthenticatedRole='my_auth_role',
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertIn('{0}'.format([first_pool_ret, third_pool_ret]), result.get('comment', ''))
def test_present_when_failing_to_create_a_new_identity_pool(self):
'''
Tests present on an identity pool name that doesn't exist and
an error is thrown on creation.
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
self.conn.create_identity_pool.side_effect = ClientError(error_content, 'error on create_identity_pool')
result = salt_states['boto_cognitoidentity.pool_present'](
name='test pool present',
IdentityPoolName=default_pool_name,
AuthenticatedRole='my_auth_role',
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertTrue('error on create_identity_pool' in result.get('comment', ''))
self.conn.update_identity_pool.assert_not_called()
def test_present_when_failing_to_update_an_existing_identity_pool(self):
'''
Tests present on a unique instance of identity pool having the matching
IdentityPoolName, and an error is thrown on updating the pool properties.
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
self.conn.update_identity_pool.side_effect = ClientError(error_content, 'error on update_identity_pool')
result = salt_states['boto_cognitoidentity.pool_present'](
name='test pool present',
IdentityPoolName=second_pool_name,
AuthenticatedRole='my_auth_role',
AllowUnauthenticatedIdentities=True,
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertTrue('error on update_identity_pool' in result.get('comment', ''))
self.conn.create_identity_pool.assert_not_called()
def _get_identity_pool_roles_side_effect(self, *args, **kwargs):
if kwargs.get('IdentityPoolId') == first_pool_id:
return first_pool_role_ret
elif kwargs.get('IdentityPoolId') == second_pool_id:
return second_pool_role_ret
elif kwargs.get('IdentityPoolId') == third_pool_id:
return third_pool_role_ret
else:
return default_pool_role_ret
def test_present_when_failing_to_get_identity_pool_roles(self):
'''
Tests present on a unique instance of identity pool having the matching
IdentityPoolName, where update_identity_pool succeeded, but an error
is thrown on getting the identity pool role prior to setting the roles.
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
self.conn.update_identity_pool.return_value = second_pool_update_ret
self.conn.get_identity_pool_roles.side_effect = ClientError(error_content, 'error on get_identity_pool_roles')
result = salt_states['boto_cognitoidentity.pool_present'](
name='test pool present',
IdentityPoolName=second_pool_name,
AuthenticatedRole='my_auth_role',
AllowUnauthenticatedIdentities=True,
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertTrue('error on get_identity_pool_roles' in result.get('comment', ''))
self.conn.create_identity_pool.assert_not_called()
self.conn.set_identity_pool_roles.assert_not_called()
def test_present_when_failing_to_set_identity_pool_roles(self):
'''
Tests present on a unique instance of identity pool having the matching
IdentityPoolName, where update_identity_pool succeeded, but an error
is thrown on setting the identity pool role.
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
self.conn.update_identity_pool.return_value = second_pool_update_ret
self.conn.get_identity_pool_roles.return_value = second_pool_role_ret
self.conn.set_identity_pool_roles.side_effect = ClientError(error_content, 'error on set_identity_pool_roles')
with patch.dict(funcs, {'boto_iam.describe_role': MagicMock(return_value={'arn': 'my_auth_role_arn'})}):
result = salt_states['boto_cognitoidentity.pool_present'](
name='test pool present',
IdentityPoolName=second_pool_name,
AuthenticatedRole='my_auth_role',
AllowUnauthenticatedIdentities=True,
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertTrue('error on set_identity_pool_roles' in result.get('comment', ''))
expected_call_args = (dict(IdentityPoolId=second_pool_id,
Roles={'authenticated': 'my_auth_role_arn'}),)
self.assertTrue(self.conn.set_identity_pool_roles.call_args == expected_call_args)
def test_present_when_pool_name_does_not_exist(self):
'''
Tests the successful case of creating a new instance, and updating its
roles
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.create_identity_pool.side_effect = self._describe_identity_pool_side_effect
self.conn.get_identity_pool_roles.return_value = default_pool_role_ret
self.conn.set_identity_pool_roles.return_value = None
with patch.dict(funcs, {'boto_iam.describe_role': MagicMock(return_value={'arn': 'my_auth_role_arn'})}):
result = salt_states['boto_cognitoidentity.pool_present'](
name='test pool present',
IdentityPoolName=default_pool_name,
AuthenticatedRole='my_auth_role',
AllowUnauthenticatedIdentities=True,
DeveloperProviderName=default_dev_provider,
**conn_parameters)
self.assertEqual(result.get('result'), True)
expected_call_args = (dict(AllowUnauthenticatedIdentities=True,
IdentityPoolName=default_pool_name,
DeveloperProviderName=default_dev_provider,
SupportedLoginProviders={},
OpenIdConnectProviderARNs=[]),)
self.assertTrue(self.conn.create_identity_pool.call_args == expected_call_args)
expected_call_args = (dict(IdentityPoolId=default_pool_id,
Roles={'authenticated': 'my_auth_role_arn'}),)
self.assertTrue(self.conn.set_identity_pool_roles.call_args == expected_call_args)
self.conn.update_identity_pool.assert_not_called()
def test_present_when_pool_name_exists(self):
'''
Tests the successful case of updating a single instance with matching
IdentityPoolName and its roles.
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
self.conn.update_identity_pool.return_value = second_pool_update_ret
self.conn.get_identity_pool_roles.return_value = second_pool_role_ret
self.conn.set_identity_pool_roles.return_value = None
with patch.dict(funcs, {'boto_iam.describe_role': MagicMock(return_value={'arn': 'my_auth_role_arn'})}):
result = salt_states['boto_cognitoidentity.pool_present'](
name='test pool present',
IdentityPoolName=second_pool_name,
AuthenticatedRole='my_auth_role',
AllowUnauthenticatedIdentities=True,
**conn_parameters)
self.assertEqual(result.get('result'), True)
expected_call_args = (dict(AllowUnauthenticatedIdentities=True,
IdentityPoolId=second_pool_id,
IdentityPoolName=second_pool_name),)
self.assertTrue(self.conn.update_identity_pool.call_args == expected_call_args)
expected_call_args = (dict(IdentityPoolId=second_pool_id,
Roles={'authenticated': 'my_auth_role_arn'}),)
self.assertTrue(self.conn.set_identity_pool_roles.call_args == expected_call_args)
self.conn.create_identity_pool.assert_not_called()
def test_absent_when_pool_does_not_exist(self):
'''
Tests absent on an identity pool that does not exist.
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
result = salt_states['boto_cognitoidentity.pool_absent'](
name='test pool absent',
IdentityPoolName='no_such_pool_name',
RemoveAllMatched=False,
**conn_parameters)
self.assertEqual(result.get('result'), True)
self.assertEqual(result['changes'], {})
def test_absent_when_removeallmatched_is_false_and_multiple_pools_matched(self):
'''
Tests absent on when RemoveAllMatched flag is false and there are multiple matches
for the given pool name
first_pool_name is matched to first and third pool with different id's
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
result = salt_states['boto_cognitoidentity.pool_absent'](
name='test pool absent',
IdentityPoolName=first_pool_name,
RemoveAllMatched=False,
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertEqual(result['changes'], {})
self.assertTrue('{0}'.format([first_pool_ret, third_pool_ret]) in result.get('comment', ''))
def test_absent_when_failing_to_describe_identity_pools(self):
'''
Tests exceptions when describing identity pools
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = ClientError(error_content, 'error on describe identity pool')
result = salt_states['boto_cognitoidentity.pool_absent'](
name='test pool absent',
IdentityPoolName=first_pool_name,
RemoveAllMatched=False,
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertTrue('error on describe identity pool' in result.get('comment', {}))
def test_absent_when_erroring_on_delete_identity_pool(self):
'''
Tests error due to delete_identity_pools
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
self.conn.delete_identity_pool.side_effect = ClientError(error_content, 'error on delete identity pool')
result = salt_states['boto_cognitoidentity.pool_absent'](
name='test pool absent',
IdentityPoolName=first_pool_name,
RemoveAllMatched=True,
**conn_parameters)
self.assertEqual(result.get('result'), False)
self.assertEqual(result['changes'], {})
self.assertTrue('error on delete identity pool' in result.get('comment', ''))
def test_absent_when_a_single_pool_exists(self):
'''
Tests absent succeeds on delete when a single pool matched and
RemoveAllMatched is False
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.return_value = second_pool_ret
self.conn.delete_identity_pool.return_value = None
result = salt_states['boto_cognitoidentity.pool_absent'](
name='test pool absent',
IdentityPoolName=second_pool_name,
RemoveAllMatched=False,
**conn_parameters)
self.assertEqual(result.get('result'), True)
expected_changes = {'new': {'Identity Pool Id {0}'.format(second_pool_id): None},
'old': {'Identity Pool Id {0}'.format(second_pool_id): second_pool_name}}
self.assertEqual(result['changes'], expected_changes)
def test_absent_when_multiple_pool_exists_and_removeallmatched_flag_is_true(self):
'''
Tests absent succeeds on delete when a multiple pools matched and
RemoveAllMatched is True
first_pool_name should match to first_pool_id and third_pool_id
'''
self.conn.list_identity_pools.return_value = identity_pools_ret
self.conn.describe_identity_pool.side_effect = self._describe_identity_pool_side_effect
self.conn.delete_identity_pool.return_value = None
result = salt_states['boto_cognitoidentity.pool_absent'](
name='test pool absent',
IdentityPoolName=first_pool_name,
RemoveAllMatched=True,
**conn_parameters)
self.assertEqual(result.get('result'), True)
expected_changes = {'new': {'Identity Pool Id {0}'.format(first_pool_id): None,
'Identity Pool Id {0}'.format(third_pool_id): None},
'old': {'Identity Pool Id {0}'.format(first_pool_id): first_pool_name,
'Identity Pool Id {0}'.format(third_pool_id): third_pool_name}}
self.assertEqual(result['changes'], expected_changes)