Example #1
0
    def test_check_no_resources(self, *mocks):
        """
        Ensures the profile check fails when no resource constraints are found
        """
        profile = Profile(self.workflow)

        profile.load = mock.Mock()
        profile.load.return_value = get_content('profiles/no_constraints.yml')

        errors = profile._check_services(profile.check_resources, profile.data)

        self.assertRegex(' '.join(errors), r'resource constraints not found')
Example #2
0
    def test_check_with_node_constraints(self, *mocks):
        """
        Ensures the profile check passes when no constraints are found
        """
        profile = Profile(self.workflow)

        profile.load = mock.Mock()
        profile.load.return_value = get_content("profiles/with_node_constraints.yml")

        errors = profile._check_services(profile.check_constraints, profile.data)

        self.assertEqual(0, len(errors))
Example #3
0
    def test_check_resources_empty(self, *mocks):
        """
        Ensures the profile check fails when resources constraints are empty
        """
        profile = Profile(self.workflow)

        profile.load = mock.Mock()
        profile.load.return_value = get_content("profiles/resources_nothing_set.yml")

        errors = profile._check_services(profile.check_resources, profile.data)

        self.assertRegex(" ".join(errors), r"resource constraints not found")
Example #4
0
    def test_check_no_node_constraints(self, *mocks):
        """
        Ensures the profile check fails when `node.` constraints are not found
        """
        profile = Profile(self.workflow)

        profile.load = mock.Mock()
        profile.load.return_value = get_content("profiles/no_node_constraints.yml")

        errors = profile._check_services(profile.check_constraints, profile.data)

        self.assertRegex(" ".join(errors), r"node constraints not found")
Example #5
0
    def test_check_global_mode(self, *mocks):
        """
        Ensures the profile check does not fail when there is no constraint on a global service
        """
        profile = Profile(self.workflow)

        profile.load = mock.Mock()
        profile.load.return_value = get_content("profiles/global_no_constraints.yml")

        errors = profile._check_services(profile.check_constraints, profile.data)

        self.assertEqual(0, len(errors), errors)
Example #6
0
    def test_set_resources_empty_resources_left_alone(self, *mocks):
        """
        Ensures when services.x.deploy doesn't exist it is not added
        """
        content = get_content("profiles/no_constraints.yml")
        data = yaml_load(content)

        service_name, data = list(data["services"].items())[0]

        profile = Profile(self.workflow)

        profile.set_resources(service_name, data)

        self.assertEqual("deploy" not in data, True)
Example #7
0
    def test_checks_called(self, *mocks):
        """
        Ensure constraint checks are called on deploy
        """
        profile_data_mock = mocks[0]
        profile_data_mock.return_value = {
            "services": {
                "app": {
                    "image": "foo:test"
                }
            }
        }
        command = shlex.split("-e dev deploy")
        workflow = Workflow(argv=command)

        workflow.environment.write = mock.Mock()

        # mock out all check methods
        all_checks = Profile.get_all_checks()
        self.assertEqual(3, len(all_checks), all_checks)

        for name in all_checks:
            _check_mock = mock.Mock()
            _check_mock.return_value = []

            setattr(workflow.profile, name, _check_mock)

        workflow.run()

        for name in all_checks:
            _check_mock = getattr(workflow.profile, name)

            self.assertGreater(_check_mock.call_count, 0, f"{name} not called")
Example #8
0
    def test_expand_services(self, *mocks):
        data = {
            "services": {
                "foo": {
                    "build": "..",
                    "image": "${DOCKER_IMAGE}",
                    "environment": [
                        "FOO=1",
                        "SPARK_WORKER_PORT=8888",
                        "SPARK_WORKER_WEBUI_PORT=8080",
                    ],
                    "ports": ["8000:8000"],
                    "deploy": {"replicas": 3},
                }
            },
            "compose_flow": {
                "expand": {
                    "foo": {
                        "increment": {
                            "env": ["SPARK_WORKER_PORT", "SPARK_WORKER_WEBUI_PORT"],
                            "ports": {"source_port": True, "destination_port": True},
                        }
                    }
                }
            },
        }

        profile = Profile(self.workflow)
        new_data = profile._check_cf_config(data)

        self.assertEqual(len(new_data["services"]), 3)

        self.assertEqual(sorted(new_data["services"].keys()), ["foo1", "foo2", "foo3"])

        self.assertEqual(
            [x["ports"] for x in new_data["services"].values()],
            [["8000:8000"], ["8001:8001"], ["8002:8002"]],
        )

        self.assertEqual(
            [x["environment"] for x in new_data["services"].values()],
            [
                ["FOO=1", "SPARK_WORKER_PORT=8888", "SPARK_WORKER_WEBUI_PORT=8080"],
                ["FOO=1", "SPARK_WORKER_PORT=8889", "SPARK_WORKER_WEBUI_PORT=8081"],
                ["FOO=1", "SPARK_WORKER_PORT=8890", "SPARK_WORKER_WEBUI_PORT=8082"],
            ],
        )
Example #9
0
    def test_set_resources_memory_reservation_no_limit(self, *mocks):
        """
        Ensures memory limit is matched to reservation when no limit is given
        """
        merge_profile_mock = mocks[0]
        merge_profile_mock.return_value = get_content(
            'profiles/reservation_no_limit.yml')

        profile = Profile(self.workflow)

        param = {}
        content = profile._compile(
            param)  # the param is ignored because it's using the mock

        merge_profile_mock.assert_called_with(param)

        data = yaml_load(content)
        resources = data['services']['app']['deploy']['resources']

        self.assertEqual(resources['limits']['memory'],
                         resources['reservations']['memory'])
Example #10
0
    def test_set_resources_memory_limit_and_reservation(self, *mocks):
        """
        Ensures memory reservation and limit are left alone when they are both defined
        """
        merge_profile_mock = mocks[0]
        merge_profile_mock.return_value = get_content(
            'profiles/limit_and_reservation.yml')

        profile = Profile(self.workflow)

        param = {}
        content = profile._compile(
            param)  # the param is ignored because it's using the mock

        merge_profile_mock.assert_called_with(param)

        data = yaml_load(content)
        resources = data['services']['app']['deploy']['resources']

        self.assertEqual('10M', resources['reservations']['memory'])
        self.assertEqual('100M', resources['limits']['memory'])
Example #11
0
    def test_profile_writes_once(self, *mocks):
        open_mock = mocks[0]

        profile = Profile(self.workflow)

        profile.load = mock.Mock()
        profile.load.return_value = 'services:'

        profile.write()
        profile.write()
        profile.write()

        self.assertEqual(1, open_mock.call_count)
Example #12
0
    def test_set_resources_memory_limit_no_reservation(self, *mocks):
        """
        Ensures memory reservation is matched to limit when no reservation is given
        """
        merge_profile_mock = mocks[0]
        merge_profile_mock.return_value = get_content(
            "profiles/limit_no_reservation.yml"
        )

        profile = Profile(self.workflow)

        param = {}
        content = profile._compile(
            param
        )  # the param is ignored because it's using the mock

        merge_profile_mock.assert_called_with(param)

        data = yaml_load(content)
        resources = data["services"]["app"]["deploy"]["resources"]

        self.assertEqual(
            resources["reservations"]["memory"], resources["limits"]["memory"]
        )
Example #13
0
    def test_expand_services(self, *mocks):
        data = {
            'services': {
                'foo': {
                    'build':
                    '..',
                    'image':
                    '${DOCKER_IMAGE}',
                    'environment': [
                        'FOO=1',
                        'SPARK_WORKER_PORT=8888',
                        'SPARK_WORKER_WEBUI_PORT=8080',
                    ],
                    'ports': ['8000:8000'],
                    'deploy': {
                        'replicas': 3
                    },
                }
            },
            'compose_flow': {
                'expand': {
                    'foo': {
                        'increment': {
                            'env':
                            ['SPARK_WORKER_PORT', 'SPARK_WORKER_WEBUI_PORT'],
                            'ports': {
                                'source_port': True,
                                'destination_port': True
                            },
                        }
                    }
                }
            },
        }

        profile = Profile(self.workflow)
        new_data = profile._check_cf_config(data)

        self.assertEqual(len(new_data['services']), 3)

        self.assertEqual(sorted(new_data['services'].keys()),
                         ['foo1', 'foo2', 'foo3'])

        self.assertEqual(
            [x['ports'] for x in new_data['services'].values()],
            [['8000:8000'], ['8001:8001'], ['8002:8002']],
        )

        self.assertEqual(
            [x['environment'] for x in new_data['services'].values()],
            [
                [
                    'FOO=1', 'SPARK_WORKER_PORT=8888',
                    'SPARK_WORKER_WEBUI_PORT=8080'
                ],
                [
                    'FOO=1', 'SPARK_WORKER_PORT=8889',
                    'SPARK_WORKER_WEBUI_PORT=8081'
                ],
                [
                    'FOO=1', 'SPARK_WORKER_PORT=8890',
                    'SPARK_WORKER_WEBUI_PORT=8082'
                ],
            ],
        )
Example #14
0
 def test_profile_no_compose_dir(self, *mocks):
     """
     when there is no compose directory, do not attempt to render a profile
     """
     profile = Profile(self.workflow)