def test_create_function(make_stubber, make_unique_name, error_code): lambda_client = boto3.client('lambda') lambda_stubber = make_stubber(lambda_client) wrapper = LambdaWrapper(lambda_client, None) func_name = make_unique_name('func-') handler_name = make_unique_name('handler-') iam_role = unittest.mock.MagicMock(arn='arn:aws:iam:::role/test-role') test_package = 'test-package' func_arn = f'arn:aws:lambda:::function/{func_name}' lambda_stubber.stub_create_function(func_name, func_arn, iam_role.arn, handler_name, test_package, error_code=error_code) if error_code is None: lambda_stubber.stub_get_function(func_name, 'Active') if error_code is None: got_arn = wrapper.create_function(func_name, handler_name, iam_role, test_package) assert got_arn == func_arn else: with pytest.raises(ClientError) as exc_info: wrapper.create_function(func_name, handler_name, iam_role, test_package) assert exc_info.value.response['Error']['Code'] == error_code
def run_scenario(lambda_client, iam_resource, basic_file, calculator_file, lambda_name): """ Runs the scenario. :param lambda_client: A Boto3 Lambda client. :param iam_resource: A Boto3 IAM resource. :param basic_file: The name of the file that contains the basic Lambda handler. :param calculator_file: The name of the file that contains the calculator Lambda handler. :param lambda_name: The name to give resources created for the scenario, such as the IAM role and the Lambda function. """ logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') print('-' * 88) print("Welcome to the AWS Lambda getting started with functions demo.") print('-' * 88) wrapper = LambdaWrapper(lambda_client, iam_resource) print("Checking for IAM role for Lambda...") iam_role, should_wait = wrapper.create_iam_role_for_lambda(lambda_name) if should_wait: logger.info("Giving AWS time to create resources...") wait(10) print(f"Looking for function {lambda_name}...") function = wrapper.get_function(lambda_name) if function is None: print("Zipping the Python script into a deployment package...") deployment_package = wrapper.create_deployment_package( basic_file, f"{lambda_name}.py") print(f"...and creating the {lambda_name} Lambda function.") wrapper.create_function(lambda_name, f'{lambda_name}.lambda_handler', iam_role, deployment_package) else: print(f"Function {lambda_name} already exists.") print('-' * 88) print(f"Let's invoke {lambda_name}. This function increments a number.") action_params = { 'action': 'increment', 'number': q.ask("Give me a number to increment: ", q.is_int) } print(f"Invoking {lambda_name}...") response = wrapper.invoke_function(lambda_name, action_params) print(f"Incrementing {action_params['number']} resulted in " f"{json.load(response['Payload'])}") print('-' * 88) print(f"Let's update the function to an arithmetic calculator.") q.ask("Press Enter when you're ready.") print("Creating a new deployment package...") deployment_package = wrapper.create_deployment_package( calculator_file, f"{lambda_name}.py") print(f"...and updating the {lambda_name} Lambda function.") update_waiter = UpdateFunctionWaiter(lambda_client) wrapper.update_function_code(lambda_name, deployment_package) update_waiter.wait(lambda_name) print( f"This function uses an environment variable to control logging level." ) print(f"Let's set it to DEBUG to get the most logging.") wrapper.update_function_configuration( lambda_name, {'LOG_LEVEL': logging.getLevelName(logging.DEBUG)}) actions = ['plus', 'minus', 'times', 'divided-by'] want_invoke = True while want_invoke: print(f"Let's invoke {lambda_name}. You can invoke these actions:") for index, action in enumerate(actions): print(f"{index + 1}: {action}") action_params = {} action_index = q.ask( "Enter the number of the action you want to take: ", q.is_int, q.in_range(1, len(actions))) action_params['action'] = actions[action_index - 1] print(f"You've chosen to invoke 'x {action_params['action']} y'.") action_params['x'] = q.ask("Enter a value for x: ", q.is_int) action_params['y'] = q.ask("Enter a value for y: ", q.is_int) print(f"Invoking {lambda_name}...") response = wrapper.invoke_function(lambda_name, action_params, True) print( f"Calculating {action_params['x']} {action_params['action']} {action_params['y']} " f"resulted in {json.load(response['Payload'])}") q.ask("Press Enter to see the logs from the call.") print(base64.b64decode(response['LogResult']).decode()) want_invoke = q.ask("That was fun. Shall we do it again? (y/n) ", q.is_yesno) print('-' * 88) if q.ask("Do you want to list all of the functions in your account? (y/n) " ): wrapper.list_functions() print('-' * 88) if q.ask("Ready to delete the function and role? (y/n) ", q.is_yesno): for policy in iam_role.attached_policies.all(): policy.detach_role(RoleName=iam_role.name) iam_role.delete() print(f"Deleted role {lambda_name}.") wrapper.delete_function(lambda_name) print(f"Deleted function {lambda_name}.") print("\nThanks for watching!") print('-' * 88)