def test_new_scope_config_is_separate_copy(): original = Config(chalice_stage='dev', function_name='foo') new_config = original.scope(chalice_stage='prod', function_name='bar') # The original should not have been mutated. assert original.chalice_stage == 'dev' assert original.function_name == 'foo' assert new_config.chalice_stage == 'prod' assert new_config.function_name == 'bar'
def test_single_role_generated_for_default_config(self, sample_app_lambda_only): # The sample_app has one lambda function. # We'll add a few more and verify they all share the same role. @sample_app_lambda_only.lambda_function() def second(event, context): pass @sample_app_lambda_only.lambda_function() def third(event, context): pass config = Config.create(chalice_app=sample_app_lambda_only, project_dir='.', autogen_policy=True, api_gateway_stage='api') template = self.generate_template(config, 'dev') roles = [resource for resource in template['Resources'].values() if resource['Type'] == 'AWS::IAM::Role'] assert len(roles) == 1 # The lambda functions should all reference this role. functions = [ resource for resource in template['Resources'].values() if resource['Type'] == 'AWS::Serverless::Function' ] role_names = [ function['Properties']['Role'] for function in functions ] assert role_names == [ {'Fn::GetAtt': ['DefaultRole', 'Arn']}, {'Fn::GetAtt': ['DefaultRole', 'Arn']}, {'Fn::GetAtt': ['DefaultRole', 'Arn']}, ]
def test_can_create_app_packager_with_no_autogen(): # We can't actually observe a change here, but we want # to make sure the function can handle this param being # False. config = Config.create(autogen_policy=False) packager = package.create_app_packager(config) assert isinstance(packager, package.AppPackager)
def test_validation_error_if_no_role_provided_when_manage_false(sample_app): # We're indicating that we should not be managing the # IAM role, but we're not giving a role ARN to use. # This is a validation error. config = Config.create(chalice_app=sample_app, manage_iam_role=False) with pytest.raises(ValueError): validate_configuration(config)
def test_tags_specified_does_not_override_chalice_tag(self): c = Config.create( chalice_stage='dev', app_name='myapp', tags={'aws-chalice': 'attempted-override'}) assert c.tags == { 'aws-chalice': 'version=%s:stage=dev:app=myapp' % chalice_version, }
def test_can_create_scope_obj_with_new_function(): disk_config = { 'lambda_timeout': 10, 'stages': { 'dev': { 'manage_iam_role': True, 'iam_role_arn': 'role-arn', 'autogen_policy': True, 'iam_policy_file': 'policy.json', 'environment_variables': {'env': 'stage'}, 'lambda_timeout': 1, 'lambda_memory_size': 1, 'tags': {'tag': 'stage'}, 'lambda_functions': { 'api_handler': { 'lambda_timeout': 30, }, 'myauth': { # We're purposefully using different # values for everything in the stage # level config to ensure we can pull # from function scoped config properly. 'manage_iam_role': True, 'iam_role_arn': 'auth-role-arn', 'autogen_policy': True, 'iam_policy_file': 'function.json', 'environment_variables': {'env': 'function'}, 'lambda_timeout': 2, 'lambda_memory_size': 2, 'tags': {'tag': 'function'}, } } } } } c = Config(chalice_stage='dev', config_from_disk=disk_config) new_config = c.scope(chalice_stage='dev', function_name='myauth') assert new_config.manage_iam_role assert new_config.iam_role_arn == 'auth-role-arn' assert new_config.autogen_policy assert new_config.iam_policy_file == 'function.json' assert new_config.environment_variables == {'env': 'function'} assert new_config.lambda_timeout == 2 assert new_config.lambda_memory_size == 2 assert new_config.tags['tag'] == 'function'
def new_project(project_name, profile): # type: (str, str) -> None if project_name is None: project_name = getting_started_prompt(click) if os.path.isdir(project_name): click.echo("Directory already exists: %s" % project_name, err=True) raise click.Abort() create_new_project_skeleton(project_name, profile) validate_python_version(Config.create())
def test_can_create_scope_new_stage_and_function(stage_name, function_name, expected): disk_config = { 'environment_variables': {'from': 'global'}, 'stages': { 'dev': { 'environment_variables': {'from': 'dev-stage'}, 'lambda_functions': { 'api_handler': { 'environment_variables': { 'from': 'dev-api-handler', } }, 'myauth': { 'environment_variables': { 'from': 'dev-myauth', } } } }, 'beta': { 'environment_variables': {'from': 'beta-stage'}, 'lambda_functions': { 'api_handler': { 'environment_variables': { 'from': 'beta-api-handler', } }, 'myauth': { 'environment_variables': { 'from': 'beta-myauth', } } } }, 'prod': { 'environment_variables': {'from': 'prod-stage'}, } } } c = Config(chalice_stage='dev', config_from_disk=disk_config) new_config = c.scope(chalice_stage=stage_name, function_name=function_name) assert new_config.environment_variables == {'from': expected}
def test_can_generate_rest_api(self, sample_app_with_auth): config = Config.create(chalice_app=sample_app_with_auth, project_dir='.', api_gateway_stage='api') template = self.generate_template(config, 'dev') resources = template['Resources'] # Lambda function should be created. assert resources['APIHandler']['Type'] == 'AWS::Serverless::Function' # Along with permission to invoke from API Gateway. assert resources['APIHandlerInvokePermission'] == { 'Type': 'AWS::Lambda::Permission', 'Properties': { 'Action': 'lambda:InvokeFunction', 'FunctionName': {'Ref': 'APIHandler'}, 'Principal': 'apigateway.amazonaws.com', 'SourceArn': { 'Fn::Sub': [ ('arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}' ':${RestAPIId}/*'), {'RestAPIId': {'Ref': 'RestAPI'}}]}}, } assert resources['RestAPI']['Type'] == 'AWS::Serverless::Api' # We should also create the auth lambda function. assert resources['Myauth']['Type'] == 'AWS::Serverless::Function' # Along with permission to invoke from API Gateway. assert resources['MyauthInvokePermission'] == { 'Type': 'AWS::Lambda::Permission', 'Properties': { 'Action': 'lambda:InvokeFunction', 'FunctionName': {'Fn::GetAtt': ['Myauth', 'Arn']}, 'Principal': 'apigateway.amazonaws.com', 'SourceArn': { 'Fn::Sub': [ ('arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}' ':${RestAPIId}/*'), {'RestAPIId': {'Ref': 'RestAPI'}}]}}, } # Also verify we add the expected outputs when using # a Rest API. assert template['Outputs'] == { 'APIHandlerArn': { 'Value': { 'Fn::GetAtt': ['APIHandler', 'Arn'] } }, 'APIHandlerName': {'Value': {'Ref': 'APIHandler'}}, 'EndpointURL': { 'Value': { 'Fn::Sub': ( 'https://${RestAPI}.execute-api.' '${AWS::Region}.amazonaws.com/api/' ) } }, 'RestAPIId': {'Value': {'Ref': 'RestAPI'}} }
def test_preconfigured_policy_proxies(): policy_gen = mock.Mock(spec=ApplicationPolicyHandler) config = Config.create(project_dir='project_dir', autogen_policy=False) generator = package.PreconfiguredPolicyGenerator( config, policy_gen=policy_gen) policy_gen.generate_policy_from_app_source.return_value = { 'policy': True} policy = generator.generate_policy_from_app_source() policy_gen.generate_policy_from_app_source.assert_called_with(config) assert policy == {'policy': True}
def test_will_create_outdir_if_needed(tmpdir): appdir = _create_app_structure(tmpdir) outdir = str(appdir.join('outdir')) config = Config.create(project_dir=str(appdir), chalice_app=sample_app()) p = package.create_app_packager(config) p.package_app(config, str(outdir)) contents = os.listdir(str(outdir)) assert 'deployment.zip' in contents assert 'sam.json' in contents
def test_will_create_outdir_if_needed(tmpdir): appdir = _create_app_structure(tmpdir) outdir = str(appdir.join('outdir')) default_params = {'autogen_policy': True} config = Config.create(project_dir=str(appdir), chalice_app=sample_app(), **default_params) p = package.create_app_packager(config) p.package_app(config, str(outdir), 'dev') contents = os.listdir(str(outdir)) assert 'deployment.zip' in contents assert 'sam.json' in contents
def test_validate_names_across_function_types(sample_app): @sample_app.lambda_function() def foo(event, context): pass @sample_app.schedule('rate(1 hour)', name='foo') def bar(event): pass config = Config.create(chalice_app=sample_app, manage_iam_role=False) with pytest.raises(ValueError): validate_unique_function_names(config)
def test_validate_names_using_name_kwarg(sample_app): @sample_app.authorizer(name='duplicate') def foo(auth_request): pass @sample_app.lambda_function(name='duplicate') def bar(event): pass config = Config.create(chalice_app=sample_app, manage_iam_role=False) with pytest.raises(ValueError): validate_unique_function_names(config)
def test_default_function_memory_size(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator( mock_swagger_generator, mock_policy_generator) mock_swagger_generator.generate_swagger.return_value = { 'swagger': 'document' } config = Config.create(chalice_app=sample_app, api_gateway_stage='dev') template = p.generate_sam_template(config) properties = template['Resources']['APIHandler']['Properties'] assert properties['MemorySize'] == 128
def test_timeout_added_to_function(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator( mock_swagger_generator, mock_policy_generator) mock_swagger_generator.generate_swagger.return_value = { 'swagger': 'document' } config = Config.create(chalice_app=sample_app, api_gateway_stage='dev', app_name='myapp', lambda_timeout=240) template = p.generate_sam_template(config) properties = template['Resources']['APIHandler']['Properties'] assert properties['Timeout'] == 240
def test_sam_injects_swagger_doc(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator(mock_swagger_generator, mock_policy_generator) mock_swagger_generator.generate_swagger.return_value = { 'swagger': 'document' } config = Config.create(chalice_app=sample_app, api_gateway_stage='dev') template = p.generate_sam_template(config) properties = template['Resources']['RestAPI']['Properties'] assert properties['DefinitionBody'] == {'swagger': 'document'}
def test_can_create_app_packager_with_no_autogen(tmpdir): appdir = _create_app_structure(tmpdir) outdir = tmpdir.mkdir('outdir') config = Config.create(project_dir=str(appdir), chalice_app=sample_app()) p = package.create_app_packager(config) p.package_app(config, str(outdir)) # We're not concerned with the contents of the files # (those are tested in the unit tests), we just want to make # sure they're written to disk and look (mostly) right. contents = os.listdir(str(outdir)) assert 'deployment.zip' in contents assert 'sam.json' in contents
def test_helpful_error_message_on_s3_event(self, sample_app): @sample_app.on_s3_event(bucket='foo') def handler(event): pass config = Config.create(chalice_app=sample_app, project_dir='.', api_gateway_stage='api') with pytest.raises(NotImplementedError) as excinfo: self.generate_template(config, 'dev') # Should mention the decorator name. assert '@app.on_s3_event' in str(excinfo.value) # Should mention you can use `chalice deploy`. assert 'chalice deploy' in str(excinfo.value)
def test_chalice_tag_added_to_function(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator( mock_swagger_generator, mock_policy_generator) mock_swagger_generator.generate_swagger.return_value = { 'swagger': 'document' } config = Config.create(chalice_app=sample_app, api_gateway_stage='dev', app_name='myapp') template = p.generate_sam_template(config) properties = template['Resources']['APIHandler']['Properties'] assert properties['Tags'] == { 'aws-chalice': 'version=%s:stage=dev:app=myapp' % chalice_version}
def test_sam_generates_sam_template_basic(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator(mock_swagger_generator, mock_policy_generator) config = Config.create(chalice_app=sample_app, api_gateway_stage='dev') template = p.generate_sam_template(config, 'code-uri') # Verify the basic structure is in place. The specific parts # are validated in other tests. assert template['AWSTemplateFormatVersion'] == '2010-09-09' assert template['Transform'] == 'AWS::Serverless-2016-10-31' assert 'Outputs' in template assert 'Resources' in template
def test_validate_unique_lambda_function_names(sample_app): @sample_app.lambda_function() def foo(event, context): pass # This will cause a validation error because # 'foo' is already registered as a lambda function. @sample_app.lambda_function(name='foo') def bar(event, context): pass config = Config.create(chalice_app=sample_app, manage_iam_role=False) with pytest.raises(ValueError): validate_unique_function_names(config)
def test_env_vars_set_in_local(runner, mock_cli_factory, monkeypatch): local_server = mock.Mock(spec=local.LocalDevServer) mock_cli_factory.create_local_server.return_value = local_server mock_cli_factory.create_config_obj.return_value = Config.create( project_dir='.', environment_variables={'foo': 'bar'}) actual_env = {} monkeypatch.setattr(os, 'environ', actual_env) with runner.isolated_filesystem(): cli.create_new_project_skeleton('testproject') os.chdir('testproject') _run_cli_command(runner, cli.local, [], cli_factory=mock_cli_factory) assert actual_env['foo'] == 'bar'
def test_can_lazy_load_chalice_app(): app = Chalice(app_name='foo') calls = [] def call_recorder(*args, **kwargs): calls.append((args, kwargs)) return app c = Config.create(chalice_app=call_recorder) # Accessing the property multiple times will only # invoke the call once. assert isinstance(c.chalice_app, Chalice) assert isinstance(c.chalice_app, Chalice) assert len(calls) == 1
def test_role_arn_added_to_function(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator( mock_swagger_generator, mock_policy_generator) mock_swagger_generator.generate_swagger.return_value = { 'swagger': 'document' } config = Config.create( chalice_app=sample_app, api_gateway_stage='dev', app_name='myapp', manage_iam_role=False, iam_role_arn='role-arn') template = p.generate_sam_template(config) properties = template['Resources']['APIHandler']['Properties'] assert properties['Role'] == 'role-arn' assert 'Policies' not in properties
def test_sam_injects_policy(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator(mock_swagger_generator, mock_policy_generator) mock_policy_generator.generate_policy_from_app_source.return_value = { 'iam': 'policy', } config = Config.create(chalice_app=sample_app, api_gateway_stage='dev') template = p.generate_sam_template(config) assert template['Resources']['APIHandler']['Properties']['Policies'] == [{ 'iam': 'policy', }] assert 'Role' not in template['Resources']['APIHandler']['Properties']
def test_maps_python_version(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator( mock_swagger_generator, mock_policy_generator) mock_swagger_generator.generate_swagger.return_value = { 'swagger': 'document' } config = Config.create( chalice_app=sample_app, api_gateway_stage='dev', ) template = p.generate_sam_template(config) expected = config.lambda_python_version actual = template['Resources']['APIHandler']['Properties']['Runtime'] assert actual == expected
def test_vpc_config_added_to_function(self, sample_app_lambda_only): config = Config.create(chalice_app=sample_app_lambda_only, project_dir='.', autogen_policy=True, api_gateway_stage='api', security_group_ids=['sg1', 'sg2'], subnet_ids=['sn1', 'sn2']) template = self.generate_template(config, 'dev') resources = template['Resources'].values() lambda_fns = [resource for resource in resources if resource['Type'] == 'AWS::Serverless::Function'] assert len(lambda_fns) == 1 vpc_config = lambda_fns[0]['Properties']['VpcConfig'] assert vpc_config['SubnetIds'] == ['sn1', 'sn2'] assert vpc_config['SecurityGroupIds'] == ['sg1', 'sg2']
def test_endpoint_url_reflects_apig_stage(sample_app, mock_swagger_generator, mock_policy_generator): p = package.SAMTemplateGenerator( mock_swagger_generator, mock_policy_generator) mock_swagger_generator.generate_swagger.return_value = { 'swagger': 'document' } config = Config.create( chalice_app=sample_app, api_gateway_stage='prod', ) template = p.generate_sam_template(config) endpoint_url = template['Outputs']['EndpointURL']['Value']['Fn::Sub'] assert endpoint_url == ( 'https://${RestAPI}.execute-api.${AWS::Region}.amazonaws.com/prod/')
def test_sam_generates_sam_template_basic(self, sample_app): config = Config.create(chalice_app=sample_app, project_dir='.', api_gateway_stage='api') template = self.generate_template(config, 'dev') # Verify the basic structure is in place. The specific parts # are validated in other tests. assert template['AWSTemplateFormatVersion'] == '2010-09-09' assert template['Transform'] == 'AWS::Serverless-2016-10-31' assert 'Outputs' in template assert 'Resources' in template assert list(sorted(template['Resources'])) == [ 'APIHandler', 'APIHandlerInvokePermission', # This casing on the ApiHandlerRole name is unfortunate, but the 3 # other resources in this list are hardcoded from the old deployer. 'ApiHandlerRole', 'RestAPI', ]
def test_env_vars_chain_merge(): config_from_disk = { 'environment_variables': { 'top_level': 'foo', 'shared_key': 'from-top', }, 'stages': { 'prod': { 'environment_variables': { 'stage_var': 'bar', 'shared_key': 'from-stage', } } } } c = Config('prod', config_from_disk=config_from_disk) resolved = c.environment_variables assert resolved == { 'top_level': 'foo', 'stage_var': 'bar', 'shared_key': 'from-stage', }
def create_config_obj(self, chalice_stage_name=DEFAULT_STAGE_NAME, autogen_policy=True, api_gateway_stage=None): # type: (str, bool, Optional[str]) -> Config user_provided_params = {} # type: Dict[str, Any] default_params = {'project_dir': self.project_dir} try: config_from_disk = self.load_project_config() except (OSError, IOError): raise RuntimeError("Unable to load the project config file. " "Are you sure this is a chalice project?") self._validate_config_from_disk(config_from_disk) app_obj = self.load_chalice_app() user_provided_params['chalice_app'] = app_obj if autogen_policy is not None: user_provided_params['autogen_policy'] = autogen_policy if self.profile is not None: user_provided_params['profile'] = self.profile if api_gateway_stage is not None: user_provided_params['api_gateway_stage'] = api_gateway_stage config = Config(chalice_stage_name, user_provided_params, config_from_disk, default_params) return config
def test_can_package_sqs_handler(self, sample_app): @sample_app.on_sqs_message(queue='foo', batch_size=5) def handler(event): pass config = Config.create(chalice_app=sample_app, project_dir='.', api_gateway_stage='api') template = self.generate_template(config, 'dev') sns_handler = template['Resources']['Handler'] assert sns_handler['Properties']['Events'] == { 'HandlerSqsEventSource': { 'Type': 'SQS', 'Properties': { 'Queue': { 'Fn::Sub': ('arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:foo') }, 'BatchSize': 5, }, } }
def test_single_role_generated_for_default_config(self, sample_app_lambda_only): # The sample_app has one lambda function. # We'll add a few more and verify they all share the same role. @sample_app_lambda_only.lambda_function() def second(event, context): pass @sample_app_lambda_only.lambda_function() def third(event, context): pass config = Config.create(chalice_app=sample_app_lambda_only, project_dir='.', autogen_policy=True, api_gateway_stage='api') template = self.generate_template(config, 'dev') roles = [ resource for resource in template['Resources'].values() if resource['Type'] == 'AWS::IAM::Role' ] assert len(roles) == 1 # The lambda functions should all reference this role. functions = [ resource for resource in template['Resources'].values() if resource['Type'] == 'AWS::Serverless::Function' ] role_names = [function['Properties']['Role'] for function in functions] assert role_names == [ { 'Fn::GetAtt': ['DefaultRole', 'Arn'] }, { 'Fn::GetAtt': ['DefaultRole', 'Arn'] }, { 'Fn::GetAtt': ['DefaultRole', 'Arn'] }, ]
def test_can_package_sns_handler(self, sample_app): @sample_app.on_sns_message(topic='foo') def handler(event): pass config = Config.create(chalice_app=sample_app, project_dir='.', api_gateway_stage='api') template = self.generate_template(config, 'dev') sns_handler = template['Resources']['Handler'] assert sns_handler['Properties']['Events'] == { 'HandlerSnsSubscription': { 'Type': 'SNS', 'Properties': { 'Topic': { 'Fn::Sub': ( 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:foo' ) } }, } }
def test_can_chain_lookup(): user_provided_params = { 'api_gateway_stage': 'user_provided_params', } config_from_disk = { 'api_gateway_stage': 'config_from_disk', 'app_name': 'config_from_disk', } default_params = { 'api_gateway_stage': 'default_params', 'app_name': 'default_params', 'project_dir': 'default_params', } c = Config('dev', user_provided_params, config_from_disk, default_params) assert c.api_gateway_stage == 'user_provided_params' assert c.app_name == 'config_from_disk' assert c.project_dir == 'default_params' assert c.config_from_disk == config_from_disk
def test_lambda_deployer_with_memory_size_configured(self, sample_app): cfg = Config.create(chalice_stage='dev', app_name='myapp', chalice_app=sample_app, manage_iam_role=False, iam_role_arn='role-arn', project_dir='.', lambda_memory_size=256) deployer = LambdaDeployer(self.aws_client, self.packager, self.prompter, self.osutils, self.app_policy) deployer.deploy(cfg, self.deployed_resources, 'dev') self.aws_client.update_function.assert_called_with( function_name=self.lambda_function_name, zip_contents=self.package_contents, runtime=cfg.lambda_python_version, tags={ 'aws-chalice': 'version=%s:stage=dev:app=myapp' % (chalice_version), }, environment_variables={}, timeout=60, memory_size=256)
def test_lambda_deployer_defaults(self, sample_app): cfg = Config.create(chalice_stage='dev', app_name='myapp', chalice_app=sample_app, manage_iam_role=False, iam_role_arn='role-arn', project_dir='.') deployer = LambdaDeployer(self.aws_client, self.packager, None, self.osutils, self.app_policy) deployer.deploy(cfg, None, 'dev') self.aws_client.create_function.assert_called_with( function_name='myapp-dev', role_arn='role-arn', zip_contents=b'package contents', runtime=cfg.lambda_python_version, tags={ 'aws-chalice': 'version=%s:stage=dev:app=myapp' % (chalice_version) }, environment_variables={}, timeout=60, memory_size=128)
def test_managed_layer_removed_if_no_deps(self): function = create_function_resource('myfunction') function.managed_layer = models.LambdaLayer( resource_name='managed-layer', layer_name='appname-dev-managed-layer', runtime='python2.7', deployment_package=models.DeploymentPackage( models.Placeholder.BUILD_STAGE)) lambda_packager = mock.Mock(spec=packager.BaseLambdaDeploymentPackager) layer_packager = mock.Mock(spec=packager.BaseLambdaDeploymentPackager) lambda_packager.create_deployment_package.return_value = 'package.zip' layer_packager.create_deployment_package.side_effect = \ packager.EmptyPackageError() config = Config.create(project_dir='.') p = ManagedLayerDeploymentPackager(lambda_packager, layer_packager) p.handle(config, function.managed_layer) p.handle(config, function) # If the deployment package for layers would result in an empty # deployment package, we expect that resource to be removed, it can't # be created on the service. assert function.managed_layer is None
def test_tags_merge(self): config_from_disk = { 'app_name': 'myapp', 'tags': { 'onlyglobalkey': 'globalvalue', 'sharedkey': 'globalvalue' }, 'stages': { 'dev': { 'tags': { 'sharedkey': 'stagevalue', 'onlystagekey': 'stagevalue' } } } } c = Config('dev', config_from_disk=config_from_disk) assert c.tags == { 'onlyglobalkey': 'globalvalue', 'sharedkey': 'stagevalue', 'onlystagekey': 'stagevalue', 'aws-chalice': 'version=%s:stage=dev:app=myapp' % chalice_version }
def create_config_obj(self, chalice_stage_name=DEFAULT_STAGE_NAME, autogen_policy=None, api_gateway_stage=None, user_provided_params=None): # type: (str, Optional[bool], str, Optional[Dict[str, Any]]) -> Config if user_provided_params is None: user_provided_params = {} default_params = { 'project_dir': self.project_dir, 'api_gateway_stage': DEFAULT_APIGATEWAY_STAGE_NAME, 'api_gateway_endpoint_type': DEFAULT_ENDPOINT_TYPE, 'autogen_policy': True } try: config_from_disk = self.load_project_config() except (OSError, IOError): raise RuntimeError("Unable to load the project config file. " "Are you sure this is a chalice project?") except ValueError as err: raise RuntimeError("Unable to load the project config file: %s" % err) self._validate_config_from_disk(config_from_disk) if autogen_policy is not None: user_provided_params['autogen_policy'] = autogen_policy if self.profile is not None: user_provided_params['profile'] = self.profile if api_gateway_stage is not None: user_provided_params['api_gateway_stage'] = api_gateway_stage config = Config(chalice_stage=chalice_stage_name, user_provided_params=user_provided_params, config_from_disk=config_from_disk, default_params=default_params) user_provided_params['chalice_app'] = functools.partial( self.load_chalice_app, config.environment_variables) return config
def test_lambda_deployer_repeated_deploy(): osutils = InMemoryOSUtils({'packages.zip': b'package contents'}) aws_client = mock.Mock(spec=TypedAWSClient) packager = mock.Mock(spec=LambdaDeploymentPackager) packager.deployment_package_filename.return_value = 'packages.zip' # Given the lambda function already exists: aws_client.lambda_function_exists.return_value = True # And given we don't want chalice to manage our iam role for the lambda # function: cfg = Config({'chalice_app': sample_app, 'manage_iam_role': False, 'app_name': 'appname', 'iam_role_arn': True, 'project_dir': './myproject'}) d = LambdaDeployer(aws_client, packager, None, osutils) # Doing a lambda deploy: d.deploy(cfg) # Should result in injecting the latest app code. packager.inject_latest_app.assert_called_with('packages.zip', './myproject') # And should result in the lambda function being updated with the API. aws_client.update_function_code.assert_called_with( 'appname', 'package contents')
def test_lambda_deployer_repeated_deploy(app_policy, sample_app): osutils = InMemoryOSUtils({'packages.zip': b'package contents'}) aws_client = mock.Mock(spec=TypedAWSClient) packager = mock.Mock(spec=LambdaDeploymentPackager) packager.deployment_package_filename.return_value = 'packages.zip' # Given the lambda function already exists: aws_client.lambda_function_exists.return_value = True aws_client.update_function.return_value = {"FunctionArn": "myarn"} # And given we don't want chalice to manage our iam role for the lambda # function: cfg = Config.create( chalice_stage='dev', chalice_app=sample_app, manage_iam_role=False, app_name='appname', iam_role_arn=True, project_dir='./myproject', environment_variables={"FOO": "BAR"}, ) d = LambdaDeployer(aws_client, packager, None, osutils, app_policy) # Doing a lambda deploy: lambda_function_name = 'lambda_function_name' deployed = DeployedResources('api', 'api_handler_arn', lambda_function_name, None, 'dev', None, None) d.deploy(cfg, deployed, 'dev') # Should result in injecting the latest app code. packager.inject_latest_app.assert_called_with('packages.zip', './myproject') # And should result in the lambda function being updated with the API. aws_client.update_function.assert_called_with(lambda_function_name, 'package contents', {"FOO": "BAR"})
def test_default_tags(self): c = Config('dev', config_from_disk={'app_name': 'myapp'}) assert c.tags == { 'aws-chalice': 'version=%s:stage=dev:app=myapp' % chalice_version }
def test_set_lambda_memory_size_stage(self): config_from_disk = {'stages': {'dev': {'lambda_timeout': 120}}} c = Config('dev', config_from_disk=config_from_disk) assert c.lambda_timeout == 120
def test_set_lambda_timeout_global(self): config_from_disk = {'lambda_timeout': 120} c = Config('dev', config_from_disk=config_from_disk) assert c.lambda_timeout == 120
def test_not_set(self): c = Config('dev', config_from_disk={}) assert c.lambda_timeout is None
def test_default_value_of_manage_iam_role(): c = Config.create() assert c.manage_iam_role
def mock_cli_factory(mock_deployer): cli_factory = mock.Mock(spec=factory.CLIFactory) cli_factory.create_config_obj.return_value = Config.create(project_dir='.') cli_factory.create_botocore_session.return_value = mock.sentinel.Session cli_factory.create_default_deployer.return_value = mock_deployer return cli_factory
def test_not_set(self): c = Config('dev', config_from_disk={}) assert c.lambda_memory_size is None
def test_version_defaults_to_1_when_missing(): c = Config() assert c.config_file_version == '1.0'
def test_set_minimum_compression_size_global(self): config_from_disk = {'minimum_compression_size': 5000} c = Config('dev', config_from_disk=config_from_disk) assert c.minimum_compression_size == 5000
def test_not_set(self): c = Config('dev', config_from_disk={}) assert c.minimum_compression_size is None
def test_default_chalice_stage(): c = Config() assert c.chalice_stage == 'dev'
def test_environment_from_top_level(): config_from_disk = {'environment_variables': {"foo": "bar"}} c = Config('dev', config_from_disk=config_from_disk) assert c.environment_variables == config_from_disk['environment_variables']
def test_lazy_load_chalice_app_must_be_callable(): c = Config.create(chalice_app='not a callable') with pytest.raises(TypeError): c.chalice_app
def test_manage_iam_role_explicitly_set(): c = Config.create(manage_iam_role=False) assert not c.manage_iam_role c = Config.create(manage_iam_role=True) assert c.manage_iam_role
def test_set_lambda_memory_size_global(self): config_from_disk = {'lambda_memory_size': 256} c = Config('dev', config_from_disk=config_from_disk) assert c.lambda_memory_size == 256
def config(): return Config()
def test_set_lambda_memory_size_stage(self): config_from_disk = {'stages': {'dev': {'lambda_memory_size': 256}}} c = Config('dev', config_from_disk=config_from_disk) assert c.lambda_memory_size == 256