[cloud][tests] AWS lambda module unit tests (#21768)
First pass at unit tests; demonstrates no update when only one parameter changed bug that was fixed in 22701806
.
This commit is contained in:
parent
88f67747cc
commit
34d9415d6d
2 changed files with 235 additions and 0 deletions
BIN
test/units/modules/cloud/amazon/fixtures/thezip.zip
Normal file
BIN
test/units/modules/cloud/amazon/fixtures/thezip.zip
Normal file
Binary file not shown.
235
test/units/modules/cloud/amazon/test_lambda.py
Normal file
235
test/units/modules/cloud/amazon/test_lambda.py
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
#
|
||||||
|
# (c) 2016 Michael De La Rue
|
||||||
|
#
|
||||||
|
# This file is part of Ansible
|
||||||
|
#
|
||||||
|
# Ansible is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ansible is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
|
||||||
|
from nose.plugins.skip import SkipTest
|
||||||
|
import pytest
|
||||||
|
import json
|
||||||
|
import copy
|
||||||
|
from ansible.module_utils._text import to_bytes
|
||||||
|
from ansible.module_utils import basic
|
||||||
|
from ansible.compat.tests.mock import MagicMock, Mock, patch
|
||||||
|
from ansible.module_utils.ec2 import HAS_BOTO3
|
||||||
|
if not HAS_BOTO3:
|
||||||
|
raise SkipTest("test_ec2_asg.py requires the `boto3`, and `botocore` modules")
|
||||||
|
|
||||||
|
# lambda is a keyword so we have to hack this.
|
||||||
|
_temp = __import__("ansible.modules.cloud.amazon.lambda")
|
||||||
|
|
||||||
|
lda = getattr(_temp.modules.cloud.amazon,"lambda")
|
||||||
|
|
||||||
|
exit_return_dict={}
|
||||||
|
|
||||||
|
def set_module_args(args):
|
||||||
|
args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
|
||||||
|
basic._ANSIBLE_ARGS = to_bytes(args)
|
||||||
|
|
||||||
|
base_start_function_config_in_aws={
|
||||||
|
'FunctionName' : 'lambda_name',
|
||||||
|
'Role' : 'arn:aws:iam::987654321012:role/lambda_basic_execution',
|
||||||
|
'Handler' : 'lambda_python.my_handler',
|
||||||
|
'Description' : 'this that the other',
|
||||||
|
'Timeout' : 3,
|
||||||
|
'MemorySize' : 128,
|
||||||
|
'Runtime' : 'python2.7',
|
||||||
|
'CodeSha256' : 'AqMZ+xptM7aC9VXu+5jyp1sqO+Nj4WFMNzQxtPMP2n8=',
|
||||||
|
}
|
||||||
|
|
||||||
|
one_change_start_function_config_in_aws=copy.copy(base_start_function_config_in_aws)
|
||||||
|
one_change_start_function_config_in_aws['Timeout']=4
|
||||||
|
two_change_start_function_config_in_aws=copy.copy(one_change_start_function_config_in_aws)
|
||||||
|
two_change_start_function_config_in_aws['Role']='arn:aws:iam::987654321012:role/lambda_advanced_execution'
|
||||||
|
code_change_start_function_config_in_aws=copy.copy(base_start_function_config_in_aws)
|
||||||
|
code_change_start_function_config_in_aws['CodeSha256']='P+Zy8U4T4RiiHWElhL10VBKj9jw4rSJ5bm/TiW+4Rts='
|
||||||
|
|
||||||
|
base_module_args={
|
||||||
|
"region": "us-west-1",
|
||||||
|
"name": "lambda_name",
|
||||||
|
"state": "present",
|
||||||
|
"zip_file": "test/units/modules/cloud/amazon/fixtures/thezip.zip",
|
||||||
|
"runtime": 'python2.7',
|
||||||
|
"role": 'arn:aws:iam::987654321012:role/lambda_basic_execution',
|
||||||
|
"memory_size": 128,
|
||||||
|
"timeout" : 3,
|
||||||
|
"handler": 'lambda_python.my_handler'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#TODO: def test_handle_different_types_in_config_params(monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_lambda_if_code_changed(monkeypatch):
|
||||||
|
|
||||||
|
fake_lambda_connection = MagicMock()
|
||||||
|
fake_lambda_connection.get_function.configure_mock(
|
||||||
|
return_value={
|
||||||
|
'Configuration' : code_change_start_function_config_in_aws
|
||||||
|
}
|
||||||
|
)
|
||||||
|
fake_lambda_connection.update_function_configuration.configure_mock(
|
||||||
|
return_value={
|
||||||
|
'Version' : 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
fake_boto3_conn=Mock(return_value=fake_lambda_connection)
|
||||||
|
|
||||||
|
set_module_args(base_module_args)
|
||||||
|
@patch("ansible.modules.cloud.amazon.lambda.boto3_conn", fake_boto3_conn)
|
||||||
|
def call_module():
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
lda.main()
|
||||||
|
|
||||||
|
call_module()
|
||||||
|
|
||||||
|
# guard against calling other than for a lambda connection (e.g. IAM)
|
||||||
|
assert(len(fake_boto3_conn.mock_calls) == 1), "multiple boto connections used unexpectedly"
|
||||||
|
assert(len(fake_lambda_connection.update_function_configuration.mock_calls) == 0), \
|
||||||
|
"unexpectedly updatede lambda configuration when only code changed"
|
||||||
|
assert(len(fake_lambda_connection.update_function_configuration.mock_calls) < 2), \
|
||||||
|
"lambda function update called multiple times when only one time should be needed"
|
||||||
|
assert(len(fake_lambda_connection.update_function_code.mock_calls) > 1), \
|
||||||
|
"failed to update lambda function when code changed"
|
||||||
|
# 3 because after uploading we call into the return from mock to try to find what function version
|
||||||
|
# was returned so the MagicMock actually sees two calls for one update.
|
||||||
|
assert(len(fake_lambda_connection.update_function_code.mock_calls) < 3), \
|
||||||
|
"lambda function code update called multiple times when only one time should be needed"
|
||||||
|
|
||||||
|
def test_update_lambda_if_config_changed(monkeypatch):
|
||||||
|
|
||||||
|
fake_lambda_connection = MagicMock()
|
||||||
|
fake_lambda_connection.get_function.configure_mock(
|
||||||
|
return_value={
|
||||||
|
'Configuration' : two_change_start_function_config_in_aws
|
||||||
|
}
|
||||||
|
)
|
||||||
|
fake_lambda_connection.update_function_configuration.configure_mock(
|
||||||
|
return_value={
|
||||||
|
'Version' : 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
fake_boto3_conn=Mock(return_value=fake_lambda_connection)
|
||||||
|
|
||||||
|
set_module_args(base_module_args)
|
||||||
|
@patch("ansible.modules.cloud.amazon.lambda.boto3_conn", fake_boto3_conn)
|
||||||
|
def call_module():
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
lda.main()
|
||||||
|
|
||||||
|
call_module()
|
||||||
|
|
||||||
|
# guard against calling other than for a lambda connection (e.g. IAM)
|
||||||
|
assert(len(fake_boto3_conn.mock_calls) == 1), "multiple boto connections used unexpectedly"
|
||||||
|
assert(len(fake_lambda_connection.update_function_configuration.mock_calls) > 0), \
|
||||||
|
"failed to update lambda function when configuration changed"
|
||||||
|
assert(len(fake_lambda_connection.update_function_configuration.mock_calls) < 2), \
|
||||||
|
"lambda function update called multiple times when only one time should be needed"
|
||||||
|
assert(len(fake_lambda_connection.update_function_code.mock_calls) == 0), \
|
||||||
|
"updated lambda code when no change should have happened"
|
||||||
|
|
||||||
|
def test_update_lambda_if_only_one_config_item_changed(monkeypatch):
|
||||||
|
|
||||||
|
fake_lambda_connection = MagicMock()
|
||||||
|
fake_lambda_connection.get_function.configure_mock(
|
||||||
|
return_value={
|
||||||
|
'Configuration' : one_change_start_function_config_in_aws
|
||||||
|
}
|
||||||
|
)
|
||||||
|
fake_lambda_connection.update_function_configuration.configure_mock(
|
||||||
|
return_value={
|
||||||
|
'Version' : 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
fake_boto3_conn=Mock(return_value=fake_lambda_connection)
|
||||||
|
|
||||||
|
@patch("ansible.modules.cloud.amazon.lambda.boto3_conn", fake_boto3_conn)
|
||||||
|
def call_module():
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
lda.main()
|
||||||
|
|
||||||
|
call_module()
|
||||||
|
|
||||||
|
# guard against calling other than for a lambda connection (e.g. IAM)
|
||||||
|
assert(len(fake_boto3_conn.mock_calls) == 1), "multiple boto connections used unexpectedly"
|
||||||
|
assert(len(fake_lambda_connection.update_function_configuration.mock_calls) > 0), \
|
||||||
|
"failed to update lambda function when configuration changed"
|
||||||
|
assert(len(fake_lambda_connection.update_function_configuration.mock_calls) < 2), \
|
||||||
|
"lambda function update called multiple times when only one time should be needed"
|
||||||
|
assert(len(fake_lambda_connection.update_function_code.mock_calls) == 0), \
|
||||||
|
"updated lambda code when no change should have happened"
|
||||||
|
|
||||||
|
def test_dont_update_lambda_if_nothing_changed(monkeypatch):
|
||||||
|
|
||||||
|
fake_lambda_connection = MagicMock()
|
||||||
|
fake_lambda_connection.get_function.configure_mock(
|
||||||
|
return_value={
|
||||||
|
'Configuration' : base_start_function_config_in_aws
|
||||||
|
}
|
||||||
|
)
|
||||||
|
fake_lambda_connection.update_function_configuration.configure_mock(
|
||||||
|
return_value={
|
||||||
|
'Version' : 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
fake_boto3_conn=Mock(return_value=fake_lambda_connection)
|
||||||
|
|
||||||
|
@patch("ansible.modules.cloud.amazon.lambda.boto3_conn", fake_boto3_conn)
|
||||||
|
def call_module():
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
lda.main()
|
||||||
|
|
||||||
|
call_module()
|
||||||
|
|
||||||
|
# guard against calling other than for a lambda connection (e.g. IAM)
|
||||||
|
assert(len(fake_boto3_conn.mock_calls) == 1), "multiple boto connections used unexpectedly"
|
||||||
|
assert(len(fake_lambda_connection.update_function_configuration.mock_calls) == 0), \
|
||||||
|
"updated lambda function when no configuration changed"
|
||||||
|
assert(len(fake_lambda_connection.update_function_code.mock_calls) == 0 ), \
|
||||||
|
"updated lambda code when no change should have happened"
|
||||||
|
|
||||||
|
def test_warn_region_not_specified():
|
||||||
|
|
||||||
|
set_module_args({
|
||||||
|
"name": "lambda_name",
|
||||||
|
"state": "present",
|
||||||
|
# Module is called without a region causing error
|
||||||
|
# "region": "us-east-1",
|
||||||
|
"zip_file": "test/units/modules/cloud/amazon/fixtures/thezip.zip",
|
||||||
|
"runtime": 'python2.7',
|
||||||
|
"role": 'arn:aws:iam::987654321012:role/lambda_basic_execution',
|
||||||
|
"handler": 'lambda_python.my_handler'})
|
||||||
|
|
||||||
|
class AnsibleFailJson(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def fail_json(*args, **kwargs):
|
||||||
|
kwargs['failed'] = True
|
||||||
|
raise AnsibleFailJson(kwargs)
|
||||||
|
|
||||||
|
def call_module():
|
||||||
|
with patch.object(basic.AnsibleModule, 'fail_json', fail_json):
|
||||||
|
try:
|
||||||
|
lda.main()
|
||||||
|
except AnsibleFailJson as e:
|
||||||
|
result = e.args[0]
|
||||||
|
assert("region must be specified" in result['msg'])
|
||||||
|
|
||||||
|
call_module()
|
||||||
|
|
Loading…
Reference in a new issue