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
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)