def test_should_fetch_groups_with_asg_resource_ids(self, describe_stack):
        described_resources = [resource("AWS::AutoScaling::AutoScalingGroup", 1),
                               resource("AWS::AnyNonASGResource", 2),
                               resource("AWS::AutoScaling::AutoScalingGroup", 4)]
        describe_stack.return_value.describe_resources.return_value = described_resources

        stack_updater = StackUpdater("any-stack-name", "any-aws-region")
        stack_updater.get_all_asgs_from_stack()

        self.asg_conn.return_value.get_all_groups.assert_called_with([1, 4])
Ejemplo n.º 2
0
    def test_should_fetch_groups_with_asg_resource_ids(self, describe_stack):
        described_resources = [
            resource("AWS::AutoScaling::AutoScalingGroup", 1),
            resource("AWS::AnyNonASGResource", 2),
            resource("AWS::AutoScaling::AutoScalingGroup", 4)
        ]
        describe_stack.return_value.describe_resources.return_value = described_resources

        stack_updater = StackUpdater("any-stack-name", "any-aws-region")
        stack_updater.get_all_asgs_from_stack()

        self.asg_conn.return_value.get_all_groups.assert_called_with([1, 4])
Ejemplo n.º 3
0
    def test_should_error_when_describing_stack_yields_nothing(
            self, describe_stack):
        describe_stack.return_value = None

        stack_updater = StackUpdater("any-stack-name", "any-aws-region")

        self.assertRaises(Exception, stack_updater.get_all_asgs_from_stack)
Ejemplo n.º 4
0
def test_no_update():
    def callback(event):
        if event == ASGUpdater.SCALE_OUT_COMPLETED:
            raise Exception("No update --> no scaleout!")

    # action plan
    asg_before = get_asg()
    running_instances_before = count_running_instances(asg_before)
    logger.info("ASG sizing before update: " + sizing_info(asg_before))
    logger.info("Running instances before update: {0}".format(
        running_instances_before))

    # test asg size directly after creation
    assert asg_before.min_size == 1
    "ASG min_size should be equal zu what is configured in teststack.json"
    assert asg_before.max_size == 6
    "ASG max_size should be equal zu what is configured in teststack.json"
    assert asg_before.desired_capacity == 3
    "ASG desired_capacity should be equal zu what is configured in teststack.json"

    StackUpdater(stack_name, region, observer_callback=callback).update_asgs()

    asg_after = get_asg()
    running_instances_after = count_running_instances(asg_after)
    logger.info("ASG sizing after update: " + sizing_info(asg_after))
    logger.info(
        "Running instances after update: {0}".format(running_instances_after))

    assert asg_before.min_size == asg_after.min_size, "ASG min_size shouldn't have changed"
    assert asg_before.max_size == asg_after.max_size, "ASG max_size shouldn't have changed"
    assert asg_before.desired_capacity == asg_after.desired_capacity, "ASG desired_capacity shouldn't have changed"
    assert running_instances_before == running_instances_after, "Number of running instances shouldn't have changed"

    assert len(asg_after.suspended_processes) == 0
Ejemplo n.º 5
0
    def test_get_template_should_error_when_template_file_is_missing(self):
        self.s3_conn.return_value.get_bucket.return_value.get_key.return_value = None

        stack_updater = StackUpdater("any-stack-name", "any-aws-region")

        self.assertRaises(BucketNotAccessibleException,
                          stack_updater._get_template,
                          "s3://any-bucket/any-template.json")
Ejemplo n.º 6
0
def test_update():
    def callback(event):
        if event == ASGUpdater.SCALE_OUT_COMPLETED:
            asg = get_asg()
            print "ASG sizing after scale_out: " + sizing_info(asg)

            #TODO: test more precisely
            assert asg.min_size > asg_before.min_size, "ASG min_size should be bigger than before scale_out"
            assert asg.max_size > asg_before.max_size, "ASG max_size should be bigger than before scale_out"
            assert asg.desired_capacity > asg_before.desired_capacity, \
                "ASG desired_capacity should be bigger than before scale_out"

    # action plan
    asg_before = get_asg()
    logger.info("ASG sizing before update: " + sizing_info(asg_before))

    desired_ami_id = get_next_ami_id(asg_before)

    parameters = {
        "amiID": desired_ami_id,
        "az": az,
        "subnetID": subnet,
        "vpcID": vpc
    }

    update_stack(parameters)

    StackUpdater(stack_name, region, observer_callback=callback).update_asgs()

    logger.info("Waiting 300s to ensure asg is in consistent state...")
    time.sleep(300)
    asg_after = get_asg()
    logger.info("ASG sizing after update: " + sizing_info(asg_after))

    assert asg_before.min_size == asg_after.min_size, "Min size of ASG shouldn't have changed"
    assert asg_before.max_size == asg_after.max_size, "Max size of ASG shouldn't have changed"
    assert asg_before.desired_capacity == asg_after.desired_capacity, "Desired capacity of ASG shouldn't have changed"

    assert len(asg_after.suspended_processes
               ) == 0, "All processes must be resumed after Stackupdater run"

    # terminate instances is async, we need a bit of time to wait here
    # TODO: find something better
    logger.info(
        "Waiting 300s to ensure old instances are terminated before checking consistency..."
    )
    time.sleep(300)

    print logger.info("Found the following instances: " +
                      str(asg_after.instances))
    for instance in asg_after.instances:
        if instance.lifecycle_state in ASGUpdater.RUNNING_LIFECYCLE_STATES:
            logger.info("Found instance: {0} in state: {1}".format(
                instance.instance_id, instance.lifecycle_state))
            assert instance.launch_config_name == asg_after.launch_config_name, \
                "Instance {0} has launch-config {1} but should have {2}".format(instance.instance_id,
                                                                                instance.launch_config_name,
                                                                                asg_after.launch_config_name)
Ejemplo n.º 7
0
    def test_get_template_should_error_when_bucket_is_not_accessible(self):
        self.s3_conn.return_value.get_bucket.side_effect = BotoServerError(
            403, "bang!")

        stack_updater = StackUpdater("any-stack-name", "any-aws-region")

        self.assertRaises(BucketNotAccessibleException,
                          stack_updater._get_template,
                          "s3://any-bucket/any-template.json")
Ejemplo n.º 8
0
def create_stack():
    parameters = {
        "amiID": "ami-748e2903",
        "az": az,
        "subnetID": subnet,
        "vpcID": vpc
    }
    StackUpdater(stack_name,
                 region).update_stack(parameters,
                                      "../resources/teststack.json")
Ejemplo n.º 9
0
    def test_get_template_should_return_template_from_s3(self):
        template_contents = "this is no json"
        get_key = self.s3_conn.return_value.get_bucket.return_value.get_key
        get_key.return_value.get_contents_as_string.return_value = template_contents

        result = StackUpdater("any-stack-name",
                              "any-aws-region")._get_template(
                                  "s3://any-bucket/any-template.json")

        self.s3_conn.return_value.get_bucket.assert_called_with("any-bucket")
        get_key.assert_called_with("any-template.json")

        self.assertEqual(result, template_contents)
Ejemplo n.º 10
0
    def test_get_template_should_return_valid_template_from_filesystem(
            self, open):
        template_contents = "this is no json"
        open.return_value.__enter__.return_value.readlines.return_value = [
            template_contents
        ]
        file_name = "/any-dir/any-template.json"

        result = StackUpdater("any-stack-name",
                              "any-aws-region")._get_template(file_name)

        open.assert_called_with(file_name)

        self.assertEqual(result, template_contents)
Ejemplo n.º 11
0
    def test_update_without_template(self, describe_stack,
                                     wait_for_action_to_complete, get_template,
                                     do_update_or_create):
        stack_name = "any-stack-name"
        describe_stack.return_value.parameters.return_value = []
        get_template.return_value = "json"

        StackUpdater(stack_name, "any-aws-region").update_stack({})

        get_template.assert_called_with(describe_stack.return_value)
        do_update_or_create.assert_called_with(
            self.cfn_conn.return_value.update_stack, "json", {})
        wait_for_action_to_complete.assert_called_with(
            self.cfn_conn.return_value, stack_name, ANY, ANY, ANY)
Ejemplo n.º 12
0
    def test_create_stack(self, describe_stack, wait_for_action_to_complete,
                          get_template, do_update_or_create):
        template = "my-template.json"
        describe_stack.return_value = None
        get_template.return_value = "json"
        stack_name = "any-stack-name"

        StackUpdater(stack_name,
                     "any-aws-region").update_stack([],
                                                    template_filename=template)

        get_template.assert_called_with(template)
        do_update_or_create.assert_called_with(
            self.cfn_conn.return_value.create_stack, "json", [])
        wait_for_action_to_complete.assert_called_with(
            self.cfn_conn.return_value, stack_name, ANY, ANY, ANY)
Ejemplo n.º 13
0
    def test_update_with_template_and_updated_parameters(
            self, describe_stack, wait_for_action_to_complete, get_template,
            do_update_or_create):
        template = "my-template.json"
        describe_stack.return_value.parameters = [
            parameter("amiId", "xyz"),
            parameter("vpcId", "13")
        ]
        get_template.return_value = "json"

        StackUpdater("any-stack-name",
                     "any-aws-region").update_stack({"amiId": "123"},
                                                    template_filename=template)

        get_template.assert_called_with(template)
        do_update_or_create.assert_called_with(
            self.cfn_conn.return_value.update_stack, "json", {
                "amiId": "123",
                "vpcId": "13"
            })
        wait_for_action_to_complete.assert_called_with(
            self.cfn_conn.return_value, "any-stack-name", ANY, ANY, ANY)
Ejemplo n.º 14
0
def update_stack(parameters):
    StackUpdater(stack_name, region).update_stack(parameters)