def test_get_ports(self):
        ports = ['80:80', '443:443', '8001:80001']

        example_service = {'image': 'nginx:1.19', 'ports': ports}

        service = ServiceDeclaration('phillyabc', example_service)
        self.assertEqual(ports, service.get_ports())
    def test_get_update_strategy_returns_declared_value_in_yaml(self):
        example_service = {
            'image': 'nginx:1.19',
            'labels': {
                'org.riotkit.updateStrategy': 'recreate'
            }
        }

        service = ServiceDeclaration('phillyabc', example_service)
        self.assertEqual('recreate', service.get_update_strategy('compose'))
    def test_get_desired_replicas_count_returns_declared_count(self):
        example_service = {
            'image': 'nginx:1.19',
            'labels': {
                'org.riotkit.replicas': '5'
            }
        }

        service = ServiceDeclaration('phillyabc', example_service)
        self.assertEqual(5, service.get_desired_replicas_count())
    def test_watchtower_getter_invalid_value_converts_to_false(self):
        example_service = {
            'image': 'nginx:1.19',
            'labels': {
                'com.centurylinklabs.watchtower.enable': 'INVALID VALUE!'
            }
        }

        service = ServiceDeclaration('anarchist_black_cross_federation',
                                     example_service)
        self.assertFalse(service.is_using_watchtower())
    def test_get_last_container_name_for_service(self):
        drv = self._get_prepared_compose_driver()

        # make sure it is clean up
        drv.rm(ServiceDeclaration('gateway', {}),
               capture=True)  # there may be more instances, so remove them
        drv.up(ServiceDeclaration('gateway', {}),
               capture=True)  # bring one instance

        self.assertEqual('env_simple_gateway_1',
                         drv.get_last_container_name_for_service('gateway'))
    def test_watchtower_getter_true(self):
        example_service = {
            'image': 'nginx:1.19',
            'labels': {
                'com.centurylinklabs.watchtower.enable': 'true'
            }
        }

        service = ServiceDeclaration('anarchist_black_cross_federation',
                                     example_service)
        self.assertTrue(service.is_using_watchtower())
    def test_maintenance_mode_label_name(self):
        example_service = {
            'image': 'nginx:1.19',
            'labels': {
                'org.riotkit.useMaintenanceMode': 'True'
            }
        }

        service = ServiceDeclaration('anarchist_black_cross_federation',
                                     example_service)
        self.assertTrue(service.is_using_maintenance_mode())
    def test_get_created_containers_is_returning_containers_in_proper_order(
            self):
        """Test that get_created_containers() is preserving order"""

        drv = self._get_prepared_compose_driver()

        # create three instances of a service
        drv.up(ServiceDeclaration('website', {}))
        drv.scale_one_up(ServiceDeclaration('website', {}))

        containers = drv.get_created_containers(only_running=False)
        self.assertEqual([1, 2], list(containers['website'].keys()))
    def test_find_all_container_names_for_service_finds_containers(self):
        drv = self.prepare_example_service('website')

        self.assertEqual(['env_simple_website_1'],
                         drv.find_all_container_names_for_service(
                             ServiceDeclaration('website', {})))

        drv.scale_one_up(ServiceDeclaration('website', {}))
        containers = drv.find_all_container_names_for_service(
            ServiceDeclaration('website', {}))

        self.assertIn('env_simple_website_1', containers)
        self.assertIn('env_simple_website_2', containers)
    def test_get_domains(self):
        """Test get_domains() with multiple domains"""

        example_service = {
            'image': 'nginx:1.19',
            'environment': {
                'VIRTUAL_HOST': 'abcf.net,www.abcf.net'
            }
        }

        service = ServiceDeclaration('anarchist_black_cross_federation',
                                     example_service)
        self.assertEqual(['abcf.net', 'www.abcf.net'], service.get_domains())
    def test_find_container_name_does_not_find_instance_when_there_is_not_enough_replicas(
            self):
        drv = self.prepare_example_service('gateway')

        # for single works
        self.assertEqual(
            'env_simple_gateway_1',
            drv.find_container_name(ServiceDeclaration('gateway', {}),
                                    instance_num=1))

        self.assertRaises(
            ServiceNotCreatedException,
            lambda: drv.find_container_name(ServiceDeclaration('gateway', {}),
                                            instance_num=50))
    def test_functional_container_is_healthy_after_few_seconds_using_health_check_invoking_while_container_is_starting(self):
        """Expects that the container will become health within few seconds,
        even if docker daemon is showing 'starting'"""

        drv = self._get_prepared_compose_driver()
        drv.rm(ServiceDeclaration('alpine_3_health_check', {}), capture=True)
        drv.up(ServiceDeclaration('alpine_3_health_check', {}), capture=True)

        out = self.execute_mocked_task_and_get_output(WaitForServiceTask(), args={
            'name': 'alpine_3_health_check',
            '--timeout': 10,
            '--instance': 1
        })

        self.assertIn('Service healthy after', out)
예제 #13
0
    def test_functional_service_is_stopped_and_removed(self):
        """Test that service is stopped and removed, together with two instances

        1. Creates one instance + one replica
        2. Removes service
        3. Expects that two instances were removed
        """

        service = ServiceDeclaration('website', {})

        drv = self._get_prepared_compose_driver()
        drv.rm(service, capture=True)
        drv.up(service, capture=True)
        drv.scale_one_up(service)

        out = self.execute_mocked_task_and_get_output(ServiceRemoveTask(),
                                                      args={
                                                          'name': 'website',
                                                          '--with-image':
                                                          False,
                                                          '--extra-args': ''
                                                      })

        containers = self.get_containers_state(drv)

        for container_name, state in containers.items():
            if container_name.startswith('env_simple_website_'):
                self.fail(
                    'Found %s container, which should be removed by calling :harbor:service:rm'
                )

        self.assertIn('Removing env_simple_website_1', out)
        self.assertIn('Removing env_simple_website_2', out)
    def test_find_container_name_case_service_not_created_raises_exception(
            self):
        drv = self._get_prepared_compose_driver()

        self.assertRaises(
            ServiceNotCreatedException, lambda: drv.find_container_name(
                ServiceDeclaration('not_existing', {})))
    def test_find_container_name_finds_first_instance_when_no_instance_specified(
            self):
        drv = self.prepare_example_service('gateway')

        instance_name = drv.find_container_name(
            ServiceDeclaration('gateway', {}))
        self.assertEqual('env_simple_gateway_1', instance_name)
    def test_get_ports_returned_as_dict(self):
        """
        In newer versions of docker-compose the list of ports is returned as dict ex. {"published": 80, "target": 8000}
        :return:
        """

        service = ServiceDeclaration(
            'phillyabc', {
                'image': 'quay.io/riotkit/infracheck:v2.0',
                'ports': [{
                    'published': 80,
                    'target': 8000
                }]
            })

        self.assertEqual(['80:8000'], service.get_ports())
    def test_wait_for_log_message_finds_searched_phrase(self):
        drv = self.prepare_example_service('gateway')

        requests.get('http://localhost:8000')
        self.assertTrue(
            drv.wait_for_log_message('GET / HTTP/1.1',
                                     ServiceDeclaration('gateway', {}),
                                     timeout=5))
    def test_find_container_name_finds_first_instance_by_specyfing_instance_num(
            self):
        drv = self.prepare_example_service('gateway')

        self.assertEqual(
            'env_simple_gateway_1',
            drv.find_container_name(ServiceDeclaration('gateway', {}),
                                    instance_num=1))
예제 #19
0
    def test_functional_compose_method_is_executed(self):
        """Test that the service is not force-recreated by 'compose' method"""

        drv = self._get_prepared_compose_driver()
        drv.rm(ServiceDeclaration('website', {}), capture=True)
        drv.up(ServiceDeclaration('website', {}), capture=True)

        out = self.execute_mocked_task_and_get_output(
            ServiceUpTask(),
            args={
                'name': 'website',
                '--strategy': 'compose',
                '--remove-previous-images': False,
                '--extra-args': '',
                '--dont-recreate': False
            })

        self.assertIn('env_simple_website_1 is up-to-date', out)
    def test_up_invalid_parameters_for_recreation(self):
        """Unit test: Checks if exception is raised when logic error happens"""

        drv = self._get_prepared_compose_driver()
        drv.scope.sh = lambda *args, **kwargs: ''

        # action
        self.assertRaises(
            Exception, lambda: drv.up(ServiceDeclaration('healthcheck', {}),
                                      norecreate=True,
                                      force_recreate=True))
    def test_get_created_containers_is_showing_only_running_containers(self):
        """Test that 'website' service will be created, but will have no active containers"""

        drv = self._get_prepared_compose_driver()

        # create three instances of a service
        drv.up(ServiceDeclaration('website', {}))
        drv.stop('website')

        containers = drv.get_created_containers(only_running=True)
        self.assertEqual([], list(containers['website']))
    def test_functional_timeout_is_raised(self):
        """Expects that the timeout will be raised, as it is very low in test"""

        drv = self._get_prepared_compose_driver()
        drv.up(ServiceDeclaration('alpine_3_health_check', {}), capture=True)

        out = self.execute_mocked_task_and_get_output(WaitForServiceTask(), args={
            'name': 'alpine_3_health_check',
            '--timeout': 0,
            '--instance': 1
        })

        self.assertIn('Timeout of 0s reached.', out)
    def test_up_tolerates_extra_arguments(self):
        """Unit tests: Checks if extra arguments are allowed to be passed"""

        resulting_args = []
        drv = self._get_prepared_compose_driver()
        drv.scope.sh = lambda *args, **kwargs: (resulting_args.append(args))

        # action
        drv.up(ServiceDeclaration('healthcheck', {}),
               extra_args='--remove-orphans')
        args_as_str = ' '.join(resulting_args[0])

        self.assertIn('--remove-orphans', args_as_str)
    def test_wait_for_log_hits_timeout(self):
        drv = self.prepare_example_service('gateway')

        start_time = time()

        self.assertRaises(
            ServiceNotReadyException, lambda: drv.wait_for_log_message(
                'Some message that should be there',
                ServiceDeclaration('gateway', {}),
                timeout=2))

        self.assertGreaterEqual(time() - start_time,
                                2,
                                msg='Expected at least two seconds waiting')
    def test_functional_service_is_stopped(self):
        """Start service, then try to bring down, leave the images"""
        service = ServiceDeclaration('alpine_3', {})

        drv = self._get_prepared_compose_driver()
        drv.up(service, capture=True)

        self.execute_mocked_task_and_get_output(ServiceStopTask(),
                                                args={
                                                    'name': 'alpine_3',
                                                    '--extra-args': ''
                                                })

        self.assertContainerIsNotRunning('alpine_3', drv)
    def test_scale_one_up_then_scale_down_to_desired_state(self):
        """Functional test: Scale one up, then down to declared state

        Covers:
            scale_one_up()
            scale_to_desired_state()
        """

        drv = self.prepare_example_service('website')
        drv.scale_one_up(ServiceDeclaration('website', {}))

        running_containers = self.get_containers_state(drv)
        self.assertIn('env_simple_website_1', running_containers)
        self.assertIn('env_simple_website_2', running_containers)
예제 #27
0
    def test_functional_service_is_removed_together_with_image(self):
        service = ServiceDeclaration('alpine_3', {})

        drv = self._get_prepared_compose_driver()
        drv.up(service, capture=True)

        self.execute_mocked_task_and_get_output(ServiceRemoveTask(),
                                                args={
                                                    'name': 'alpine_3',
                                                    '--with-image': True,
                                                    '--extra-args': ''
                                                })

        self.assertLocalRegistryHasNoPulledImage('alpine:3.11')
    def test_functional_waits_for_service_without_healthcheck(self):
        """Expect that the task will wait for container to be up, but will not check its health check if healthcheck
        was not defined"""

        drv = self._get_prepared_compose_driver()
        drv.up(ServiceDeclaration('alpine_3', {}), capture=True)
        drv.stop('alpine_3', capture=True)

        out = self.execute_mocked_task_and_get_output(WaitForServiceTask(), args={
            'name': 'alpine_3',
            '--timeout': 1,
            '--instance': 1
        })

        self.assertIn('Instance has no healthcheck defined!', out)
예제 #29
0
    def test_report_shows_declared_and_actual_state_for_simple_service(self):
        service = ServiceDeclaration('alpine_3', {})

        drv = self._get_prepared_compose_driver()
        drv.up(service, capture=True)

        # assert it will not raise an error
        out = self.execute_mocked_task_and_get_output(
            AnalyzeServiceTask(), args={'name': 'alpine_3'})

        self.assertIn('Declared image:    alpine:3.11', out)
        self.assertIn('Update strategy:   compose', out)
        self.assertIn('Replicas:          1 of 1', out)
        self.assertIn('alpine:3.11', out)
        self.assertIn('env_simple_alpine_3_1', out)
    def test_functional_up_and_down(self):
        """Functional test to start, stop, restart, remove container
           Checks basic compatibility with docker-compose interface
        """

        drv = self._get_prepared_compose_driver()

        # 1) Start
        drv.up(ServiceDeclaration('gateway', {}))
        self.assertTrue(self.get_containers_state(drv)['env_simple_gateway_1'])

        # 2) Restart
        drv.restart('gateway')
        self.assertTrue(self.get_containers_state(drv)['env_simple_gateway_1'])

        # 3) Stop
        drv.stop('gateway')
        self.assertFalse(
            self.get_containers_state(drv)['env_simple_gateway_1'])

        # 4) Remove
        drv.rm(ServiceDeclaration('gateway', {}))
        self.assertNotIn('env_simple_gateway_1',
                         self.get_containers_state(drv))