def setUp(self):
     self.pathconfig = Mock()
     self.fs_handler = Mock(pathconfig=self.pathconfig)
     self.fs_handler.copy_dockerfile = Mock()
     self.fs_handler.dockerrun = None
     self.container = PreconfiguredContainer(self.fs_handler, SOLN_STK,
                                             None)
 def setUp(self):
     self.fs_handler = dummy.get_container_fs_handler()
     self.pathconfig = self.fs_handler.pathconfig
     self.cnt = PreconfiguredContainer(fs_handler=self.fs_handler,
                                       soln_stk=Mock(),
                                       container_cfg={},
                                       opt_env=OPT_ENV)
     self.cnt._get_log_volume_map = Mock(return_value=None)
     self.cnt._containerize = Mock(return_value=False)
     self.cnt._require_pull = Mock(return_value=False)
Example #3
0
def make_container(envvars_str=None,
                   host_port=None,
                   allow_insecure_ssl=False,
                   pathconfig=PathConfig):
    """
    Factory function for making a container or multicontainer.
    :param envvars_str: str: key=val str of environment variables
    :param host_port: str: optional host port mapped to container port
    :param allow_insecure_ssl: bool: allow insecure connection to docker registry
    :param pathconfig: PathConfig: Holds path/existence info
    :return Container/MultiContainer
    """

    soln_stk = _determine_platform()
    container_cfg = containerops.get_configuration()
    opt_env = EnvvarCollector.from_str(envvars_str)

    if containerops.is_multi(soln_stk, container_cfg):
        return MultiContainer(
            fs_handler=make_multicontainer_fs_handler(pathconfig),
            opt_env=opt_env,
            allow_insecure_ssl=allow_insecure_ssl,
            soln_stk=soln_stk)

    elif containerops.is_generic(soln_stk, container_cfg):
        return GenericContainer(
            fs_handler=make_container_fs_handler(pathconfig),
            soln_stk=soln_stk,
            container_cfg=container_cfg,
            opt_env=opt_env,
            host_port=host_port)

    elif containerops.is_preconfigured(soln_stk, container_cfg):
        return PreconfiguredContainer(
            fs_handler=make_container_fs_handler(pathconfig),
            soln_stk=soln_stk,
            container_cfg=container_cfg,
            opt_env=opt_env,
            host_port=host_port)

    else:
        raise NotSupportedError(strings['local.unsupported'])
class TestPreconfiguredContainer(TestCase):
    def setUp(self):
        self.pathconfig = Mock()
        self.fs_handler = Mock(pathconfig=self.pathconfig)
        self.fs_handler.copy_dockerfile = Mock()
        self.fs_handler.dockerrun = None
        self.container = PreconfiguredContainer(self.fs_handler, SOLN_STK,
                                                None)

    @patch(
        'ebcli.containers.preconfigured_container._validate_preconfig_dockerfile'
    )
    def test_no_preconfig_dockerfile_check(self,
                                           _validate_preconfig_dockerfile):
        _bypass_preconfig_dockerfile_validation(self.pathconfig)

        try:
            self.container.validate()
        except:
            self.fail('No validation is necessary if no Dockerfile exists')

        self.assertFalse(_validate_preconfig_dockerfile.called)

    @patch(
        'ebcli.containers.preconfigured_container.containerops._get_preconfig_info'
    )
    @patch('ebcli.containers.preconfigured_container.commands._get_base_img')
    def test_validation_pass(self, _get_base_img, _get_preconfig_info):
        _expect_preconfig_dockerfile_validation(self.pathconfig)
        _get_preconfig_info.return_value = {
            containerops.RUNTIME_IMG_KEY: MOCK_IMG
        }
        _get_base_img.return_value = MOCK_IMG

        msg = ('If user provides Dockerfile, then that Dockerfile img must '
               'match runtime img appropriate for the solution stack')

        try:
            self.container.validate()
        except:
            self.fail(msg)

    @patch(
        'ebcli.containers.preconfigured_container.containerops._get_preconfig_info'
    )
    @patch('ebcli.containers.preconfigured_container.commands._get_base_img')
    def test_validation_fail(self, _get_base_img, _get_preconfig_info):
        _expect_preconfig_dockerfile_validation(self.pathconfig)
        _get_preconfig_info.return_value = {
            containerops.RUNTIME_IMG_KEY: MOCK_IMG
        }
        _get_base_img.return_value = None

        self.assertRaises(ValidationError, self.container.validate)

    @patch('ebcli.containers.preconfigured_container.dockerrun')
    def test_validate_dockerrun_v1(self, dockerrun):
        _bypass_preconfig_dockerfile_validation(self.pathconfig)
        self.container.validate()
        dockerrun.validate_dockerrun_v1.assert_called_once_with(
            self.fs_handler.dockerrun, False)

    def test_containerize(self):
        _bypass_preconfig_dockerfile_validation(self.pathconfig)

        self.container._containerize()
        self.fs_handler.copy_dockerfile.assert_called_once_with(
            self.container.soln_stk, self.container.container_cfg)

    @patch(
        'ebcli.containers.preconfigured_container.AbstractContainer._get_log_volume_map'
    )
    def test_get_log_volume_map_exists_from_dockerrun(self,
                                                      _get_container_log_path):
        _bypass_preconfig_dockerfile_validation(self.pathconfig)
        _get_container_log_path.return_value = VOLUME_MAP

        self.assertDictEqual(self.container._get_log_volume_map(), VOLUME_MAP)

    @patch('ebcli.containers.preconfigured_container.log')
    @patch('ebcli.containers.preconfigured_container.containerops')
    @patch(
        'ebcli.containers.preconfigured_container.AbstractContainer._get_log_volume_map'
    )
    def test_get_log_volume_map_exists_by_default_log_path(
            self, _get_container_log_path, containerops, log):
        _bypass_preconfig_dockerfile_validation(self.pathconfig)
        _get_container_log_path.return_value = {}
        log.new_host_log_path.return_value = HOST_LOG_PATH
        containerops.get_runtime_default_log_path.return_value = DEFAULT_LOG_PATH

        expected_volume_map = {HOST_LOG_PATH: DEFAULT_LOG_PATH}

        self.assertDictEqual(expected_volume_map,
                             self.container._get_log_volume_map())
class TestAbstractContainer(TestCase):
    def setUp(self):
        self.fs_handler = dummy.get_container_fs_handler()
        self.pathconfig = self.fs_handler.pathconfig
        self.cnt = PreconfiguredContainer(fs_handler=self.fs_handler,
                                          soln_stk=Mock(),
                                          container_cfg={},
                                          opt_env=OPT_ENV)
        self.cnt._get_log_volume_map = Mock(return_value=None)
        self.cnt._containerize = Mock(return_value=False)
        self.cnt._require_pull = Mock(return_value=False)

    @patch('ebcli.containers.abstractcontainer.commands')
    def test_start_check_new_dockerfie_creation_when_required(self, commands):
        self.fs_handler.require_new_dockerfile.return_value = True
        self.cnt.start()
        self.cnt._containerize.assert_called_once_with()

    @patch('ebcli.containers.abstractcontainer.commands')
    def test_start_check_new_dockerfie_no_creation(self, commands):
        self.fs_handler.require_new_dockerfile.return_value = False
        self.cnt.start()
        self.assertFalse(self.cnt._containerize.called)

    @patch('ebcli.containers.abstractcontainer.commands')
    def test_start_pull_required(self, commands):
        self.cnt._require_pull.return_value = True
        self.pathconfig.dockerfile_exists = lambda: False

        self.cnt.start()
        # We expect image pulled from Dockerfile user provided
        # since we bypassed Dockerfile creation.
        commands.pull_img.assert_called_once_with(dummy.NEW_DOCKERFILE_PATH)

    @patch('ebcli.containers.abstractcontainer.commands')
    def test_start_pull_not_required(self, commands):
        self.cnt.start()
        self.assertFalse(commands.pull_img.called)

    @patch('ebcli.containers.abstractcontainer.commands')
    def test_start_container_rm(self, commands):
        self.cnt.start()
        commands.rm_container.assert_called_once_with(self.cnt.get_name(),
                                                      force=True)

    @patch('ebcli.containers.abstractcontainer.commands')
    def test_start_check_all(self, commands):
        self.pathconfig.dockerfile_exists = lambda: False
        self.fs_handler.require_append_dockerignore.return_value = True
        self.fs_handler.require_new_dockerfile.return_value = True
        self.cnt._require_pull.return_value = True

        commands.build_img.return_value = IMG_ID

        self.cnt.start()

        # Should've appended dockerignore, containerize, pull
        # remove existing container, build, and run

        self.fs_handler.append_dockerignore.assert_called_once_with()
        self.cnt._containerize.assert_called_once_with()

        commands.pull_img.assert_called_once_with(dummy.NEW_DOCKERFILE_PATH)
        commands.build_img.expect_called_once_with(dummy.DOCKER_PROJ_PATH,
                                                   dummy.NEW_DOCKERFILE_PATH)
        commands.rm_container.assert_called_once_with(self.cnt.get_name(),
                                                      force=True)
        commands.run_container.expect_called_once_with(
            dummy.NEW_DOCKERFILE_PATH,
            IMG_ID,
            envvars_map=EXPECTED_ENVVARS_MAP)

    def test_get_name(self):
        self.pathconfig.docker_proj_path = lambda: ''
        # This is the result of sha1('')
        expected_hash = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
        self.assertEqual(expected_hash, self.cnt.get_name())

    @patch('ebcli.containers.abstractcontainer.commands.is_running')
    def test_is_running_true(self, is_running):
        is_running.return_value = True
        self.assertTrue(self.cnt.is_running())

    @patch('ebcli.containers.abstractcontainer.commands.is_running')
    def test_is_running_false(self, is_running):
        is_running.return_value = False
        self.assertFalse(self.cnt.is_running())

    def test_final_envvars(self):
        self.fs_handler.get_setenv_env.return_value = SETENV_ENV
        self.assertDictEqual(EXPECTED_ENVVARS_MAP, self.cnt.final_envvars())