def test_new_autoscaler(self, deployer, post, app_spec, owner_references):
        app_spec = app_spec._replace(
            autoscaler=AutoscalerSpec(enabled=True,
                                      min_replicas=2,
                                      max_replicas=4,
                                      cpu_threshold_percentage=50))
        app_spec = app_spec._replace(resources=ResourcesSpec(
            limits=[], requests=ResourceRequirementSpec(cpu=1, memory=1)))

        expected_autoscaler = {
            'metadata': pytest.helpers.create_metadata('testapp',
                                                       labels=LABELS),
            'spec': {
                "scaleTargetRef": {
                    "kind": "Deployment",
                    "name": "testapp",
                    "apiVersion": "apps/v1"
                },
                "minReplicas": 2,
                "maxReplicas": 4,
                "targetCPUUtilizationPercentage": 50
            },
        }
        mock_response = create_autospec(Response)
        mock_response.json.return_value = expected_autoscaler
        post.return_value = mock_response

        deployer.deploy(app_spec, LABELS)

        pytest.helpers.assert_any_call(post, AUTOSCALER_API,
                                       expected_autoscaler)
        owner_references.apply.assert_called_once_with(
            TypeMatcher(HorizontalPodAutoscaler), app_spec)
def test_autoscaler_enabled_and_1_replica_gives_no_autoscaler(app_spec):
    app_spec = app_spec._replace(
        autoscaler=AutoscalerSpec(enabled=True,
                                  min_replicas=1,
                                  max_replicas=1,
                                  cpu_threshold_percentage=50))
    assert should_have_autoscaler(app_spec) is False
Beispiel #3
0
def app_spec(**kwargs):
    default_app_spec = AppSpec(
        uid="c1f34517-6f54-11ea-8eaf-0ad3d9992c8c",
        name="testapp",
        namespace="default",
        image="finntech/testimage:version",
        autoscaler=AutoscalerSpec(enabled=False, min_replicas=2, max_replicas=3, cpu_threshold_percentage=50),
        resources=ResourcesSpec(requests=ResourceRequirementSpec(cpu=None, memory=None),
                                limits=ResourceRequirementSpec(cpu=None, memory=None)),
        admin_access=False,
        secrets_in_environment=False,
        prometheus=PrometheusSpec(enabled=True, port='http', path='/internal-backstage/prometheus'),
        datadog=DatadogSpec(enabled=False, tags={}),
        ports=[
            PortSpec(protocol="http", name="http", port=80, target_port=8080),
        ],
        health_checks=HealthCheckSpec(
            liveness=CheckSpec(tcp=TcpCheckSpec(port=8080), http=None, execute=None, initial_delay_seconds=10,
                               period_seconds=10, success_threshold=1, failure_threshold=3, timeout_seconds=1),
            readiness=CheckSpec(http=HttpCheckSpec(path="/", port=8080, http_headers={}), tcp=None, execute=None,
                                initial_delay_seconds=10, period_seconds=10, success_threshold=1,
                                failure_threshold=3, timeout_seconds=1)),
        teams=[u'foo'],
        tags=[u'bar'],
        deployment_id="test_app_deployment_id",
        labels=LabelAndAnnotationSpec({}, {}, {}, {}, {}, {}),
        annotations=LabelAndAnnotationSpec({}, {}, ANNOTATIONS.copy(), {}, {}, {}),
        ingresses=[IngressItemSpec(host=None, pathmappings=[IngressPathMappingSpec(path="/", port=80)], annotations={})],
        strongbox=StrongboxSpec(enabled=False, iam_role=None, aws_region="eu-west-1", groups=None),
        singleton=False,
        ingress_tls=IngressTlsSpec(enabled=False, certificate_issuer=None),
        secrets=[]
    )

    return default_app_spec._replace(**kwargs)
    def test_new_autoscaler_with_custom_labels_and_annotations(self, deployer, post, app_spec):
        app_spec = app_spec._replace(
            autoscaler=AutoscalerSpec(enabled=True, min_replicas=2, cpu_threshold_percentage=50))
        app_spec = app_spec._replace(replicas=4)
        app_spec = app_spec._replace(
            resources=ResourcesSpec(limits=[], requests=ResourceRequirementSpec(cpu=1, memory=1)))
        labels = LabelAndAnnotationSpec(deployment={}, horizontal_pod_autoscaler={"custom": "label"}, ingress={},
                                        service={}, pod={}, status={})
        annotations = LabelAndAnnotationSpec(deployment={}, horizontal_pod_autoscaler={"custom": "annotation"},
                                             ingress={}, service={}, pod={}, status={})
        app_spec = app_spec._replace(labels=labels, annotations=annotations)

        expected_autoscaler = {
            'metadata': pytest.helpers.create_metadata('testapp', labels={"autoscaler_deployer": "pass through",
                                                                          "custom": "label"},
                                                       annotations={"custom": "annotation"}),
            'spec': {
                "scaleTargetRef": {
                    "kind": "Deployment",
                    "name": "testapp",
                    "apiVersion": "extensions/v1beta1"
                },
                "minReplicas": 2,
                "maxReplicas": 4,
                "targetCPUUtilizationPercentage": 50
            }
        }
        mock_response = create_autospec(Response)
        mock_response.json.return_value = expected_autoscaler
        post.return_value = mock_response

        deployer.deploy(app_spec, LABELS)

        pytest.helpers.assert_any_call(post, AUTOSCALER_API, expected_autoscaler)
def test_autoscaler_enabled_and_2_replica_and__requested_cpu_gives_autoscaler(
        app_spec):
    app_spec = app_spec._replace(autoscaler=AutoscalerSpec(
        enabled=True, min_replicas=2, cpu_threshold_percentage=50))
    app_spec = app_spec._replace(replicas=2)
    app_spec = app_spec._replace(resources=ResourcesSpec(
        limits=[], requests=ResourceRequirementSpec(cpu=1, memory=1)))

    assert should_have_autoscaler(app_spec)
import mock
import pytest
from k8s import config
from k8s.client import NotFound

from fiaas_deploy_daemon.specs.models import AppSpec, \
    ResourceRequirementSpec, ResourcesSpec, PrometheusSpec, DatadogSpec, \
    PortSpec, CheckSpec, HttpCheckSpec, TcpCheckSpec, HealthCheckSpec, \
    AutoscalerSpec, ExecCheckSpec, LabelAndAnnotationSpec, \
    IngressItemSpec, IngressPathMappingSpec, StrongboxSpec, IngressTlsSpec
from minikube import MinikubeInstaller, MinikubeError
from minikube.drivers import MinikubeDriverError

PROMETHEUS_SPEC = PrometheusSpec(enabled=True, port='http', path='/internal-backstage/prometheus')
DATADOG_SPEC = DatadogSpec(enabled=False, tags={})
AUTOSCALER_SPEC = AutoscalerSpec(enabled=False, min_replicas=2, cpu_threshold_percentage=50)
EMPTY_RESOURCE_SPEC = ResourcesSpec(requests=ResourceRequirementSpec(cpu=None, memory=None),
                                    limits=ResourceRequirementSpec(cpu=None, memory=None))


# App specs

@pytest.fixture
def app_spec():
    return AppSpec(
        name="testapp",
        namespace="default",
        image="finntech/testimage:version",
        replicas=3,
        autoscaler=AUTOSCALER_SPEC,
        resources=EMPTY_RESOURCE_SPEC,
    def test_replicas_when_autoscaler_enabled(self, previous_replicas,
                                              max_replicas, min_replicas,
                                              cpu_request, expected_replicas,
                                              config, app_spec, get, put, post,
                                              datadog, prometheus, secrets):
        deployer = DeploymentDeployer(config, datadog, prometheus, secrets)

        image = "finntech/testimage:version2"
        version = "version2"
        app_spec = app_spec._replace(replicas=max_replicas,
                                     autoscaler=AutoscalerSpec(
                                         enabled=True,
                                         min_replicas=min_replicas,
                                         cpu_threshold_percentage=50),
                                     image=image)
        if cpu_request:
            app_spec = app_spec._replace(resources=ResourcesSpec(
                requests=ResourceRequirementSpec(cpu=cpu_request, memory=None),
                limits=ResourceRequirementSpec(cpu=None, memory=None)))

        expected_volumes = _get_expected_volumes(app_spec)
        expected_volume_mounts = _get_expected_volume_mounts(app_spec)

        mock_response = create_autospec(Response)
        mock_response.json.return_value = {
            'metadata': pytest.helpers.create_metadata('testapp',
                                                       labels=LABELS),
            'spec': {
                'selector': {
                    'matchLabels': SELECTOR
                },
                'template': {
                    'spec': {
                        'dnsPolicy':
                        'ClusterFirst',
                        'automountServiceAccountToken':
                        False,
                        'serviceAccountName':
                        'default',
                        'terminationGracePeriodSeconds':
                        31,
                        'restartPolicy':
                        'Always',
                        'volumes':
                        expected_volumes,
                        'imagePullSecrets': [],
                        'strategy': {
                            'type': 'rollingUpdate',
                            'rollingUpdate': {
                                'maxSurge': '25%',
                                'maxUnavailable': 0
                            },
                        },
                        'containers': [{
                            'livenessProbe': {
                                'initialDelaySeconds': 10,
                                'periodSeconds': 10,
                                'successThreshold': 1,
                                'failureThreshold': 3,
                                'timeoutSeconds': 1,
                                'tcpSocket': {
                                    'port': 8080
                                }
                            },
                            'name':
                            'testapp',
                            'image':
                            'finntech/testimage:version',
                            'volumeMounts':
                            expected_volume_mounts,
                            'command': [],
                            'env':
                            create_environment_variables(
                                config.infrastructure,
                                global_env=config.global_env,
                                environment=config.environment),
                            'envFrom': [{
                                'configMapRef': {
                                    'name': app_spec.name,
                                    'optional': True,
                                }
                            }],
                            'imagePullPolicy':
                            'IfNotPresent',
                            'readinessProbe': {
                                'initialDelaySeconds': 10,
                                'periodSeconds': 10,
                                'successThreshold': 1,
                                'failureThreshold': 3,
                                'timeoutSeconds': 1,
                                'httpGet': {
                                    'path': '/',
                                    'scheme': 'HTTP',
                                    'port': 8080,
                                    'httpHeaders': []
                                }
                            },
                            'ports': [{
                                'protocol': 'TCP',
                                'containerPort': 8080,
                                'name': 'http'
                            }],
                            'resources': {}
                        }]
                    },
                    'metadata':
                    pytest.helpers.create_metadata('testapp', labels=LABELS)
                },
                'replicas': previous_replicas,
                'revisionHistoryLimit': 5
            }
        }
        get.side_effect = None
        get.return_value = mock_response

        expected_deployment = create_expected_deployment(
            config,
            app_spec,
            image=image,
            version=version,
            replicas=expected_replicas)
        put_mock_response = create_autospec(Response)
        put_mock_response.json.return_value = expected_deployment
        put.side_effect = None
        put.return_value = put_mock_response

        deployer.deploy(app_spec, SELECTOR, LABELS, False)

        pytest.helpers.assert_no_calls(post)
        pytest.helpers.assert_any_call(put, DEPLOYMENTS_URI + "testapp",
                                       expected_deployment)
        datadog.apply.assert_called_once_with(DeploymentMatcher(), app_spec,
                                              False)
        prometheus.apply.assert_called_once_with(DeploymentMatcher(), app_spec)
        secrets.apply.assert_called_once_with(DeploymentMatcher(), app_spec)