def test_can_package_as_cdk_app(runner): # The CDK loading/synth can take a while so we're testing the # various APIs out in one test to cut down on test time. with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testcdkpackage', project_type='cdk-ddb') dirname = os.path.abspath( os.path.join('testcdkpackage', 'infrastructure')) os.chdir(dirname) cdk_app, chalice_app = load_chalice_construct(dirname, 'testcdkpackage') assembly = cdk_app.synth() stack = assembly.get_stack_by_name('testcdkpackage') cfn_template = stack.template resources = cfn_template['Resources'] # Sanity check that we have the resources from Chalice as well as the # resources from the ChaliceApp construct. assert 'APIHandler' in resources assert 'DefaultRole' in resources ddb_tables = filter_resources(cfn_template, 'AWS::DynamoDB::Table')[0] # CDK adds a random suffix to our resource name so we verify that # the name starts with our provided name "AppTable". assert ddb_tables[0].startswith('AppTable') # We also need to verify that we've replaces the CodUri with the # CDK specific assets. functions = filter_resources(cfn_template, 'AWS::Serverless::Function')[0] bucket_ref = functions[1]['Properties']['CodeUri']['Bucket']['Ref'] assert bucket_ref.startswith('AssetParameters')
def test_can_specify_profile_for_logs(runner, mock_cli_factory): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.logs, ['--profile', 'my-profile'], cli_factory=mock_cli_factory) assert result.exit_code == 0 assert mock_cli_factory.profile == 'my-profile'
def test_can_generate_appgraph(runner, mock_cli_factory): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.appgraph, []) assert result.exit_code == 0 # Just sanity checking some of the output assert 'Application' in result.output assert 'RestAPI(' in result.output
def test_case_insensitive_template_format(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.package, ['--template-format', 'YAML', 'outdir']) assert result.exit_code == 0, result.output assert os.path.isdir('outdir') assert 'sam.yaml' in os.listdir('outdir')
def test_debug_flag_enables_logging(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = runner.invoke(cli.cli, ['--debug', 'package', 'outdir'], obj={}) assert result.exit_code == 0 assert re.search('[DEBUG].*Creating deployment package', result.output) is not None
def test_error_when_no_deployed_record(runner, mock_cli_factory): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.url, [], cli_factory=mock_cli_factory) assert result.exit_code == 2 assert 'not find' in result.output
def test_can_package_with_single_file(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.package, ['--single-file', 'package.zip']) assert result.exit_code == 0, result.output assert os.path.isfile('package.zip') with zipfile.ZipFile('package.zip', 'r') as f: assert sorted(f.namelist()) == ['deployment.zip', 'sam.json']
def test_can_package_command(runner, mock_cli_factory): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.package, ['outdir']) assert result.exit_code == 0, result.output assert os.path.isdir('outdir') dir_contents = os.listdir('outdir') assert 'sam.json' in dir_contents assert 'deployment.zip' in dir_contents
def test_does_fail_to_generate_swagger_if_no_rest_api(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') with open('app.py', 'w') as f: f.write('from chalice import Chalice\n' 'app = Chalice("myapp")\n') result = _run_cli_command(runner, cli.generate_models, []) assert result.exit_code == 1 assert result.output == ('No REST API found to generate model from.\n' 'Aborted!\n')
def test_can_deploy_specify_connection_timeout(runner, mock_cli_factory): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.deploy, ['--connection-timeout', 100], cli_factory=mock_cli_factory) assert result.exit_code == 0 mock_cli_factory.create_botocore_session.assert_called_with( connection_timeout=100)
def test_invoke_does_raise_if_no_function_found(runner, mock_cli_factory): mock_cli_factory.create_lambda_invoke_handler.side_effect = \ factory.NoSuchFunctionError('foo') with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.invoke, ['-n', 'foo'], cli_factory=mock_cli_factory) assert result.exit_code == 2 assert 'foo' in result.output
def test_can_package_different_formats(runner, package_format, template_format, expected_filename): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') package_app('testproject', output_dir='packagedir', stage='dev', package_format=package_format, template_format=template_format) app_contents = os.listdir('packagedir') assert expected_filename in app_contents assert 'deployment.zip' in app_contents
def test_can_package_with_yaml_command(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.package, ['--template-format', 'yaml', 'outdir']) assert result.exit_code == 0, result.output assert os.path.isdir('outdir') dir_contents = os.listdir('outdir') assert 'sam.yaml' in dir_contents assert 'deployment.zip' in dir_contents
def test_invoke_does_raise_if_read_timeout(runner, mock_cli_factory): mock_cli_factory.create_lambda_invoke_handler.side_effect = \ ReadTimeout('It took too long') with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.invoke, ['-n', 'foo'], cli_factory=mock_cli_factory) assert result.exit_code == 1 assert 'It took too long' in result.output
def test_cdk_construct_api(runner): # The CDK loading/synth can take a while so we're testing the # various APIs out in one test to cut down on test time. with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testcdk', project_type='cdk-ddb') dirname = os.path.abspath(os.path.join('testcdk', 'infrastructure')) os.chdir(dirname) cdk_app, chalice_app = load_chalice_construct(dirname, 'testcdk') api_handler = chalice_app.get_function('APIHandler') assert api_handler == chalice_app.get_function('APIHandler') role = chalice_app.get_role('DefaultRole') assert hasattr(role, 'role_name')
def test_can_generate_dev_plan(runner, mock_cli_factory): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.plan, [], cli_factory=mock_cli_factory) deployer = mock_cli_factory.create_plan_only_deployer.return_value call_args = deployer.deploy.call_args assert result.exit_code == 0 assert isinstance(call_args[0][0], Config) assert call_args[1] == {'chalice_stage_name': 'dev'}
def test_can_specify_api_gateway_stage(runner, mock_cli_factory): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.deploy, ['--api-gateway-stage', 'notdev'], cli_factory=mock_cli_factory) assert result.exit_code == 0 mock_cli_factory.create_config_obj.assert_called_with( autogen_policy=None, chalice_stage_name='dev', api_gateway_stage='notdev')
def test_gen_policy_command_creates_policy(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = runner.invoke(cli.cli, ['gen-policy'], obj={}) assert result.exit_code == 0 # The output should be valid JSON. parsed_policy = json.loads(result.output) # We don't want to validate the specific parts of the policy # (that's tested elsewhere), but we'll check to make sure # it looks like a policy document. assert 'Version' in parsed_policy assert 'Statement' in parsed_policy
def test_no_errors_if_override_codebuild_image(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.generate_pipeline, ['-i', 'python:3.6.1', 'pipeline.json']) assert result.exit_code == 0, result.output assert os.path.isfile('pipeline.json') with open('pipeline.json', 'r') as f: template = json.load(f) # The actual contents are tested in the unit # tests. Just a sanity check that it looks right. image = template['Parameters']['CodeBuildImage']['Default'] assert image == 'python:3.6.1'
def test_can_call_invoke(runner, mock_cli_factory, monkeypatch): invoke_handler = mock.Mock(spec=LambdaInvokeHandler) mock_cli_factory.create_lambda_invoke_handler.return_value = invoke_handler mock_reader = mock.Mock(spec=PipeReader) mock_reader.read.return_value = 'barbaz' mock_cli_factory.create_stdin_reader.return_value = mock_reader with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.invoke, ['-n', 'foo'], cli_factory=mock_cli_factory) assert result.exit_code == 0 assert invoke_handler.invoke.call_args == mock.call('barbaz')
def test_does_deploy_with_default_api_gateway_stage_name( runner, mock_cli_factory): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') # This isn't perfect as we're assuming we know how to # create the config_obj like the deploy() command does, # it should give us more confidence that the api gateway # stage defaults are still working. cli_factory = factory.CLIFactory('.') config = cli_factory.create_config_obj(chalice_stage_name='dev', autogen_policy=None, api_gateway_stage=None) assert config.api_gateway_stage == DEFAULT_APIGATEWAY_STAGE_NAME
def test_can_generate_pipeline_for_all(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.generate_pipeline, ['pipeline.json']) assert result.exit_code == 0, result.output assert os.path.isfile('pipeline.json') with open('pipeline.json', 'r') as f: template = json.load(f) # The actual contents are tested in the unit # tests. Just a sanity check that it looks right. assert "AWSTemplateFormatVersion" in template assert "Outputs" in template
def new_project(ctx, project_name, profile, project_type): # type: (click.Context, str, str, str) -> None if project_name is None: prompter = ctx.obj.get('prompter', newproj.getting_started_prompt) answers = prompter() project_name = answers['project_name'] project_type = answers['project_type'] if os.path.isdir(project_name): click.echo("Directory already exists: %s" % project_name, err=True) raise click.Abort() newproj.create_new_project_skeleton(project_name, project_type=project_type) validate_python_version(Config.create()) click.echo("Your project has been generated in ./%s" % project_name)
def test_can_extract_buildspec_yaml(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.generate_pipeline, [ '--buildspec-file', 'buildspec.yml', '-i', 'python:3.6.1', 'pipeline.json' ]) assert result.exit_code == 0, result.output assert os.path.isfile('buildspec.yml') with open('buildspec.yml') as f: data = f.read() # The contents of this file are tested elsewhere, # we just want a basic sanity check here. assert 'chalice package' in data
def test_package_terraform_err_with_single_file_or_merge(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command( runner, cli.package, ['--pkg-format', 'terraform', '--single-file', 'module']) assert result.exit_code == 1, result.output assert "Terraform format does not support" in result.output result = _run_cli_command(runner, cli.package, [ '--pkg-format', 'terraform', '--merge-template', 'foo.json', 'module' ]) assert result.exit_code == 1, result.output assert "Terraform format does not support" in result.output
def test_error_message_displayed_when_missing_feature_opt_in(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') with open(os.path.join('testproject', 'app.py'), 'w') as f: # Rather than pick an existing experimental feature, we're # manually injecting a feature flag into our app. This ensures # we don't have to update this test if a feature graduates # from trial to accepted. The '_features_used' is a "package # private" var for chalice code. f.write('from chalice import Chalice\n' 'app = Chalice("myapp")\n' 'app._features_used.add("MYTESTFEATURE")\n') os.chdir('testproject') result = _run_cli_command(runner, cli.package, ['out']) assert isinstance(result.exception, ExperimentalFeatureError) assert 'MYTESTFEATURE' in str(result.exception)
def test_can_retrieve_url(runner, mock_cli_factory): deployed_values_dev = { "schema_version": "2.0", "resources": [ { "rest_api_url": "https://dev-url/", "name": "rest_api", "resource_type": "rest_api" }, ] } deployed_values_prod = { "schema_version": "2.0", "resources": [ { "rest_api_url": "https://prod-url/", "name": "rest_api", "resource_type": "rest_api" }, ] } with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') deployed_dir = os.path.join('.chalice', 'deployed') os.makedirs(deployed_dir) record_deployed_values(deployed_values_dev, os.path.join(deployed_dir, 'dev.json')) record_deployed_values(deployed_values_prod, os.path.join(deployed_dir, 'prod.json')) result = _run_cli_command(runner, cli.url, [], cli_factory=mock_cli_factory) assert result.exit_code == 0 assert result.output == 'https://dev-url/\n' prod_result = _run_cli_command(runner, cli.url, ['--stage', 'prod'], cli_factory=mock_cli_factory) assert prod_result.exit_code == 0 assert prod_result.output == 'https://prod-url/\n'
def test_can_override_chalice_config(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') chalice_config = { 'environment_variables': { 'FOO': 'BAR', } } package_app('testproject', output_dir='packagedir', stage='dev', chalice_config=chalice_config) app_contents = os.listdir('packagedir') assert 'sam.json' in app_contents with open(os.path.join('packagedir', 'sam.json')) as f: data = json.loads(f.read()) properties = data['Resources']['APIHandler']['Properties'] assert properties['Environment'] == { 'Variables': { 'FOO': 'BAR', } }
def test_can_configure_github(runner): with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') # The -i option is provided so we don't have to skip this # test on python3.6 result = _run_cli_command( runner, cli.generate_pipeline, ['--source', 'github', '-i' 'python:3.6.1', 'pipeline.json']) assert result.exit_code == 0, result.output assert os.path.isfile('pipeline.json') with open('pipeline.json', 'r') as f: template = json.load(f) # The template is already tested in the unit tests # for template generation. We just want a basic # sanity check to make sure things are mapped # properly. assert 'GithubOwner' in template['Parameters'] assert 'GithubRepoName' in template['Parameters']
def test_invoke_does_raise_if_unhandled_error(runner, mock_cli_factory): deployed_resources = DeployedResources({"resources": []}) mock_cli_factory.create_config_obj.return_value = FakeConfig( deployed_resources) invoke_handler = mock.Mock(spec=LambdaInvokeHandler) invoke_handler.invoke.side_effect = UnhandledLambdaError('foo') mock_cli_factory.create_lambda_invoke_handler.return_value = invoke_handler mock_reader = mock.Mock(spec=PipeReader) mock_reader.read.return_value = 'barbaz' mock_cli_factory.create_stdin_reader.return_value = mock_reader with runner.isolated_filesystem(): newproj.create_new_project_skeleton('testproject') os.chdir('testproject') result = _run_cli_command(runner, cli.invoke, ['-n', 'foo'], cli_factory=mock_cli_factory) assert result.exit_code == 1 assert invoke_handler.invoke.call_args == mock.call('barbaz') assert 'Unhandled exception in Lambda function, details above.' \ in result.output