コード例 #1
0
def test_deployed_api_mapping_resource():
    deployed = DeployedResources(
        {'resources': [
            {'name': 'foo'},
            {
                "name": "api_gateway_custom_domain",
                "resource_type": "domain_name",
                "api_mapping": [
                    {
                        "key": "path_key"
                    }
                ]
            }
        ]}
    )

    name = 'api_gateway_custom_domain.api_mapping.path_key'
    result = deployed.resource_values(name)
    assert result == {
        "name": "api_gateway_custom_domain",
        "resource_type": "domain_name",
        "api_mapping": [
            {
                "key": "path_key"
            }
        ]
    }
コード例 #2
0
class SmokeTestApplication(object):

    # Number of seconds to wait after redeploy before starting
    # to poll for successful 200.
    _REDEPLOY_SLEEP = 20
    # Seconds to wait between poll attempts after redeploy.
    _POLLING_DELAY = 5

    def __init__(self, deployed_values, stage_name, app_name, app_dir, region):
        self._deployed_resources = DeployedResources(deployed_values)
        self.stage_name = stage_name
        self.app_name = app_name
        # The name of the tmpdir where the app is copied.
        self.app_dir = app_dir
        self._has_redeployed = False
        self._region = region

    @property
    def websocket_api_id(self):
        return self._deployed_resources.resource_values(
            'websocket_api')['websocket_api_id']

    @property
    def websocket_connect_url(self):
        return ("wss://{websocket_api_id}.execute-api.{region}.amazonaws.com/"
                "{api_gateway_stage}".format(
                    websocket_api_id=self.websocket_api_id,
                    region=self._region,
                    api_gateway_stage='api',
                ))

    @property
    def websocket_message_handler_arn(self):
        return self._deployed_resources.resource_values(
            'websocket_message')['lambda_arn']

    @property
    def region(self):
        return self._region

    def redeploy_once(self):
        # Redeploy the application once.  If a redeploy
        # has already happened, this function is a noop.
        if self._has_redeployed:
            return
        new_file = os.path.join(self.app_dir, 'app-redeploy.py')
        original_app_py = os.path.join(self.app_dir, 'app.py')
        shutil.move(original_app_py, original_app_py + '.bak')
        shutil.copy(new_file, original_app_py)
        self._clear_app_import()
        _deploy_app(self.app_dir)
        self._has_redeployed = True
        # Give it settling time before running more tests.
        time.sleep(self._REDEPLOY_SLEEP)

    def _clear_app_import(self):
        # Now that we're using `import` instead of `exec` we need
        # to clear out sys.modules in order to pick up the new
        # version of the app we just copied over.
        del sys.modules['app']
コード例 #3
0
 def __init__(self, deployed_values, stage_name, app_name, app_dir, region):
     self._deployed_resources = DeployedResources(deployed_values)
     self.stage_name = stage_name
     self.app_name = app_name
     # The name of the tmpdir where the app is copied.
     self.app_dir = app_dir
     self._has_redeployed = False
     self._region = region
コード例 #4
0
def test_prompted_on_runtime_change_can_reject_change(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'
    aws_client.lambda_function_exists.return_value = True
    aws_client.get_function_configuration.return_value = {
        'Runtime': 'python1.0',
    }
    aws_client.update_function.return_value = {"FunctionArn": "myarn"}
    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"},
    )
    prompter = mock.Mock(spec=NoPrompt)
    prompter.confirm.side_effect = RuntimeError("Aborted")

    d = LambdaDeployer(aws_client, packager, prompter, osutils, app_policy)
    # Doing a lambda deploy with a different runtime:
    lambda_function_name = 'lambda_function_name'
    deployed = DeployedResources('api', 'api_handler_arn',
                                 lambda_function_name, None, 'dev', None, None)
    with pytest.raises(RuntimeError):
        d.deploy(cfg, deployed, 'dev')

    assert not packager.inject_latest_app.called
    assert not aws_client.update_function.called
    assert prompter.confirm.called
    message = prompter.confirm.call_args[0][0]
    assert 'runtime will change' in message
コード例 #5
0
ファイル: test_cli.py プロジェクト: yutiansut/chalice
def test_can_provide_lambda_name_for_logs(runner, mock_cli_factory):
    deployed_resources = DeployedResources({
        "resources": [
            {"name": "foo",
             "lambda_arn": "arn:aws:lambda::app-dev-foo",
             "resource_type": "lambda_function"}]
    })
    mock_cli_factory.create_config_obj.return_value = FakeConfig(
        deployed_resources)
    log_retriever = mock.Mock(spec=LogRetriever)
    log_retriever.retrieve_logs.return_value = []
    mock_cli_factory.create_log_retriever.return_value = log_retriever
    with runner.isolated_filesystem():
        cli.create_new_project_skeleton('testproject')
        os.chdir('testproject')
        result = _run_cli_command(
            runner, cli.logs, ['--name', 'foo'],
            cli_factory=mock_cli_factory
        )
        assert result.exit_code == 0
    log_retriever.retrieve_logs.assert_called_with(
        include_lambda_messages=False, max_entries=None)
    mock_cli_factory.create_log_retriever.assert_called_with(
        mock.sentinel.Session, 'arn:aws:lambda::app-dev-foo'
    )
コード例 #6
0
ファイル: test_cli.py プロジェクト: yutiansut/chalice
def test_invoke_does_raise_if_service_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 = ClientError(
        {
            'Error': {
                'Code': 'LambdaError',
                'Message': 'Error message'
            }
        },
        'Invoke'
    )
    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():
        cli.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 (
        "Error: got 'LambdaError' exception back from Lambda\n"
        "Error message"
    ) in result.output
コード例 #7
0
ファイル: test_features.py プロジェクト: awslabs/chalice
 def __init__(self, deployed_values, stage_name, app_name,
              app_dir, region):
     self._deployed_resources = DeployedResources(deployed_values)
     self.stage_name = stage_name
     self.app_name = app_name
     # The name of the tmpdir where the app is copied.
     self.app_dir = app_dir
     self._has_redeployed = False
     self._region = region
コード例 #8
0
def test_api_gateway_deployer_delete(config_obj):
    aws_client = mock.Mock(spec=TypedAWSClient, region_name='us-west-2')

    rest_api_id = 'abcdef1234'
    deployed = DeployedResources(None, None, None, rest_api_id, 'dev', None,
                                 None)
    aws_client.rest_api_exists.return_value = True

    d = APIGatewayDeployer(aws_client)
    d.delete(deployed)
    aws_client.delete_rest_api.assert_called_with(rest_api_id)
コード例 #9
0
ファイル: test_planner.py プロジェクト: vignesh97/chalice
 def test_can_get_deployed_values(self):
     remote_state = RemoteState(
         self.client,
         DeployedResources(
             {'resources': [{
                 'name': 'rest_api',
                 'rest_api_id': 'foo'
             }]}))
     rest_api = self.create_rest_api_model()
     values = remote_state.resource_deployed_values(rest_api)
     assert values == {'name': 'rest_api', 'rest_api_id': 'foo'}
コード例 #10
0
ファイル: test_planner.py プロジェクト: vignesh97/chalice
 def test_value_error_raised_for_unknown_resource_name(self):
     remote_state = RemoteState(
         self.client,
         DeployedResources({
             'resources': [{
                 'name': 'not_rest_api',
                 'rest_api_id': 'foo'
             }]
         }))
     rest_api = self.create_rest_api_model()
     with pytest.raises(ValueError):
         remote_state.resource_deployed_values(rest_api)
コード例 #11
0
def test_lambda_deployer_delete():
    aws_client = mock.Mock(spec=TypedAWSClient)
    aws_client.get_role_arn_for_name.return_value = 'arn_prefix/role_name'
    lambda_function_name = 'lambda_name'
    deployed = DeployedResources('api', 'api_handler_arn/lambda_name',
                                 lambda_function_name, None, 'dev', None, None)
    d = LambdaDeployer(aws_client, None, CustomConfirmPrompt(True), None, None)
    d.delete(deployed)

    aws_client.get_role_arn_for_name.assert_called_with(lambda_function_name)
    aws_client.delete_function.assert_called_with(lambda_function_name)
    aws_client.delete_role.assert_called_with('role_name')
コード例 #12
0
ファイル: test_deployer.py プロジェクト: stBecker/chalice
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"},
                        lambda_timeout=120,
                        lambda_memory_size=256,
                        tags={'mykey': 'myvalue'})
    aws_client.get_function_configuration.return_value = {
        'Runtime': cfg.lambda_python_version,
    }
    prompter = mock.Mock(spec=NoPrompt)
    prompter.confirm.return_value = True

    d = LambdaDeployer(aws_client, packager, prompter, 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(
        function_name=lambda_function_name,
        zip_contents=b'package contents',
        runtime=cfg.lambda_python_version,
        environment_variables={"FOO": "BAR"},
        tags={
            'aws-chalice':
            'version=%s:stage=%s:app=%s' % (chalice_version, 'dev', 'appname'),
            'mykey':
            'myvalue'
        },
        timeout=120,
        memory_size=256)
コード例 #13
0
ファイル: test_config.py プロジェクト: sanmartim/chalice
def test_lambda_functions_not_required_from_dict():
    older_version = {
        # Older versions of chalice did not include the
        # lambda_functions key.
        'backend': 'api',
        'api_handler_arn': 'arn',
        'api_handler_name': 'name',
        'rest_api_id': 'id',
        'api_gateway_stage': 'stage',
        'region': 'region',
        'chalice_version': '1.0.0',
    }
    d = DeployedResources.from_dict(older_version)
    assert d.lambda_functions == {}
コード例 #14
0
ファイル: test_planner.py プロジェクト: vignesh97/chalice
 def test_rest_api_not_exists_with_preexisting_deploy(self):
     rest_api = self.create_rest_api_model()
     deployed_resources = {
         'resources': [{
             'name': 'rest_api',
             'resource_type': 'rest_api',
             'rest_api_id': 'my_rest_api_id',
         }]
     }
     self.client.rest_api_exists.return_value = False
     remote_state = RemoteState(self.client,
                                DeployedResources(deployed_resources))
     assert not remote_state.resource_exists(rest_api)
     self.client.rest_api_exists.assert_called_with('my_rest_api_id')
コード例 #15
0
def test_lambda_deployer_delete_already_deleted(capsys):
    lambda_function_name = 'lambda_name'
    aws_client = mock.Mock(spec=TypedAWSClient)
    aws_client.get_role_arn_for_name.return_value = 'arn_prefix/role_name'
    aws_client.delete_function.side_effect = ResourceDoesNotExistError(
        lambda_function_name)
    deployed = DeployedResources('api', 'api_handler_arn/lambda_name',
                                 lambda_function_name, None, 'dev', None, None)
    d = LambdaDeployer(aws_client, None, NoPrompt(), None, None)
    d.delete(deployed)

    # check that we printed that no lambda function with that name was found
    out, _ = capsys.readouterr()
    assert "No lambda function named %s found." % lambda_function_name in out
    aws_client.delete_function.assert_called_with(lambda_function_name)
コード例 #16
0
def test_api_gateway_deployer_delete_already_deleted(capsys):
    rest_api_id = 'abcdef1234'
    aws_client = mock.Mock(spec=TypedAWSClient, region_name='us-west-2')
    aws_client.delete_rest_api.side_effect = ResourceDoesNotExistError(
        rest_api_id)
    deployed = DeployedResources(None, None, None, rest_api_id, 'dev', None,
                                 None)
    aws_client.rest_api_exists.return_value = True
    d = APIGatewayDeployer(aws_client)
    d.delete(deployed)

    # Check that we printed out that no rest api with that id was found
    out, _ = capsys.readouterr()
    assert "No rest API with id %s found." % rest_api_id in out
    aws_client.delete_rest_api.assert_called_with(rest_api_id)
コード例 #17
0
def test_can_create_deployed_resource_from_dict():
    d = DeployedResources.from_dict({
        'backend': 'api',
        'api_handler_arn': 'arn',
        'api_handler_name': 'name',
        'rest_api_id': 'id',
        'api_gateway_stage': 'stage',
        'region': 'region',
        'chalice_version': '1.0.0',
    })
    assert d.backend == 'api'
    assert d.api_handler_arn == 'arn'
    assert d.api_handler_name == 'name'
    assert d.rest_api_id == 'id'
    assert d.api_gateway_stage == 'stage'
    assert d.region == 'region'
    assert d.chalice_version == '1.0.0'
コード例 #18
0
ファイル: test_config.py プロジェクト: patrickpierson/chalice
def test_can_create_deployed_resource_from_dict():
    d = DeployedResources.from_dict({
        'backend': 'api',
        'api_handler_arn': 'arn',
        'api_handler_name': 'name',
        'rest_api_id': 'id',
        'api_gateway_stage': 'stage',
        'region': 'region',
        'chalice_version': '1.0.0',
    })
    assert d.backend == 'api'
    assert d.api_handler_arn == 'arn'
    assert d.api_handler_name == 'name'
    assert d.rest_api_id == 'id'
    assert d.api_gateway_stage == 'stage'
    assert d.region == 'region'
    assert d.chalice_version == '1.0.0'
コード例 #19
0
ファイル: test_cli.py プロジェクト: yutiansut/chalice
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():
        cli.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
コード例 #20
0
ファイル: test_planner.py プロジェクト: vignesh97/chalice
 def test_dynamically_lookup_iam_role(self):
     remote_state = RemoteState(
         self.client,
         DeployedResources(
             {'resources': [{
                 'name': 'rest_api',
                 'rest_api_id': 'foo'
             }]}))
     resource = models.ManagedIAMRole(
         resource_name='default-role',
         role_name='myrole',
         trust_policy={'trust': 'policy'},
         policy=models.AutoGenIAMPolicy(document={'iam': 'policy'}),
     )
     self.client.get_role_arn_for_name.return_value = 'my-role-arn'
     values = remote_state.resource_deployed_values(resource)
     assert values == {
         'name': 'default-role',
         'resource_type': 'iam_role',
         'role_arn': 'my-role-arn',
         'role_name': 'myrole'
     }
コード例 #21
0
ファイル: test_deployer.py プロジェクト: edebill/chalice
def test_api_gateway_deployer_redeploy_api(config_obj):
    aws_client = mock.Mock(spec=TypedAWSClient, region_name='us-west-2')

    # The rest_api_id does not exist which will trigger
    # the initial import
    deployed = DeployedResources(None, None, None, 'existing-id', 'dev', None,
                                 None)
    aws_client.rest_api_exists.return_value = True
    lambda_arn = 'arn:aws:lambda:us-west-2:account-id:function:func-name'

    d = APIGatewayDeployer(aws_client)
    d.deploy(config_obj, deployed, lambda_arn)

    aws_client.update_api_from_swagger.assert_called_with(
        'existing-id', mock.ANY)
    second_arg = aws_client.update_api_from_swagger.call_args[0][1]
    assert isinstance(second_arg, dict)
    assert 'swagger' in second_arg

    aws_client.deploy_rest_api.assert_called_with('existing-id', 'dev')
    aws_client.add_permission_for_apigateway_if_needed.assert_called_with(
        'func-name', 'us-west-2', 'account-id', 'existing-id', mock.ANY)
コード例 #22
0
def test_deployer_delete_calls_deletes():
    # Check that athe deployer class calls other deployer classes delete
    # methods.
    lambda_deploy = mock.Mock(spec=LambdaDeployer)
    apig_deploy = mock.Mock(spec=APIGatewayDeployer)
    cfg = mock.Mock(spec=Config)
    deployed_resources = DeployedResources.from_dict({
        'backend': 'api',
        'api_handler_arn': 'lambda_arn',
        'api_handler_name': 'lambda_name',
        'rest_api_id': 'rest_id',
        'api_gateway_stage': 'dev',
        'region': 'us-west-2',
        'chalice_version': '0',
    })
    cfg.deployed_resources.return_value = deployed_resources

    d = Deployer(apig_deploy, lambda_deploy)
    d.delete(cfg)

    lambda_deploy.delete.assert_called_with(deployed_resources)
    apig_deploy.delete.assert_called_with(deployed_resources)
コード例 #23
0
ファイル: test_deployer.py プロジェクト: stBecker/chalice
    def setup_deployer_dependencies(self, app_policy):
        # This autouse fixture is used instead of ``setup_method`` because it:
        # * Is ran for every test
        # * Allows additional fixtures to be passed in to reduce the number
        #   of fixtures that need to be supplied for the test methods.
        # * ``setup_method`` is called before fixtures get applied so
        #   they cannot be applied to the ``setup_method`` or you will
        #   will get a TypeError for too few arguments.
        self.package_name = 'packages.zip'
        self.package_contents = b'package contents'
        self.lambda_arn = 'lambda-arn'
        self.lambda_function_name = 'lambda_function_name'

        self.osutils = InMemoryOSUtils(
            {self.package_name: self.package_contents})

        self.aws_client = mock.Mock(spec=TypedAWSClient)
        self.aws_client.lambda_function_exists.return_value = True
        self.aws_client.update_function.return_value = {
            'FunctionArn': self.lambda_arn
        }
        self.aws_client.get_function_configuration.return_value = {
            'Runtime': 'python2.7',
        }

        self.prompter = mock.Mock(spec=NoPrompt)
        self.prompter.confirm.return_value = True

        self.packager = mock.Mock(LambdaDeploymentPackager)
        self.packager.create_deployment_package.return_value =\
            self.package_name

        self.app_policy = app_policy

        self.deployed_resources = DeployedResources('api', 'api_handler_arn',
                                                    self.lambda_function_name,
                                                    None, 'dev', None, None)
コード例 #24
0
ファイル: test_deployer.py プロジェクト: edebill/chalice
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_deployed_resource_exists():
    deployed = DeployedResources({'resources': [{'name': 'foo'}]})
    assert deployed.resource_values('foo') == {'name': 'foo'}
    assert deployed.resource_names() == ['foo']
def test_deployed_resource_does_not_exist():
    deployed = DeployedResources({'resources': [{'name': 'foo'}]})
    with pytest.raises(ValueError):
        deployed.resource_values('bar')
コード例 #27
0
class SmokeTestApplication(object):

    # Number of seconds to wait after redeploy before starting
    # to poll for successful 200.
    _REDEPLOY_SLEEP = 30
    # Seconds to wait between poll attempts after redeploy.
    _POLLING_DELAY = 5
    # Number of successful wait attempts before we consider the app
    # stabilized.
    _NUM_SUCCESS = 3

    def __init__(self, deployed_values, stage_name, app_name, app_dir, region):
        self._deployed_resources = DeployedResources(deployed_values)
        self.stage_name = stage_name
        self.app_name = app_name
        # The name of the tmpdir where the app is copied.
        self.app_dir = app_dir
        self._has_redeployed = False
        self._region = region

    @property
    def url(self):
        return ("https://{rest_api_id}.execute-api.{region}.amazonaws.com/"
                "{api_gateway_stage}".format(rest_api_id=self.rest_api_id,
                                             region=self._region,
                                             api_gateway_stage='api'))

    @property
    def rest_api_id(self):
        return self._deployed_resources.resource_values(
            'rest_api')['rest_api_id']

    @property
    def websocket_api_id(self):
        return self._deployed_resources.resource_values(
            'websocket_api')['websocket_api_id']

    @property
    def websocket_connect_url(self):
        return ("wss://{websocket_api_id}.execute-api.{region}.amazonaws.com/"
                "{api_gateway_stage}".format(
                    websocket_api_id=self.websocket_api_id,
                    region=self._region,
                    api_gateway_stage='api',
                ))

    @retry(max_attempts=10, delay=5)
    def get_json(self, url):
        try:
            return self._get_json(url)
        except requests.exceptions.HTTPError:
            pass

    def _get_json(self, url):
        if not url.startswith('/'):
            url = '/' + url
        response = requests.get(self.url + url)
        response.raise_for_status()
        return response.json()

    @retry(max_attempts=10, delay=5)
    def get_response(self, url, headers=None):
        try:
            return self._send_request('GET', url, headers=headers)
        except InternalServerError:
            pass

    def _send_request(self, http_method, url, headers=None, data=None):
        kwargs = {}
        if headers is not None:
            kwargs['headers'] = headers
        if data is not None:
            kwargs['data'] = data
        response = requests.request(http_method, self.url + url, **kwargs)
        if response.status_code >= 500:
            raise InternalServerError()
        return response

    @retry(max_attempts=10, delay=5)
    def post_response(self, url, headers=None, data=None):
        try:
            return self._send_request('POST', url, headers=headers, data=data)
        except InternalServerError:
            pass

    @retry(max_attempts=10, delay=5)
    def put_response(self, url):
        try:
            return self._send_request('PUT', url)
        except InternalServerError:
            pass

    @retry(max_attempts=10, delay=5)
    def options_response(self, url):
        try:
            return self._send_request('OPTIONS', url)
        except InternalServerError:
            pass

    def redeploy_once(self):
        # Redeploy the application once.  If a redeploy
        # has already happened, this function is a noop.
        if self._has_redeployed:
            return
        new_file = os.path.join(self.app_dir, 'app-redeploy.py')
        original_app_py = os.path.join(self.app_dir, 'app.py')
        shutil.move(original_app_py, original_app_py + '.bak')
        shutil.copy(new_file, original_app_py)
        _deploy_app(self.app_dir)
        self._has_redeployed = True
        # Give it settling time before running more tests.
        time.sleep(self._REDEPLOY_SLEEP)
        for _ in range(self._NUM_SUCCESS):
            self._wait_for_stablize()
            time.sleep(self._POLLING_DELAY)

    def _wait_for_stablize(self):
        # After a deployment we sometimes need to wait for
        # API Gateway to propagate all of its changes.
        # We're going to give it num_attempts to give us a
        # 200 response before failing.
        return self.get_json('/')
コード例 #28
0
ファイル: test_features.py プロジェクト: awslabs/chalice
class SmokeTestApplication(object):

    # Number of seconds to wait after redeploy before starting
    # to poll for successful 200.
    _REDEPLOY_SLEEP = 20
    # Seconds to wait between poll attempts after redeploy.
    _POLLING_DELAY = 5

    def __init__(self, deployed_values, stage_name, app_name,
                 app_dir, region):
        self._deployed_resources = DeployedResources(deployed_values)
        self.stage_name = stage_name
        self.app_name = app_name
        # The name of the tmpdir where the app is copied.
        self.app_dir = app_dir
        self._has_redeployed = False
        self._region = region

    @property
    def url(self):
        return (
            "https://{rest_api_id}.execute-api.{region}.amazonaws.com/"
            "{api_gateway_stage}".format(rest_api_id=self.rest_api_id,
                                         region=self._region,
                                         api_gateway_stage='api')
        )

    @property
    def rest_api_id(self):
        return self._deployed_resources.resource_values(
            'rest_api')['rest_api_id']

    def get_json(self, url):
        if not url.startswith('/'):
            url = '/' + url
        response = requests.get(self.url + url)
        response.raise_for_status()
        return response.json()

    def redeploy_once(self):
        # Redeploy the application once.  If a redeploy
        # has already happened, this function is a noop.
        if self._has_redeployed:
            return
        new_file = os.path.join(self.app_dir, 'app-redeploy.py')
        original_app_py = os.path.join(self.app_dir, 'app.py')
        shutil.move(original_app_py, original_app_py + '.bak')
        shutil.copy(new_file, original_app_py)
        self._clear_app_import()
        _deploy_app(self.app_dir)
        self._has_redeployed = True
        # Give it settling time before running more tests.
        time.sleep(self._REDEPLOY_SLEEP)
        self._wait_for_stablize()

    @retry(max_attempts=10, delay=5)
    def _wait_for_stablize(self):
        # After a deployment we sometimes need to wait for
        # API Gateway to propagate all of its changes.
        # We're going to give it num_attempts to give us a
        # 200 response before failing.
        try:
            return self.get_json('/')
        except requests.exceptions.HTTPError:
            pass

    def _clear_app_import(self):
        # Now that we're using `import` instead of `exec` we need
        # to clear out sys.modules in order to pick up the new
        # version of the app we just copied over.
        del sys.modules['app']
コード例 #29
0
ファイル: test_factory.py プロジェクト: jlee2000/Bootcamp3
def no_deployed_values():
    return DeployedResources({'resources': [], 'schema_version': '2.0'})
コード例 #30
0
ファイル: test_features.py プロジェクト: tunks/chalice
class SmokeTestApplication(object):

    # Number of seconds to wait after redeploy before starting
    # to poll for successful 200.
    _REDEPLOY_SLEEP = 20
    # Seconds to wait between poll attempts after redeploy.
    _POLLING_DELAY = 5

    def __init__(self, deployed_values, stage_name, app_name, app_dir, region):
        self._deployed_resources = DeployedResources(deployed_values)
        self.stage_name = stage_name
        self.app_name = app_name
        # The name of the tmpdir where the app is copied.
        self.app_dir = app_dir
        self._has_redeployed = False
        self._region = region

    @property
    def url(self):
        return ("https://{rest_api_id}.execute-api.{region}.amazonaws.com/"
                "{api_gateway_stage}".format(rest_api_id=self.rest_api_id,
                                             region=self._region,
                                             api_gateway_stage='api'))

    @property
    def rest_api_id(self):
        return self._deployed_resources.resource_values(
            'rest_api')['rest_api_id']

    @property
    def websocket_api_id(self):
        return self._deployed_resources.resource_values(
            'websocket_api')['websocket_api_id']

    @property
    def websocket_connect_url(self):
        return ("wss://{websocket_api_id}.execute-api.{region}.amazonaws.com/"
                "{api_gateway_stage}".format(
                    websocket_api_id=self.websocket_api_id,
                    region=self._region,
                    api_gateway_stage='api',
                ))

    def get_json(self, url):
        if not url.startswith('/'):
            url = '/' + url
        response = requests.get(self.url + url)
        response.raise_for_status()
        return response.json()

    def redeploy_once(self):
        # Redeploy the application once.  If a redeploy
        # has already happened, this function is a noop.
        if self._has_redeployed:
            return
        new_file = os.path.join(self.app_dir, 'app-redeploy.py')
        original_app_py = os.path.join(self.app_dir, 'app.py')
        shutil.move(original_app_py, original_app_py + '.bak')
        shutil.copy(new_file, original_app_py)
        _deploy_app(self.app_dir)
        self._has_redeployed = True
        # Give it settling time before running more tests.
        time.sleep(self._REDEPLOY_SLEEP)
        self._wait_for_stablize()

    @retry(max_attempts=10, delay=5)
    def _wait_for_stablize(self):
        # After a deployment we sometimes need to wait for
        # API Gateway to propagate all of its changes.
        # We're going to give it num_attempts to give us a
        # 200 response before failing.
        try:
            return self.get_json('/')
        except requests.exceptions.HTTPError:
            pass
コード例 #31
0
ファイル: test_planner.py プロジェクト: vignesh97/chalice
 def deployed_resources(self, chalice_stage_name):
     return DeployedResources(self._deployed_values)
コード例 #32
0
ファイル: test_config.py プロジェクト: awslabs/chalice
def test_deployed_resource_exists():
    deployed = DeployedResources(
        {'resources': [{'name': 'foo'}]}
    )
    assert deployed.resource_values('foo') == {'name': 'foo'}
    assert deployed.resource_names() == ['foo']
コード例 #33
0
ファイル: test_config.py プロジェクト: awslabs/chalice
def test_deployed_resource_does_not_exist():
    deployed = DeployedResources(
        {'resources': [{'name': 'foo'}]}
    )
    with pytest.raises(ValueError):
        deployed.resource_values('bar')