def test_autoscale_marathon_instance_aborts_when_task_deploying():
    fake_marathon_service_config = marathon_tools.MarathonServiceConfig(
        service='fake-service',
        instance='fake-instance',
        cluster='fake-cluster',
        config_dict={'min_instances': 1, 'max_instances': 10},
        branch_dict={},
    )
    with contextlib.nested(
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.set_instances_for_marathon_service',
                   autospec=True),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.get_service_metrics_provider', autospec=True),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.get_decision_policy', autospec=True,
                   return_value=mock.Mock(return_value=1)),
        mock.patch.object(marathon_tools.MarathonServiceConfig, 'get_instances', autospec=True, return_value=500),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib._log', autospec=True),
    ) as (
        mock_set_instances_for_marathon_service,
        _,
        _,
        _,
        _,
    ):
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config, [mock.Mock()], [mock.Mock()])
        assert not mock_set_instances_for_marathon_service.called
Example #2
0
def test_autoscale_marathon_instance_aborts_when_task_deploying():
    fake_marathon_service_config = marathon_tools.MarathonServiceConfig(
        service='fake-service',
        instance='fake-instance',
        cluster='fake-cluster',
        config_dict={'min_instances': 1, 'max_instances': 10},
        branch_dict={},
    )
    with contextlib.nested(
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.set_instances_for_marathon_service',
                   autospec=True),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.get_service_metrics_provider', autospec=True),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.get_decision_policy', autospec=True,
                   return_value=mock.Mock(return_value=1)),
        mock.patch.object(marathon_tools.MarathonServiceConfig, 'get_instances', autospec=True, return_value=500),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib._log', autospec=True),
    ) as (
        mock_set_instances_for_marathon_service,
        _,
        _,
        _,
        _,
    ):
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config, [mock.Mock()], [mock.Mock()])
        assert not mock_set_instances_for_marathon_service.called
Example #3
0
def test_autoscale_marathon_with_http_stuff():
    fake_marathon_service_config = marathon_tools.MarathonServiceConfig(
        service='fake-service',
        instance='fake-instance',
        cluster='fake-cluster',
        config_dict={'min_instances': 1, 'max_instances': 10, 'autoscaling':
                     {
                         'decision_policy': 'pid',
                         'metrics_provider': 'http',
                         'endpoint': '/bogus',
                     },
                     },
        branch_dict={},
    )
    with contextlib.nested(
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.set_instances_for_marathon_service',
                   autospec=True),
        mock.patch.object(marathon_tools.MarathonServiceConfig, 'get_instances', autospec=True, return_value=1),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib._log', autospec=True),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.get_http_utilization_for_all_tasks',
                   autospec=True),
        mock.patch('paasta_tools.autoscaling.autoscaling_service_lib.get_decision_policy', autospec=True,
                   return_value=mock.Mock(return_value=1)),
    ) as (
        mock_set_instances_for_marathon_service,
        _,
        _,
        mock_get_http_utilization_for_all_tasks,
        _,
    ):
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config, [mock.Mock()], [mock.Mock()])
        mock_set_instances_for_marathon_service.assert_called_once_with(
            service='fake-service', instance='fake-instance', instance_count=2)
        assert mock_get_http_utilization_for_all_tasks.called
Example #4
0
def test_autoscale_marathon_instance_drastic_downscaling():
    current_instances = 100
    fake_marathon_service_config = marathon_tools.MarathonServiceConfig(
        service='fake-service',
        instance='fake-instance',
        cluster='fake-cluster',
        config_dict={'min_instances': 5, 'max_instances': 100},
        branch_dict={},
    )
    with mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.set_instances_for_marathon_service',
        autospec=True,
    ) as mock_set_instances_for_marathon_service, mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.get_service_metrics_provider', autospec=True,
        **{'return_value.return_value': 0}
    ), mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.get_decision_policy', autospec=True,
        return_value=mock.Mock(return_value=-50),
    ), mock.patch.object(
        marathon_tools.MarathonServiceConfig,
        'get_instances',
        autospec=True,
        return_value=current_instances,
    ), mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib._log', autospec=True,
    ):
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [mock.Mock() for i in range(current_instances)],
                                                            [mock.Mock()])
        mock_set_instances_for_marathon_service.assert_called_once_with(
            service='fake-service', instance='fake-instance', instance_count=int(current_instances * 0.7))
Example #5
0
def test_autoscale_marathon_instance_up_to_min_instances():
    current_instances = 5
    fake_marathon_service_config = marathon_tools.MarathonServiceConfig(
        service='fake-service',
        instance='fake-instance',
        cluster='fake-cluster',
        config_dict={'min_instances': 10, 'max_instances': 100},
        branch_dict={},
    )
    with mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.set_instances_for_marathon_service',
        autospec=True,
    ) as mock_set_instances_for_marathon_service, mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.get_service_metrics_provider', autospec=True,
        **{'return_value.return_value': 0}
    ), mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.get_decision_policy', autospec=True,
        return_value=mock.Mock(return_value=-3),
    ), mock.patch.object(
        marathon_tools.MarathonServiceConfig,
        'get_instances',
        autospec=True,
        return_value=current_instances,
    ), mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib._log', autospec=True,
    ):
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [mock.Mock()] * 5,
                                                            [mock.Mock()] * 5)
        mock_set_instances_for_marathon_service.assert_called_once_with(
            service='fake-service', instance='fake-instance', instance_count=10)

        # even if we don't find the tasks healthy in marathon we shouldn't be below min_instances
        mock_set_instances_for_marathon_service.reset_mock()
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [mock.Mock()] * (int(5 * (1 - MAX_TASK_DELTA)) - 1),
                                                            [mock.Mock()] * (int(5 * (1 - MAX_TASK_DELTA)) - 1))
        mock_set_instances_for_marathon_service.assert_called_once_with(
            service='fake-service', instance='fake-instance', instance_count=10)
Example #6
0
def test_autoscale_marathon_instance_aborts_when_wrong_number_tasks():
    fake_marathon_service_config = marathon_tools.MarathonServiceConfig(
        service='fake-service',
        instance='fake-instance',
        cluster='fake-cluster',
        config_dict={'min_instances': 1, 'max_instances': 100},
        branch_dict={},
    )
    with mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.set_instances_for_marathon_service',
        autospec=True,
    ) as mock_set_instances_for_marathon_service, mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.get_service_metrics_provider', autospec=True,
        **{'return_value.return_value': 0.0}
    ), mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib.get_decision_policy', autospec=True,
        return_value=mock.Mock(return_value=1),
    ), mock.patch.object(
        marathon_tools.MarathonServiceConfig, 'get_instances', autospec=True,
    ) as mock_get_instances, mock.patch(
        'paasta_tools.autoscaling.autoscaling_service_lib._log', autospec=True,
    ):
        # Test all running
        mock_set_instances_for_marathon_service.reset_mock()
        mock_get_instances.return_value = 10
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [mock.Mock()] * 10,
                                                            [mock.Mock()] * 10)
        assert mock_set_instances_for_marathon_service.called

        # Test none running
        mock_set_instances_for_marathon_service.reset_mock()
        mock_get_instances.return_value = 10
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [], [])
        assert not mock_set_instances_for_marathon_service.called

        # Test more instances above threshold
        mock_set_instances_for_marathon_service.reset_mock()
        mock_get_instances.return_value = 10
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [mock.Mock()] * (int(10 * (1 + MAX_TASK_DELTA)) + 1),
                                                            [mock.Mock()] * (int(10 * (1 + MAX_TASK_DELTA)) + 1))
        assert not mock_set_instances_for_marathon_service.called

        # Test more instances below threshold
        mock_set_instances_for_marathon_service.reset_mock()
        mock_get_instances.return_value = 10
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [mock.Mock()] * (int(10 * (1 + MAX_TASK_DELTA)) - 1),
                                                            [mock.Mock()] * (int(10 * (1 + MAX_TASK_DELTA)) - 1))
        assert mock_set_instances_for_marathon_service.called

        # Test fewer below threshold
        mock_set_instances_for_marathon_service.reset_mock()
        mock_get_instances.return_value = 10
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [mock.Mock()] * (int(10 * (1 - MAX_TASK_DELTA)) - 1),
                                                            [mock.Mock()] * (int(10 * (1 - MAX_TASK_DELTA)) - 1))
        assert not mock_set_instances_for_marathon_service.called

        # Test fewer above threshold
        mock_set_instances_for_marathon_service.reset_mock()
        mock_get_instances.return_value = 10
        autoscaling_service_lib.autoscale_marathon_instance(fake_marathon_service_config,
                                                            [mock.Mock()] * (int(10 * (1 - MAX_TASK_DELTA)) + 1),
                                                            [mock.Mock()] * (int(10 * (1 - MAX_TASK_DELTA)) + 1))
        assert mock_set_instances_for_marathon_service.called