import os
import grp
import stat
import shutil
import pytest
import hashlib
from collections import OrderedDict
from calculate.templates.template_processor import TemplateExecutor, DIR,\
                                                   FILE, CalculateConfigFile,\
                                                   TemplateExecutorError,\
                                                   TemplateWrapper
from calculate.templates.template_engine import ParametersContainer
from calculate.utils.package import PackageAtomName, Version, Package
from calculate.utils.files import join_paths


CHROOT_PATH = os.path.join(os.getcwd(),
                           'tests/templates/testfiles/test_executor_root')
CONFIG_PATH = os.path.join(CHROOT_PATH, 'var/lib/calculate/config')
CONFIG_ARCHIVE_PATH = os.path.join(CHROOT_PATH,
                                   'var/lib/calculate/config-archive')
EXECUTE_ARCHIVE_PATH = os.path.join(CHROOT_PATH,
                                    'var/lib/calculate/.execute')


template_executor = TemplateExecutor(chroot_path=CHROOT_PATH,
                                     cl_config_archive=CONFIG_ARCHIVE_PATH,
                                     cl_config_path=CONFIG_PATH,
                                     execute_archive_path=EXECUTE_ARCHIVE_PATH)

test_package_name = PackageAtomName(
                        {'pkg_path': os.path.join(
                                  CHROOT_PATH,
                                  'var/db/pkg/test-category/test-package-1.0'),
                         'version': Version('1.0')})

other_package_name = PackageAtomName(
                        {'pkg_path': os.path.join(
                                 CHROOT_PATH,
                                 'var/db/pkg/test-category/other-package-1.1'),
                         'version': Version('1.1')})


@pytest.mark.template_executor
class TestTemplateExecutor:
    def test_function_to_copy_testfiles(self):
        TemplateWrapper._protected_is_set = False
        shutil.copytree(os.path.join(CHROOT_PATH, 'etc.backup'),
                        os.path.join(CHROOT_PATH, 'etc'),
                        symlinks=True)
        shutil.copytree(os.path.join(CHROOT_PATH, 'unprotected.backup'),
                        os.path.join(CHROOT_PATH, 'unprotected'),
                        symlinks=True)
        shutil.copytree(os.path.join(
                                 CHROOT_PATH,
                                 'var/lib/calculate/config-archive.backup'),
                        os.path.join(CHROOT_PATH,
                                     'var/lib/calculate/config-archive'),
                        symlinks=True)

    # Сначала протестируем класс для работы с /var/lib/calculate/config файлом.
    def test_if_config_file_does_not_exist__a_CalculateConfigFile_object_will_create_one_while_its_initialization(self):
        temporary_chroot = join_paths(
                         os.getcwd(),
                         'tests/templates/testfiles/test_config_root_1')
        temporary_config_path = join_paths(temporary_chroot,
                                           'var/lib/calculate/config')
        calculate_config_file = CalculateConfigFile(
                                          cl_config_path=temporary_config_path,
                                          cl_chroot_path=temporary_chroot)
        assert os.path.exists(calculate_config_file.cl_config_path)

        os.remove(calculate_config_file.cl_config_path)

    def test_if_config_directory_is_on_the_config_path_instead_of_config_file__a_CalculateConfigFile_object_throws_TemplateExecutorError_exception(self):
        temporary_chroot = join_paths(
                                os.getcwd(),
                                'tests/templates/testfiles/test_config_root_2')
        temporary_config_path = join_paths(temporary_chroot,
                                           'var/lib/calculate/config')

        with pytest.raises(TemplateExecutorError):
            calculate_config_file = CalculateConfigFile(
                                          cl_config_path=temporary_config_path,
                                          cl_chroot_path=temporary_chroot)
            calculate_config_file.save_changes()

    def test_if_a_CalculateConfigFile_object_is_initialized__the_object_can_be_used_for_setting_hash_sum_for_the_any_file(self):
        calculate_config_file = CalculateConfigFile(
                                                 cl_config_path=CONFIG_PATH,
                                                 cl_chroot_path=CHROOT_PATH)
        md5_value = hashlib.md5(open(join_paths(
                                               CHROOT_PATH,
                                               '/etc/config_testfiles/file_0'),
                                     'r').read().encode()).hexdigest()
        calculate_config_file.set_files_md5('/etc/config_testfiles/file_0',
                                            md5_value)
        assert '/etc/config_testfiles/file_0' in calculate_config_file
        assert calculate_config_file._config_dictionary[
                                   '/etc/config_testfiles/file_0'] == md5_value

    def test_if_a_CalculateConfigFile_object_is_initialized__the_object_can_be_used_for_removing_any_file_from_config_file(self):
        calculate_config_file = CalculateConfigFile(
                                                 cl_config_path=CONFIG_PATH,
                                                 cl_chroot_path=CHROOT_PATH)
        md5_value = hashlib.md5(open(join_paths(
                                               CHROOT_PATH,
                                               '/etc/config_testfiles/file_1'),
                                     'r').read().encode()).hexdigest()
        calculate_config_file.set_files_md5('/etc/config_testfiles/file_1',
                                            md5_value)
        assert '/etc/config_testfiles/file_1' in calculate_config_file

        calculate_config_file.remove_file('/etc/config_testfiles/file_1')
        assert '/etc/config_testfiles/file_1' not in calculate_config_file

    def test_if_a_CalculateConfigFile_object_contains_file_with_its_hash_and_the_hash_compared_with_equal_hash__the_compare_md5_method_returns_True(self):
        calculate_config_file = CalculateConfigFile(
                                                 cl_config_path=CONFIG_PATH,
                                                 cl_chroot_path=CHROOT_PATH)
        md5_value = hashlib.md5(open(join_paths(
                                               CHROOT_PATH,
                                               '/etc/config_testfiles/file_2'),
                                     'r').read().encode()).hexdigest()
        calculate_config_file.set_files_md5('/etc/config_testfiles/file_2',
                                            md5_value)

        assert calculate_config_file.compare_md5(
                                     '/etc/config_testfiles/file_2', md5_value)

    def test_if_a_CalculateConfigFile_object_contains_file_with_its_hash_and_the_hash_compared_with_not_equal_hash__the_compare_md5_method_returns_False(self):
        calculate_config_file = CalculateConfigFile(
                                                 cl_config_path=CONFIG_PATH,
                                                 cl_chroot_path=CHROOT_PATH)
        md5_value_1 = hashlib.md5(open(join_paths(
                                               CHROOT_PATH,
                                               '/etc/config_testfiles/file_3'),
                                       'r').read().encode()).hexdigest()
        calculate_config_file.set_files_md5('/etc/config_testfiles/file_3',
                                            md5_value_1)

        if os.path.exists(join_paths(CHROOT_PATH,
                                     '/etc/config_testfiles/file_4')):
            print('File exists')
        else:
            print('File does not exist')
        md5_value_2 = hashlib.md5(open(join_paths(
                                            CHROOT_PATH,
                                            '/etc/config_testfiles/file_4'),
                                       'r').read().encode()).hexdigest()
        assert not calculate_config_file.compare_md5(
                                   '/etc/config_testfiles/file_3', md5_value_2)

    def test_if_a_CalculateConfigFile_object_is_used_for_comparing_a_hash_with_a_hash_of_a_file_that_is_not_in_the_config_file__the_compare_md5_method_returns_False(self):
        calculate_config_file = CalculateConfigFile(
                                                 cl_config_path=CONFIG_PATH,
                                                 cl_chroot_path=CHROOT_PATH)
        md5_value = hashlib.md5(open(join_paths(
                                               CHROOT_PATH,
                                               '/etc/config_testfiles/file_5'),
                                     'r').read().encode()).hexdigest()

        assert not calculate_config_file.compare_md5(
                                     '/etc/config_testfiles/file_5', md5_value)

    def test_if_a_CalculateConfigFile_object_was_used_to_make_changes_in_the_config_file__the_save_changes_method_will_save_the_changes(self):
        temporary_chroot = join_paths(
                         os.getcwd(),
                         'tests/templates/testfiles/test_config_root_1')
        temporary_config_path = join_paths(temporary_chroot,
                                           'var/lib/calculate/config')
        calculate_config_file = CalculateConfigFile(
                                          cl_config_path=temporary_config_path,
                                          cl_chroot_path=temporary_chroot)

        md5_value_1 = hashlib.md5(open(join_paths(temporary_chroot,
                                                  '/etc/file'),
                                       'r').read().encode()).hexdigest()
        calculate_config_file.set_files_md5('/etc/file', md5_value_1)

        md5_value_2 = hashlib.md5(open(join_paths(temporary_chroot,
                                                  '/etc/dir/file.conf'),
                                       'r').read().encode()).hexdigest()
        calculate_config_file.set_files_md5('/etc/dir/file.conf', md5_value_2)
        calculate_config_file.save_changes()

        output_text = '/etc/file {}\n/etc/dir/file.conf {}\n'.format(
                                                                   md5_value_1,
                                                                   md5_value_2)
        assert open(temporary_config_path, 'r').read() == output_text
        os.remove(calculate_config_file.cl_config_path)

    # Тестируем исполнительный модуль.
    # Тестируем сначала кое-какие вспомогательные методы.
    def test_if_a_TemplateExecutor_object_is_initialized__the_object_can_return_the_set_of_the_supported_values_of_the_append_parameter(self):
        template_executor = TemplateExecutor(
                                  chroot_path=CHROOT_PATH,
                                  cl_config_archive=CONFIG_ARCHIVE_PATH,
                                  cl_config_path=CONFIG_PATH,
                                  execute_archive_path=EXECUTE_ARCHIVE_PATH)

        assert template_executor.available_appends

        assert 'join' in template_executor.available_appends
        assert 'skip' in template_executor.available_appends
        assert 'remove' in template_executor.available_appends

    def test_if_the_translate_uid_gid_method_s_input_is_uid_and_gid_of_an_existing_user__the_method_returns_user_s_name_and_usser_s_groupname(self):
        if os.getuid() == 0 and "SUDO_COMMAND" in os.environ:
            chown_value = {'uid': int(os.environ.get('SUDO_UID', 0)),
                           'gid': int(os.environ.get('SUDO_GID', 0))}
            user_name = os.environ.get('SUDO_USER', 0)
            group_name = grp.getgrgid(
                                    int(os.environ.get('SUDO_GID', 0))).gr_name
        else:
            # chown_value = {'uid': os.getuid(),
            #                'gid': os.getgid()}
            # user_name = getpass.getuser()
            # group_name = grp.getgrgid(int(os.getgid())).gr_name
            chown_value = {'uid': 1000,
                           'gid': 1000}
            user_name = 'guest'
            group_name = 'guest'

        username_and_group = template_executor._translate_uid_gid(
                                                            chown_value['uid'],
                                                            chown_value['gid'])

        assert username_and_group == "{}:{}".format(user_name, group_name)

    # Тестируем методы для работы непосредственно с файловой системой.
    # Тестируем методы для изменения владельца файла.
    def test_if_the_chown_directory_method_input_is_path_to_the_existing_directory_and_correct_chown_value__the_chown_directory_method_succesfully_changes_directory_owner(self):
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        template_executor._chown_directory(join_paths(
                                             CHROOT_PATH,
                                             '/etc/chown_testfiles/dir_0'),
                                           chown_value)
        assert os.stat(join_paths(CHROOT_PATH,
                                  '/etc/chown_testfiles/dir_0')).\
            st_uid == chown_value['uid']
        assert os.stat(join_paths(CHROOT_PATH,
                                  '/etc/chown_testfiles/dir_0')).\
            st_gid == chown_value['gid']

    def test_if_the_chown_directory_method_input_is_path_to_the_unexisting_directory_and_correct_chown_value__the_chown_directory_method_does_nothing(self):
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        with pytest.raises(TemplateExecutorError):
            template_executor._chown_directory(join_paths(
                                                 CHROOT_PATH,
                                                 '/etc/chown_testfiles/dir_1'),
                                               chown_value)

    def test_if_the_chown_directory_method_input_is_a_path_to_the_directory_with_a_fat_filesystem_and_a_correct_chown_value__TemplateExecutor_object_throws_exception(self):
        # Для тестирования нужно примонтировать файловую систему с fat32.
        pass

    def test_if_the_chown_file_method_input_is_a_path_to_an_existing_file_and_the_correct_chown_value__the_chown_file_method_succesfully_changes_file_owner(self):
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        template_executor._chown_file(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chown_testfiles/file_0'),
                                      chown_value)
        assert os.stat(join_paths(CHROOT_PATH,
                                  '/etc/chown_testfiles/file_0')).\
            st_uid == chown_value['uid']
        assert os.stat(join_paths(CHROOT_PATH,
                                  '/etc/chown_testfiles/file_0')).\
            st_gid == chown_value['gid']

    def test_if_the_chown_file_method_input_is_path_to_the_unexisting_file_and_correct_chown_value__the_chown_directory_method_does_nothing(self):
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        with pytest.raises(TemplateExecutorError):
            template_executor._chown_file(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chown_testfiles/file_1'),
                                          chown_value)

    def test_if_the_chown_file_method_input_is_a_path_to_the_file_from_the_fat_filesystem_and_a_correct_chown_value__TemplateExecutor_object_throws_exception(self):
        # Для тестирования нужно примонтировать файловую систему с fat32.
        pass

    # Тестируем методы для изменения доступа к файлу.
    def test_if_the_chmod_directory_method_input_is_path_to_the_existing_directory_and_correct_chmod_value__the_chmod_directory_method_succesfully_changes_directory_mode(self):
        chmod_value = int(0o777)
        template_executor._chmod_directory(join_paths(
                                                 CHROOT_PATH,
                                                 '/etc/chmod_testfiles/dir_0'),
                                           chmod_value)
        result = stat.S_IMODE(os.stat(join_paths(
                                        CHROOT_PATH,
                                        '/etc/chmod_testfiles/dir_0')).st_mode)

        assert result == chmod_value

    def test_if_the_chmod_directory_method_input_is_path_to_the_unexisting_directory_and_correct_chmod_value__the_chmod_directory_method_does_nothing(self):
        chmod_value = int(0o777)
        with pytest.raises(TemplateExecutorError):
            template_executor._chmod_directory(join_paths(
                                                 CHROOT_PATH,
                                                 '/etc/chmod_testfiles/dir_1'),
                                               chmod_value)

    def test_if_the_chmod_directory_method_input_is_a_path_to_the_directory_with_a_fat_filesystem_and_a_correct_chmod_value__TemplateExecutor_object_throws_exception(self):
        # Для тестирования нужно примонтировать файловую систему с fat32.
        pass

    def test_if_the_chmod_file_method_input_is_a_path_to_an_existing_file_and_the_correct_chmod_value__the_chmod_file_method_succesfully_changes_file_owner(self):
        chmod_value = int(0o666)
        template_executor._chmod_file(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chmod_testfiles/file_0'),
                                      chmod_value)
        result = stat.S_IMODE(os.stat(join_paths(
                                       CHROOT_PATH,
                                       '/etc/chmod_testfiles/file_0')).st_mode)

        assert result == chmod_value

    def test_if_the_chmod_file_method_input_is_path_to_the_unexisting_file_and_correct_chmod_value__the_chmod_file_method_does_nothing(self):
        chmod_value = int(0o777)
        with pytest.raises(TemplateExecutorError):
            template_executor._chmod_directory(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chmod_testfiles/file_1'),
                                               chmod_value)

    def test_if_the_chmod_file_method_input_is_a_path_to_the_file_with_a_fat_filesystem_and_a_correct_chmod_value__TemplateExecutor_object_throws_exception(self):
        # Для тестирования нужно примонтировать файловую систему с fat32.
        pass

    # Тестируем методы для получения информации о владельце файла.
    def test_if_the_get_file_owner_method_is_called_with_a_path_to_a_directory_that_exists__the_method_returns_a_dictionary_with_its_owner_s_and_group_s_id(self):
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        template_executor._chown_directory(join_paths(
                                             CHROOT_PATH,
                                             '/etc/chown_testfiles/dir_2'),
                                           chown_value)
        owner = template_executor._get_file_owner(join_paths(
                                             CHROOT_PATH,
                                             '/etc/chown_testfiles/dir_2'))
        assert owner == chown_value

    def test_if_the_get_file_owner_method_is_called_with_a_path_to_a_directory_that_does_not_exists__the_method_throws_TemplateExecutorError_exception(self):
        with pytest.raises(TemplateExecutorError):
            template_executor._get_file_owner(join_paths(
                                                 CHROOT_PATH,
                                                 '/etc/chown_testfiles/dir_1'))

    def test_if_the_get_file_owner_method_is_called_with_a_path_to_a_file_that_exists__the_method_returns_a_dictionary_with_its_owner_s_and_group_s_id(self):
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        template_executor._chown_directory(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chown_testfiles/file_2'),
                                           chown_value)
        owner = template_executor._get_file_owner(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chown_testfiles/file_2'))
        assert owner == chown_value

    def test_if_the_get_file_owner_method_is_called_with_a_path_to_a_file_that_does_not_exists__the_method_throws_TemplateExecutorError_exception(self):
        with pytest.raises(TemplateExecutorError):
            template_executor._get_file_owner(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chown_testfiles/file_1'))

    # Тестируем методы для получения информации о доступе к файлу.
    def test_if_the_get_file_mode_method_is_called_with_a_path_to_a_directory_that_exists__the_method_returns_its_mode_value(self):
        chmod_value = int(0o777)
        template_executor._chmod_directory(join_paths(
                                                 CHROOT_PATH,
                                                 '/etc/chmod_testfiles/dir_2'),
                                           chmod_value)
        mode = template_executor._get_file_mode(join_paths(
                                                 CHROOT_PATH,
                                                 '/etc/chmod_testfiles/dir_2'))
        assert mode == chmod_value

    def test_if_the_get_file_mode_method_is_called_with_a_path_to_a_directory_that_does_not_exists__the_method_throws_TemplateExecutorError_exception(self):
        with pytest.raises(TemplateExecutorError):
            template_executor._get_file_mode(join_paths(
                                                 CHROOT_PATH,
                                                 '/etc/chmod_testfiles/dir_1'))

    def test_if_the_get_file_mode_method_is_called_with_a_path_to_a_file_that_exists__the_method_returns_its_mode_value(self):
        chmod_value = int(0o666)
        template_executor._chmod_file(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chmod_testfiles/file_2'),
                                      chmod_value)
        mode = template_executor._get_file_mode(
                                            join_paths(
                                                CHROOT_PATH,
                                                '/etc/chmod_testfiles/file_2'))

        assert mode == chmod_value

    def test_if_the_get_file_mode_method_is_called_with_a_path_to_a_file_that_does_not_exists__the_method_throws_TemplateExecutorError_exception(self):
        with pytest.raises(TemplateExecutorError):
            template_executor._get_file_mode(join_paths(
                                                CHROOT_PATH,
                                                '/etc/chmod_testfiles/file_1'))

    # Тесты действий с директориями.
    def test_if_the_create_directory_method_input_is_a_template_with_a_target_path_to_an_existing_directory_and_chown_and_chmod_parameters_is_not_set__the_method_does_nothing(self):
        target_directory = join_paths(CHROOT_PATH,
                                      '/etc/create_dir_testfiles/dir_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join'})
        template_wrapper = TemplateWrapper(
                                       target_directory,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        dir_owner = template_executor._get_file_owner(target_directory)
        dir_mode = template_executor._get_file_mode(target_directory)

        template_executor._create_directory(template_wrapper)

        assert dir_owner == template_executor._get_file_owner(target_directory)
        assert dir_mode == template_executor._get_file_mode(target_directory)

    def test_if_the_create_directory_method_input_is_a_template_with_a_target_path_to_an_existing_directory_and_chown_and_chmod_parameters_is_set__the_method_chmod_and_chown_target_file(self):
        target_directory = join_paths(CHROOT_PATH,
                                      '/etc/create_dir_testfiles/dir_0')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        template_wrapper = TemplateWrapper(
                                       target_directory,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)

        template_executor._create_directory(template_wrapper)

        assert chown_value == template_executor._get_file_owner(
                                                              target_directory)
        assert chmod_value == template_executor._get_file_mode(
                                                              target_directory)

    def test_if_the_create_directory_method_input_is_a_template_with_a_target_path_to_an_unexisting_directory_from_an_existing_directory_and_chown_and_chmod_parameters_is_not_set__the_method_creates_one_new_directory_with_a_mode_and_an_owner_of_its_parent_directory(self):
        target_directory = join_paths(CHROOT_PATH,
                                      '/etc/create_dir_testfiles/dir_1/subdir')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join'})
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        template_executor._chown_directory(os.path.dirname(target_directory),
                                           chown_value)
        template_executor._chmod_directory(os.path.dirname(target_directory),
                                           chmod_value)

        template_wrapper = TemplateWrapper(
                                       target_directory,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._create_directory(template_wrapper)

        assert os.path.exists(target_directory)
        assert template_executor._get_file_mode(target_directory) ==\
            chmod_value
        assert template_executor._get_file_owner(target_directory) ==\
            chown_value

    def test_if_the_create_directory_method_input_is_a_template_with_a_target_path_to_an_unexisting_directory_from_an_existing_directory_and_chown_and_chmod_parameters_is_set__the_method_one_new_directory_with_a_mode_and_an_owner_from_the_parameters(self):
        target_directory = join_paths(CHROOT_PATH,
                                      '/etc/create_dir_testfiles/dir_2/subdir')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        template_wrapper = TemplateWrapper(
                                       target_directory,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._create_directory(template_wrapper)

        assert os.path.exists(target_directory)
        assert template_executor._get_file_mode(target_directory) ==\
            chmod_value
        assert template_executor._get_file_owner(target_directory) ==\
            chown_value

    def test_if_the_create_directory_method_input_is_a_template_with_a_target_path_to_an_unexisting_directory_from_an_unexisting_directory_and_chown_and_chmod_parameters_is_not_set__the_method_creates_new_directory_and_all_its_parents_with_a_mode_and_an_owner_of_its_existing_parent(self):
        target_directory = join_paths(
                            CHROOT_PATH,
                            '/etc/create_dir_testfiles/dir_3/subdir/subsubdir')
        parent_directory = join_paths(CHROOT_PATH,
                                      '/etc/create_dir_testfiles/dir_3')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join'})
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        template_executor._chown_directory(parent_directory, chown_value)
        template_executor._chmod_directory(parent_directory, chmod_value)

        template_wrapper = TemplateWrapper(
                                       target_directory,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._create_directory(template_wrapper)

        assert os.path.exists(target_directory)
        assert template_executor._get_file_mode(target_directory) ==\
            chmod_value
        assert template_executor._get_file_owner(target_directory) ==\
            chown_value
        assert template_executor._get_file_mode(
                   os.path.dirname(target_directory)) == chmod_value
        assert template_executor._get_file_owner(
                   os.path.dirname(target_directory)) == chown_value

    def test_if_the_create_directory_method_s_input_is_a_template_with_a_target_path_to_an_unexisting_directory_from_an_unexisting_directory_and_chown_and_chmod_parameters_is_set__the_method_creates_new_directory_and_all_its_parents_with_a_mode_and_an_owner_from_the_parameters(self):
        target_directory = join_paths(
                            CHROOT_PATH,
                            '/etc/create_dir_testfiles/dir_4/subdir/subsubdir')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})

        template_wrapper = TemplateWrapper(
                                       target_directory,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._create_directory(template_wrapper)

        assert os.path.exists(target_directory)
        assert template_executor._get_file_mode(target_directory) ==\
            chmod_value
        assert template_executor._get_file_owner(target_directory) ==\
            chown_value
        assert template_executor._get_file_mode(
                   os.path.dirname(target_directory)) == chmod_value
        assert template_executor._get_file_owner(
                   os.path.dirname(target_directory)) == chown_value

    def test_if_the_link_directory_method_s_input_is_a_path_to_an_existing_source_directory_and_a_target_path__the_method_creates_a_link_to_a_source_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/link_dir_testfiles/link_dir_0')
        source_path = join_paths(CHROOT_PATH, '/etc/link_dir_testfiles/dir_0')
        template_executor._link_directory(source_path, target_path)

        assert os.path.exists(target_path)
        assert os.path.islink(target_path)

    def test_if_the_link_directory_method_s_input_is_a_path_to_an_existing_source_directory_and_a_target_path_to_an_existing_link__the_method_raises_the_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/link_dir_testfiles/link_dir_1')
        source_path = join_paths(CHROOT_PATH, '/etc/link_dir_testfiles/dir_1')

        with pytest.raises(TemplateExecutorError):
            template_executor._link_directory(source_path, target_path)

    def test_if_the_remove_directory_method_s_input_is_a_path_to_an_existing_empty_directory__the_method_will_remove_the_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_dir_testfiles/dir_0')
        os.remove(os.path.join(target_path, 'file'))

        template_executor._remove_directory(target_path)
        assert not os.path.exists(target_path)

    def test_if_the_remove_directory_method_s_input_is_a_path_to_an_existing_directory_that_contains_a_some_files__the_method_will_remove_the_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_dir_testfiles/dir_2')

        template_executor._remove_directory(target_path)
        assert not os.path.exists(target_path)

    def test_if_the_remove_directory_method_s_input_is_a_path_to_an_existing_directory_that_contains_directories__the_method_will_remove_the_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_dir_testfiles/dir_3')

        template_executor._remove_directory(target_path)
        assert not os.path.exists(target_path)

    def test_if_the_remove_directory_method_s_input_is_a_path_to_an_existing_link_to_a_directory__the_method_will_remove_the_link_but_not_the_link_s_source_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_dir_testfiles/link_dir_1')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_dir_testfiles/dir_1')

        template_executor._remove_directory(target_path)
        assert not os.path.exists(target_path)
        assert os.path.exists(source_path)

    def test_if_the_remove_directory_method_s_input_is_a_path_to_an_unexisting_directory__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_dir_testfiles/dir_4')

        with pytest.raises(TemplateExecutorError):
            template_executor._remove_directory(target_path)

    def test_if_the_remove_directory_method_s_input_is_a_path_to_a_file__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_dir_testfiles/file_0')

        with pytest.raises(TemplateExecutorError):
            template_executor._remove_directory(target_path)

    def test_if_the_clear_directory_method_s_input_is_a_path_to_an_existing_empty_directory__the_method_does_nothing(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_dir_testfiles/dir_0')
        # Делаем директорию пустой.
        os.remove(os.path.join(target_path, 'file'))

        template_executor._clear_directory(target_path)
        assert not os.listdir(target_path)

    def test_if_the_clear_directory_method_s_input_is_a_path_to_an_existing_directory_that_contains_some_files__the_method_clears_the_target_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_dir_testfiles/dir_1')

        template_executor._clear_directory(target_path)
        assert not os.listdir(target_path)

    def test_if_the_clear_directory_method_s_input_is_a_path_to_an_existing_directory_that_contains_some_directories__the_method_clears_the_target_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_dir_testfiles/dir_2')

        template_executor._clear_directory(target_path)
        assert not os.listdir(target_path)

    def test_if_the_clear_directory_method_s_input_is_a_path_to_an_existing_directory_that_contains_some_directories_and_files__the_method_clears_the_target_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_dir_testfiles/dir_3')

        template_executor._clear_directory(target_path)
        assert not os.listdir(target_path)

    def test_if_the_clear_directory_method_s_input_is_a_path_to_an_unexisting_directory__the_method_raises_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_dir_testfiles/dir_4')

        with pytest.raises(TemplateExecutorError):
            template_executor._clear_directory(target_path)

    def test_if_the_clear_directory_method_s_input_is_a_path_to_a_file__the_method_raises_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_dir_testfiles/file_0')

        with pytest.raises(TemplateExecutorError):
            template_executor._clear_directory(target_path)

    def test_if_the_link_file_method_s_input_is_a_path_to_an_existing_source_file_and_a_target_path__the_method_creates_a_link_to_a_source_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/link_file_testfiles/link_file_0')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/link_file_testfiles/file_0')
        template_executor._link_file(source_path, target_path)

        assert os.path.exists(target_path)
        assert os.path.islink(target_path)

    def test_if_the_link_file_method_s_input_is_a_path_to_an_existing_source_file_and_a_target_path_to_an_existing_file__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/link_file_testfiles/link_file_1')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/link_file_testfiles/file_1')

        with pytest.raises(TemplateExecutorError):
            template_executor._link_file(source_path, target_path)

    def test_if_the_remove_file_method_s_input_is_a_path_to_an_existing_file__the_method_removes_a_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_file_testfiles/file_0')

        template_executor._remove_file(target_path)
        assert not os.path.exists(target_path)

    def test_if_the_remove_file_method_s_input_is_a_path_to_an_existing_link_to_an_existing_file__the_method_removes_a_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_file_testfiles/link_file_1')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_file_testfiles/file_1')

        template_executor._remove_file(target_path)
        assert not os.path.exists(target_path)
        assert os.path.exists(source_path)

    def test_if_the_remove_file_method_s_input_is_a_path_to_an_unexisting_file__the_method_raises_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_file_testfiles/file_2')

        with pytest.raises(TemplateExecutorError):
            template_executor._remove_file(target_path)

    def test_if_the_remove_file_method_s_input_is_a_path_to_an_existing_directory__the_method_raises_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/remove_file_testfiles/dir_0')

        with pytest.raises(TemplateExecutorError):
            template_executor._remove_file(target_path)

    def test_if_clear_file_method_s_input_is_a_path_to_an_existing_empty_file__the_method_does_nothing(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_file_testfiles/file_0')

        template_executor._clear_file(target_path)
        with open(target_path, 'r') as target_file:
            text = target_file.read()
            assert not text

    def test_if_clear_file_method_s_input_is_a_path_to_an_existing_file_with_any_content__the_method_does_nothing(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_file_testfiles/file_1')

        template_executor._clear_file(target_path)
        with open(target_path, 'r') as target_file:
            text = target_file.read()
            assert not text

    def test_if_clear_file_method_s_input_is_a_path_to_an_unexisting_file__the_method_raises_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_file_testfiles/file_2')

        with pytest.raises(TemplateExecutorError):
            template_executor._clear_file(target_path)

    def test_if_clear_file_method_s_input_is_a_path_to_an_existing_directory__the_method_raises_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/clear_file_testfiles/dir_0')

        with pytest.raises(TemplateExecutorError):
            template_executor._clear_file(target_path)

    # Тестируем поведение исполнительного модуля при различных значениях
    # параметра append.
    def test_if_append_join_directory_method_s_input_is_a_template_with_a_target_path_to_an_unexisting_directory__the_method_creates_new_directory_and_adds_it_to_a_package_contents_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_join_dir_testfiles/dir_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        try:
            template_executor._append_join_directory(template_wrapper)
        except Exception as error:
            pytest.fail('Exception: {}'.format(str(error)))

        assert os.path.exists(target_path)
        assert '/etc/append_join_dir_testfiles/dir_0'\
            in template_wrapper.target_package

    def test_if_append_join_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_that_does_not_belong_to_any_package__the_method_just_adds_new_directory_to_a_package_contents_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_join_dir_testfiles/dir_1')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        try:
            template_executor._append_join_directory(template_wrapper)
        except Exception as error:
            pytest.fail('Exception: {}'.format(str(error)))

        assert os.path.exists(target_path)
        assert '/etc/append_join_dir_testfiles/dir_1'\
            in template_wrapper.target_package

    def test_if_append_join_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_belongs_to_the_template_package__the_method_does_nothing(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_join_dir_testfiles/dir_2')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_directory(template_wrapper)

        assert os.path.exists(target_path)
        assert '/etc/append_join_dir_testfiles/dir_2'\
            in template_wrapper.target_package

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_join_parameter_a_target_path_to_an_existing_file_that_belongs_to_the_template_package_and_force_parameter_is_set__the_method_removes_file_on_a_target_path__creates_new_directory_and_changes_target_s_type_to_the_dir_type_in_the_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_join_dir_testfiles/dir_3')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'force': True})
        assert os.path.isfile(target_path)
        print('START EXECUTION')
        output = template_executor.execute_template(
                                                   target_path,
                                                   parameters_object,
                                                   DIR,
                                                   '/path/to/template',
                                                   save_changes=False,
                                                   target_package=test_package)

        assert os.path.exists(target_path)
        assert os.path.isdir(target_path)
        assert output['target_path'] is None
        assert '/etc/append_join_dir_testfiles/dir_3' in test_package
        assert test_package.contents_dictionary[
            '/etc/append_join_dir_testfiles/dir_3'] == {'type': 'dir'}

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_join_parameter_a_target_path_to_an_existing_link_to_a_directory_that_belongs_to_the_template_package__the_method_changes_a_target_path_to_a_link_s_source_path_and_returns_one(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_join_dir_testfiles/link_0')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join'})
        assert os.path.islink(target_path)
        output = template_executor.execute_template(
                                                   target_path,
                                                   parameters_object,
                                                   DIR,
                                                   '/path/to/template',
                                                   save_changes=False,
                                                   target_package=test_package)
        assert output['target_path'] == join_paths(
                                        CHROOT_PATH,
                                        '/etc/append_join_dir_testfiles/dir_4')

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_join_parameter_a_target_path_to_an_existing_link_to_a_directory_that_belongs_to_the_template_package_and_force_parameter_is_set__the_method_changes_a_target_path_to_a_link_s_source_path_and_returns_one(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_join_dir_testfiles/dir_5')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'force': True})
        assert os.path.islink(target_path)
        output = template_executor.execute_template(
                                                   target_path,
                                                   parameters_object,
                                                   DIR,
                                                   '/path/to/template',
                                                   save_changes=False,
                                                   target_package=test_package)
        assert os.path.exists(target_path)
        assert os.path.isdir(target_path)
        assert output['target_path'] is None
        assert '/etc/append_join_dir_testfiles/dir_5' in test_package
        assert test_package.contents_dictionary[
            '/etc/append_join_dir_testfiles/dir_5'] == {'type': 'dir'}

    def test_if_append_remove_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_that_belongs_to_the_template_package__the_method_removes_a_target_directory_in_a_filesystem_and_in_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_remove_dir_testfiles/dir_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'remove'})

        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_remove_directory(template_wrapper)
        assert not os.path.exists(target_path)
        assert '/etc/append_remove_dir_testfiles/dir_0/file'\
            not in template_wrapper.target_package
        assert '/etc/append_remove_dir_testfiles/dir_0'\
            not in template_wrapper.target_package

    def test_if_append_remove_directory_method_s_input_is_a_template_with_a_target_path_to_an_unexisting_directory_that_belongs_to_the_template_package__the_method_removes_a_target_directory_in_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_remove_dir_testfiles/dir_1')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'remove'})

        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_remove_directory(template_wrapper)
        assert '/etc/append_remove_dir_testfiles/dir_1/file'\
            not in template_wrapper.target_package
        assert '/etc/append_remove_dir_testfiles/dir_1'\
            not in template_wrapper.target_package

    def test_if_append_remove_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_that_does_not_belong_to_any_package__the_method_removes_a_target_directory_in_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_remove_dir_testfiles/dir_2')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'remove'})

        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_remove_directory(template_wrapper)
        assert not os.path.exists(target_path)
        assert '/etc/append_remove_dir_testfiles/dir_2'\
            not in template_wrapper.target_package

    def test_if_append_clear_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_empty_directory_that_belongs_to_the_template_package__the_method_just_removes_all_its_files_from_a_package_CONTENTS_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_clear_dir_testfiles/dir_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_directory(template_wrapper)
        assert not os.listdir(target_path)
        assert '/etc/append_clear_dir_testfiles/dir_0/file'\
            not in template_wrapper.target_package

    def test_if_append_clear_directory_method_s_input_is_a_template_with_a_target_path_to_an_unexisting_directory_that_belongs_to_the_template_package__the_method_just_removes_the_directory_and_all_its_files_from_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_clear_dir_testfiles/dir_1')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_directory(template_wrapper)
        # Метод выполняется при сохранении файла CONTENTS,
        # здесь вызывем напрямую.
        template_wrapper.target_package.remove_empty_directories()
        assert '/etc/append_clear_dir_testfiles/dir_1'\
            not in template_wrapper.target_package

    def test_if_append_clear_directory_method_s_input_is_a_template_with_a_target_path_to_an_unexisting_directory_that_does_not_belong_to_the_template_package__the_method_does_nothing(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_clear_dir_testfiles/dir_2')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_directory(template_wrapper)
        assert not os.path.exists(target_path)

    def test_if_append_clear_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_with_some_files_that_belongs_to_the_template_package__the_method_clears_directory_and_removes_all_its_files_from_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_clear_dir_testfiles/dir_3')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_directory(template_wrapper)
        assert not os.listdir(target_path)
        assert '/etc/append_clear_dir_testfiles/dir_3/file_0'\
            not in template_wrapper.target_package
        assert '/etc/append_clear_dir_testfiles/dir_3/file_1'\
            not in template_wrapper.target_package
        assert '/etc/append_clear_dir_testfiles/dir_3/link'\
            not in template_wrapper.target_package

    def test_if_append_clear_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_with_some_directories_with_files_that_belongs_to_the_template_package__the_method_clears_directory_and_removes_all_its_files_from_a_package_CONTENTS_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_clear_dir_testfiles/dir_4')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_directory(template_wrapper)
        assert not os.listdir(target_path)
        assert '/etc/append_clear_dir_testfiles/dir_4/subdir_0/file'\
            not in template_wrapper.target_package
        assert '/etc/append_clear_dir_testfiles/dir_4/subdir_0'\
            not in template_wrapper.target_package
        assert '/etc/append_clear_dir_testfiles/dir_4/subdir_1/file'\
            not in template_wrapper.target_package
        assert '/etc/append_clear_dir_testfiles/dir_4/subdir_1'\
            not in template_wrapper.target_package
        assert '/etc/append_clear_dir_testfiles/dir_4/link'\
            not in template_wrapper.target_package

    def test_if_append_clear_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_that_belongs_to_the_template_package_and_chmod_and_chown_parameters_are_set__the_method_clears_directory_removes_all_its_files_from_a_package_CONTENTS_file_and_chmod_and_chown_one(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_clear_dir_testfiles/dir_5')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_directory(template_wrapper)
        assert not os.listdir(target_path)
        assert template_executor._get_file_owner(target_path) == chown_value
        assert template_executor._get_file_mode(target_path) == chmod_value

    def test_if_append_replace_directory_method_s_input_is_a_template_with_a_target_path_to_an_unexisting_directory__the_method_creates_new_directory_and_add_it_to_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_replace_dir_testfiles/dir_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'replace'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_replace_directory(template_wrapper)
        assert os.path.exists(target_path)
        assert '/etc/append_replace_dir_testfiles/dir_0'\
            in template_wrapper.target_package

    def test_if_append_replace_directory_method_s_input_is_a_template_with_a_target_path_to_an_unexisting_directory_and_the_chown_and_the_chmod_parameters_are_set__the_method_creates_new_directory_adds_it_to_a_package_CONTENTS_file_and_chown_and_chmod_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_replace_dir_testfiles/dir_1')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'replace',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_replace_directory(template_wrapper)
        assert os.path.exists(target_path)
        assert '/etc/append_replace_dir_testfiles/dir_1'\
            in template_wrapper.target_package
        assert template_executor._get_file_owner(target_path) == chown_value
        assert template_executor._get_file_mode(target_path) == chmod_value

    def test_if_append_replace_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_empty_directory_that_belongs_to_the_template_package__the_method_does_nothing(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_replace_dir_testfiles/dir_2')
        os.remove(os.path.join(target_path, 'file'))
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'replace'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_directory(template_wrapper)
        assert not os.listdir(target_path)
        assert '/etc/append_replace_dir_testfiles/dir_2/file'\
            not in template_wrapper.target_package

    def test_if_append_replace_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_empty_directory_that_belongs_to_the_template_package_and_the_chown_and_chmod_parameters_are_set__the_method_just_chown_and_chmod_a_target_directory(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_replace_dir_testfiles/dir_3')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'replace',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_directory(template_wrapper)
        assert not os.listdir(target_path)
        assert '/etc/append_replace_dir_testfiles/dir_3/file'\
            not in template_wrapper.target_package
        assert template_executor._get_file_owner(target_path) == chown_value
        assert template_executor._get_file_mode(target_path) == chmod_value

    def test_if_append_replace_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_with_some_files_that_belongs_to_the_template_package__the_method_clears_directory_and_removes_all_its_files_from_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_replace_dir_testfiles/dir_4')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'replace'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_replace_directory(template_wrapper)
        assert not os.listdir(target_path)
        assert '/etc/append_replace_dir_testfiles/dir_4/file_0'\
            not in template_wrapper.target_package
        assert '/etc/append_replace_dir_testfiles/dir_4/file_1'\
            not in template_wrapper.target_package
        assert '/etc/append_replace_dir_testfiles/dir_4/link'\
            not in template_wrapper.target_package

    def test_if_append_replace_directory_method_s_input_is_a_template_with_a_target_path_to_an_existing_directory_with_some_directories_with_files_that_belongs_to_the_template_package__the_method_clears_directory_and_removes_all_its_files_from_a_package_CONTENTS_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_replace_dir_testfiles/dir_5')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'replace'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_replace_directory(template_wrapper)
        assert not os.listdir(target_path)
        assert '/etc/append_replace_dir_testfiles/dir_5/subdir_0/file'\
            not in template_wrapper.target_package
        assert '/etc/append_replace_dir_testfiles/dir_5/subdir_0'\
            not in template_wrapper.target_package
        assert '/etc/append_replace_dir_testfiles/dir_5/subdir_1/file'\
            not in template_wrapper.target_package
        assert '/etc/append_replace_dir_testfiles/dir_5/subdir_1'\
            not in template_wrapper.target_package
        assert '/etc/append_replace_dir_testfiles/dir_5/link'\
            not in template_wrapper.target_package

    def test_if_append_link_directory_method_s_input_is_a_template_with_a_target_path_and_a_source_path_to_the_existing_directory__the_method_creates_a_link_to_the_source_directory_and_adds_this_link_to_the_package_CONTENTS_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_link_dir_testfiles/link_dir_0')
        source_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_link_dir_testfiles/dir_0')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_link_directory(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.islink(target_path)
        assert os.readlink(target_path) == source_path

        assert '/etc/append_link_dir_testfiles/link_dir_0'\
            in template_wrapper.target_package

    def test_if_append_link_directory_method_s_input_is_a_template_with_a_target_path_and_a_source_path_to_the_existing_directory_and_the_chown_and_chmod_parameters_are_set__the_method_creates_a_link_to_the_source_directory_and_adds_this_link_to_the_package_CONTENTS_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_link_dir_testfiles/link_dir_1')
        source_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_link_dir_testfiles/dir_1')

        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path,
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, DIR,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_link_directory(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.islink(target_path)

        assert '/etc/append_link_dir_testfiles/link_dir_1'\
            in template_wrapper.target_package

        assert os.readlink(target_path) == source_path
        assert template_executor._get_file_owner(target_path) == chown_value
        assert template_executor._get_file_mode(target_path) == chmod_value

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_link_parameter_a_target_path_to_an_existing_link_to_a_directory_that_belongs_to_the_template_package__the_method_removes_link_on_a_target_path_and_creates_new_one(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/link_dir_2')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/dir_3')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path})
        assert os.path.islink(target_path)
        assert os.readlink(target_path) == 'dir_2'
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           DIR,
                                           '/path/to/template',
                                           save_changes=False,
                                           target_package=test_package)
        assert os.path.exists(target_path)
        assert os.path.islink(target_path)
        assert os.readlink(target_path) == source_path

        assert '/etc/append_link_dir_testfiles/link_dir_2' in test_package
        assert test_package.contents_dictionary[
            '/etc/append_link_dir_testfiles/link_dir_2']['type'] == 'sym'
        assert test_package.contents_dictionary[
            '/etc/append_link_dir_testfiles/link_dir_2']['target'] ==\
            source_path

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_link_parameter_a_target_path_to_an_existing_link_to_a_file_that_belongs_to_the_template_package__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/link_dir_4')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/dir_4')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path})
        assert os.path.islink(target_path)
        assert os.path.isfile(target_path)
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               save_changes=False,
                                               target_package=test_package)

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_link_parameter_a_target_path_to_an_existing_link_to_a_file_that_belongs_to_the_template_package_and_force_parameter_is_set__the_method_removes_a_link_from_a_target_path_and_creates_a_link_to_a_source_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/link_dir_4')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/dir_4')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path,
                                                 'force': True})
        assert os.path.islink(target_path)
        assert os.path.isfile(target_path)
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           DIR,
                                           '/path/to/template',
                                           save_changes=False,
                                           target_package=test_package)
        assert os.path.exists(target_path)
        assert os.path.islink(target_path)
        assert os.readlink(target_path) == source_path

        assert '/etc/append_link_dir_testfiles/link_dir_4' in test_package
        assert test_package.contents_dictionary[
            '/etc/append_link_dir_testfiles/link_dir_4']['type'] == 'sym'
        assert test_package.contents_dictionary[
            '/etc/append_link_dir_testfiles/link_dir_4']['target'] ==\
            source_path

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_link_parameter_a_target_path_to_an_existing_file_that_belongs_to_the_template_package__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/link_dir_5')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/dir_5')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path})
        assert os.path.isfile(target_path)
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               save_changes=False,
                                               target_package=test_package)

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_link_parameter_a_target_path_to_an_existing_file_that_belongs_to_the_template_package_and_force_parameter_is_set__the_method_removes_a_file_from_a_target_path_and_creates_a_link_to_a_source_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/link_dir_5')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/dir_5')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path,
                                                 'force': True})
        assert os.path.isfile(target_path)
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           DIR,
                                           '/path/to/template',
                                           save_changes=False,
                                           target_package=test_package)
        assert os.path.exists(target_path)
        assert os.path.islink(target_path)
        assert os.readlink(target_path) == source_path

        assert '/etc/append_link_dir_testfiles/link_dir_5' in test_package
        assert test_package.contents_dictionary[
            '/etc/append_link_dir_testfiles/link_dir_5']['type'] == 'sym'
        assert test_package.contents_dictionary[
            '/etc/append_link_dir_testfiles/link_dir_5']['target'] ==\
            source_path

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_link_parameter_a_target_path_to_an_existing_directory_that_belongs_to_the_template_package__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/link_dir_6')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/dir_6')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path})
        assert os.path.isdir(target_path)
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               save_changes=False,
                                               target_package=test_package)

    def test_if_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_append_link_parameter_a_target_path_to_an_existing_directory_that_belongs_to_the_template_package_and_force_parameter_is_set__the_method_removes_a_directory_from_a_target_path_and_creates_a_link_to_a_source_directory(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/link_dir_6')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_dir_testfiles/dir_6')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path,
                                                 'force': True})
        assert os.path.isdir(target_path)
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           DIR,
                                           '/path/to/template',
                                           save_changes=False,
                                           target_package=test_package)
        assert os.path.exists(target_path)
        assert os.path.islink(target_path)
        assert os.readlink(target_path) == source_path

        assert '/etc/append_link_dir_testfiles/link_dir_6' in test_package
        assert test_package.contents_dictionary[
            '/etc/append_link_dir_testfiles/link_dir_6']['type'] == 'sym'
        assert test_package.contents_dictionary[
            '/etc/append_link_dir_testfiles/link_dir_6']['target'] ==\
            source_path

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_unexisting_file_that_should_not_exist__the_method_creates_new_empty_file_joins_a_template_with_them_adds_file_to_the_package_CONTENTS_file_and_create_an_archive_version_of_a_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_0')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n'
                                     '    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.exists(join_paths(
                                     CONFIG_ARCHIVE_PATH,
                                     '/etc/append_join_file_testfiles/file_0'))
        assert '/etc/append_join_file_testfiles/file_0'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_unexisting_file_that_should_exist__the_method_creates_new_empty_cfg_file_joins_a_template_with_them_and_adds_it_to_config_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_1')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n'
                                     '    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(os.path.join(os.path.dirname(target_path),
                                           '._cfg0000_file_1'))
        assert not os.path.exists(join_paths(
                                     CONFIG_ARCHIVE_PATH,
                                     '/etc/append_join_file_testfiles/file_1'))
        assert '/etc/append_join_file_testfiles/file_1'\
            in template_executor.calculate_config_file
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_unexisting_file_that_should_exist_and_autoupdate_parameters_is_set__the_method_creates_new_empty_file_joins_a_template_with_them_and_adds_it_to_config_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_2')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'autoupdate': True})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n'
                                     '    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.exists(join_paths(
                                     CONFIG_ARCHIVE_PATH,
                                     '/etc/append_join_file_testfiles/file_2'))
        assert '/etc/append_join_file_testfiles/file_2'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_unexisting_file_that_should_not_exist_and_chown_and_chmod_parameters_are_set__the_method_creates_new_empty_file__joins_a_template_with_them__adds_file_to_the_package_CONTENTS_file__create_an_archive_version_of_a_file_and_chown_and_chmod_it(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_3')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        archive_path = join_paths(CONFIG_ARCHIVE_PATH,
                                  '/etc/append_join_file_testfiles/file_3')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n'
                                     '    parameter-2 no;\n'
                                     '};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert template_executor._get_file_owner(target_path) == chown_value
        assert template_executor._get_file_mode(target_path) == chmod_value

        assert os.path.exists(archive_path)
        assert template_executor._get_file_owner(archive_path) == chown_value
        assert template_executor._get_file_mode(archive_path) == chmod_value

        assert '/etc/append_join_file_testfiles/file_3'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_unexisting_file_that_should_exist_and_chown_and_chmod_parameters_are_set__the_method_creates_new_empty_cfg_file__joins_a_template_with_them__adds_it_to_config_file_and_chown_and_chmod_it(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_4')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join', 'format': 'bind',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        output_path = os.path.join(os.path.dirname(target_path),
                                   '._cfg0000_file_4')
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(output_path)
        assert template_executor._get_file_owner(output_path) == chown_value
        assert template_executor._get_file_mode(output_path) == chmod_value

        assert not os.path.exists(join_paths(
                                     CONFIG_ARCHIVE_PATH,
                                     '/etc/append_join_file_testfiles/file_4'))
        assert '/etc/append_join_file_testfiles/file_4'\
            in template_executor.calculate_config_file
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_and_its_hash_sum_matches_the_hash_from_a_CONTENTS_file__the_method_joins_an_input_file_with_a_template__changes_its_hash_in_the_CONTENTS__updates_config_archive(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_5')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.exists(join_paths(
                                     CONFIG_ARCHIVE_PATH,
                                     '/etc/append_join_file_testfiles/file_5'))
        assert '/etc/append_join_file_testfiles/file_5'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_its_hash_sum_matches_the_hash_from_a_CONTENTS_file_and_a_chown_and_chmod_parameters_are_set__the_method_joins_an_input_file_with_a_template__changes_its_hash_in_the_CONTENTS__updates_config_archive_and_chown_and_chmod_it(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_6')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        archive_path = join_paths(CONFIG_ARCHIVE_PATH,
                                  '/etc/append_join_file_testfiles/file_6')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert template_executor._get_file_owner(target_path) == chown_value
        assert template_executor._get_file_mode(target_path) == chmod_value

        assert os.path.exists(archive_path)
        assert template_executor._get_file_owner(archive_path) == chown_value
        assert template_executor._get_file_mode(archive_path) == chmod_value

        assert '/etc/append_join_file_testfiles/file_6'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file__the_method_creates_a_cfg_file_and_adds_a_target_file_s_path_to_the_config_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_7')
        output_path = os.path.join(os.path.dirname(target_path),
                                   '._cfg0000_file_7')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.exists(output_path)

        assert '/etc/append_join_file_testfiles/file_7'\
            in template_executor.calculate_config_file
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file_and_the_chown_and_chmod_parameters_is_set__the_method_creates_a_cfg_file_and_adds_a_target_file_s_path_to_the_config_file_and_chown_and_chmod_it(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_8')
        output_path = os.path.join(os.path.dirname(target_path),
                                   '._cfg0000_file_8')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.exists(output_path)
        assert template_executor._get_file_owner(output_path) == chown_value
        assert template_executor._get_file_mode(output_path) == chmod_value

        assert '/etc/append_join_file_testfiles/file_8'\
            in template_executor.calculate_config_file
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file_and_the_autoupdate_parameter_is_set__the_method_joins_a_target_file_and_a_template__removes_a_path_to_file_from_the_config_file_and_updates_a_package_CONTENTS_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_join_file_testfiles/file_9')
        cfg_path = os.path.join(os.path.dirname(target_path),
                                '._cfg0001_file_9')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'autoupdate': True})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 no;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert not os.path.exists(cfg_path)

        assert '/etc/append_join_file_testfiles/file_9'\
            not in template_executor.calculate_config_file

        assert '/etc/append_join_file_testfiles/file_9'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            assert output_file.read() == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file_and_there_is_some_cfg_files_and_the_autoupdate_parameter_is_set__the_method_joins_a_target_file_and_a_template__removes_a_path_to_file_from_the_config_file__removes_all_cfg_files_and_updates_a_package_CONTENTS_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_join_file_testfiles/file_10')
        cfg_path_1 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0001_file_10')
        cfg_path_2 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0002_file_10')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'autoupdate': True})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-4 yes; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-4 yes;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        print('input path = {}'.format(template_wrapper.input_path))
        assert os.path.exists(target_path)
        assert not os.path.exists(cfg_path_1)
        assert not os.path.exists(cfg_path_2)

        assert '/etc/append_join_file_testfiles/file_10'\
            not in template_executor.calculate_config_file

        assert '/etc/append_join_file_testfiles/file_10'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            print('Output:\n{}'.format(output_file_text))
            assert output_file_text == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file_and_there_is_two_cfg_files__the_method_creates_third_cfg_file_and_updates_config_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_join_file_testfiles/file_11')
        cfg_path_1 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0001_file_11')
        cfg_path_2 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0002_file_11')
        cfg_path_3 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0003_file_11')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-4 yes; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-4 yes;\n};\n'))
        output_md5 = hashlib.md5(output_text.encode()).hexdigest()
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        print('output_path = {}'.format(template_wrapper.output_path))
        assert os.path.exists(target_path)
        assert os.path.exists(cfg_path_1)
        assert os.path.exists(cfg_path_2)
        assert os.path.exists(cfg_path_3)

        assert '/etc/append_join_file_testfiles/file_11'\
            in template_executor.calculate_config_file
        assert template_executor.calculate_config_file.compare_md5(
                         '/etc/append_join_file_testfiles/file_11', output_md5)
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            print('Output:\n{}'.format(output_file_text))
            assert output_file_text == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file_and_there_is_two_cfg_files_and_changes_from_a_template_is_similar_to_the_last_one__the_method_does_nothing(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_join_file_testfiles/file_12')
        cfg_path_2 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0002_file_12')
        cfg_path_3 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0003_file_12')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-3 10; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-3 10;\n};\n'))
        output_md5 = hashlib.md5(output_text.encode()).hexdigest()
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.exists(cfg_path_2)
        assert not os.path.exists(cfg_path_3)

        assert '/etc/append_join_file_testfiles/file_12'\
            in template_executor.calculate_config_file
        assert template_executor.calculate_config_file.compare_md5(
                         '/etc/append_join_file_testfiles/file_12', output_md5)
        with open(cfg_path_2, 'r') as output_file:
            output_file_text = output_file.read()
            assert output_file_text == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_an_unprotected_target_path_to_an_existing_file_that_belongs_to_the_template_package__the_method_just_joins_a_template_to_a_target_file_without_updating_a_CONTENTS_file_and_creating_an_archive_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/unprotected/append_join_file_testfiles/file_0')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert not template_wrapper.protected
        assert os.path.exists(target_path)
        assert not os.path.exists(join_paths(
                                     CONFIG_ARCHIVE_PATH,
                                     '/unprotected/append_join_file_testfiles/file_0'))
        assert '/unprotected/append_join_file_testfiles/file_0'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert output_file_text == output_text
            assert hashlib.md5(output_file_text.encode()).hexdigest !=\
                template_wrapper.target_package.get_md5(target_path)

    def test_if_append_join_file_method_s_input_is_a_template_with_an_unprotected_target_path_to_an_existing_file_that_belongs_to_the_template_package_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file__the_method_just_joins_a_template_to_a_target_file_without_updating_a_package_CONTENTS_and_the_config_files_and_creating_an_archive_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/unprotected/append_join_file_testfiles/file_1')
        cfg_path_1 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0001_file_1')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 no;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert not template_wrapper.protected
        assert os.path.exists(target_path)
        assert not os.path.exists(cfg_path_1)
        assert not os.path.exists(join_paths(
                             CONFIG_ARCHIVE_PATH,
                             '/unprotected/append_join_file_testfiles/file_1'))
        assert '/unprotected/append_join_file_testfiles/file_1'\
            not in template_executor.calculate_config_file
        assert '/unprotected/append_join_file_testfiles/file_1'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert output_file_text == output_text
            assert hashlib.md5(output_file_text.encode()).hexdigest !=\
                template_wrapper.target_package.get_md5(target_path)

    def test_if_append_join_file_method_s_input_is_a_template_with_an_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_and_the_unbound_parameter_is_set__the_method_joins_template_and_removes_a_target_file_path_from_a_package_CONTENTS_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_join_file_testfiles/file_13')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'unbound': True})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 yes;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.exists(join_paths(
                                    CONFIG_ARCHIVE_PATH,
                                    '/etc/append_join_file_testfiles/file_13'))
        assert '/etc/append_join_file_testfiles/file_13'\
            not in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert output_file_text == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_an_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_and_the_unbound_parameter_is_set_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file__the_method_joins_template__removes_a_target_file_path_from_a_package_CONTENTS_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_join_file_testfiles/file_14')
        cfg_path_1 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0001_file_14')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'unbound': True})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 no;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)
        assert os.path.exists(target_path)
        assert not os.path.exists(cfg_path_1)
        assert os.path.exists(join_paths(
                                    CONFIG_ARCHIVE_PATH,
                                    '/etc/append_join_file_testfiles/file_14'))
        assert '/etc/append_join_file_testfiles/file_14'\
            not in template_wrapper.target_package
        assert '/etc/append_join_file_testfiles/file_14'\
            not in template_executor.calculate_config_file
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert output_file_text == output_text

    def test_if_append_join_file_method_s_input_is_a_template_with_an_protected_target_path_to_an_existing_file_that_belongs_to_the_template_package_and_the_unbound_parameter_is_set_but_its_hash_sum_does_not_match_the_hash_from_a_CONTENTS_file_and_there_are_some_cfg_file__the_method_joins_template__removes_a_target_file_path_from_a_package_CONTENTS_file_and_the_config_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_join_file_testfiles/file_15')
        cfg_path_1 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0001_file_15')
        cfg_path_2 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0002_file_15')
        cfg_path_3 = os.path.join(os.path.dirname(target_path),
                                  '._cfg0003_file_15')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'unbound': True})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(header,
                                    ('section-name {\n    parameter-1 no;'
                                     '\n    parameter-2 no;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)

        assert os.path.exists(target_path)
        assert not os.path.exists(cfg_path_1)
        assert not os.path.exists(cfg_path_2)
        assert not os.path.exists(cfg_path_3)
        assert os.path.exists(join_paths(
                                    CONFIG_ARCHIVE_PATH,
                                    '/etc/append_join_file_testfiles/file_15'))
        assert '/etc/append_join_file_testfiles/file_15'\
            not in template_wrapper.target_package
        assert '/etc/append_join_file_testfiles/file_15'\
            not in template_executor.calculate_config_file
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert output_file_text == output_text

    def test_if_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_append_join_parameter_a_target_path_to_an_existing_directory_that_belongs_to_the_template_package__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_join_file_testfiles/file_16')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind'})
        template_text = 'section-name { parameter-2 no; }'

        assert os.path.isdir(target_path)
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               FILE,
                                               '/path/to/template',
                                               save_changes=False,
                                               template_text=template_text,
                                               target_package=test_package)

    def test_if_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_append_join_parameter_a_target_path_to_an_existing_directory_that_belongs_to_the_template_package_and_force_parameter_is_set__the_method_removes_a_directory_from_a_target_path__creates_empty_file__joins_template_with_the_created_file_and_updates_the_CONTENTS_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_join_file_testfiles/file_16')
        test_package = Package(test_package_name, chroot_path=CHROOT_PATH)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'join',
                                                 'format': 'bind',
                                                 'force': True})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = 'section-name { parameter-2 no; }'
        output_text = '{}{}'.format(
                                   header,
                                   'section-name {\n    parameter-2 no;\n};\n')

        assert os.path.isdir(target_path)
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           FILE,
                                           '/path/to/template',
                                           save_changes=False,
                                           template_text=template_text,
                                           target_package=test_package)

        assert os.path.exists(target_path)
        assert os.path.isfile(target_path)
        assert os.path.exists(join_paths(
                                    CONFIG_ARCHIVE_PATH,
                                    '/etc/append_join_file_testfiles/file_16'))
        assert '/etc/append_join_file_testfiles/file_16'\
            in test_package
        assert '/etc/append_join_file_testfiles/file_16'\
            not in template_executor.calculate_config_file
        with open(target_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert output_file_text == output_text

    def test_if_the_append_after_file_method_s_input_is_a_not_empty_template__the_template_s_text_and_sections_joins_after_the_text_of_the_target_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_after_file_testfiles/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'after',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = ('section-1 { parameter-2 no; }'
                         'section-2 { parameter-1 10; }')
        output_text = '{}{}'.format(header,
                                    ('section-1 {\n    parameter-1 yes;'
                                     '\n    parameter-2 no;\n};\n\n'
                                     'section-2 {\n    parameter-1 10;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_after_file(template_wrapper)

        assert os.path.exists(target_path)
        assert '/etc/append_after_file_testfiles/file_0'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert output_file_text == output_text

    def test_if_the_append_before_file_method_s_input_is_a_not_empty_template__the_template_s_text_and_sections_joins_before_the_text_of_the_target_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_before_file_testfiles/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'before',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = ('section-1 { parameter-1 no; }'
                         'section-2 { parameter-2 10; }')
        output_text = '{}{}'.format(header,
                                    ('section-1 {\n    parameter-1 no;\n};\n'
                                     '\nsection-2 {\n    parameter-1 yes;'
                                     '\n    parameter-2 10;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_before_file(template_wrapper)

        assert os.path.exists(target_path)
        assert '/etc/append_after_file_testfiles/file_0'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            print('output text:\n{}\n'.format(output_file_text))
            assert output_file_text == output_text

    def test_if_the_append_replace_file_method_s_input_is_a_not_empty_template_with_a_target_path_to_an_existing_file__the_method_joins_a_template_with_the_empty_text_and_replaces_the_target_file_with_the_template_join_result(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_replace_file_testfiles/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'replace',
                                                 'format': 'bind'})
        header = ('#' + '-' * 79 + '\n' +
                  '# Modified by Calculate Utilities 4.0\n' +
                  '# Processed template files:\n' +
                  '# /path/to/template\n' +
                  '#' + '-' * 79 + '\n')
        template_text = ('section-1 { parameter-1 no; };'
                         'section-2 { parameter-1 10; }')
        output_text = '{}{}'.format(
                                  header,
                                  ('section-1 {\n    parameter-1 no;\n};\n'
                                   '\nsection-2 {\n    parameter-1 10;\n};\n'))
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       template_text=template_text,
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_replace_file(template_wrapper)

        assert os.path.exists(target_path)
        assert '/etc/append_after_file_testfiles/file_0'\
            in template_wrapper.target_package
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            output_md5 = hashlib.md5(output_file_text.encode()).hexdigest()
            print('output text:\n{}\n'.format(output_file_text))
            assert output_file_text == output_text
            assert template_wrapper.target_package.get_md5(target_path) ==\
                output_md5

    def test_if_the_append_remove_file_method_s_input_is_a_template_with_a_target_path_to_an_existing_file_that_belongs_to_the_template_package__the_method_removes_a_target_file_in_a_filesystem_and_in_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_remove_file_testfiles/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'remove'})

        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_remove_file(template_wrapper)
        assert not os.path.exists(target_path)
        assert '/etc/append_remove_file_testfiles/file_0'\
            not in template_wrapper.target_package

    def test_if_the_append_remove_file_method_s_input_is_a_template_with_a_target_path_to_an_unexisting_file_that_belongs_to_the_template_package__the_method_removes_a_target_file_in_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_remove_file_testfiles/file_1')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'remove'})

        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_remove_file(template_wrapper)
        assert '/etc/append_remove_file_testfiles/file_1'\
            not in template_wrapper.target_package

    def test_if_the_append_remove_file_method_s_input_is_a_template_with_a_target_path_to_an_existing_file_that_does_not_belong_to_any_package__the_method_removes_a_target_file_in_a_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_remove_file_testfiles/file_2')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'remove'})

        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_remove_file(template_wrapper)
        assert not os.path.exists(target_path)
        assert '/etc/append_remove_file_testfiles/file_2'\
            not in template_wrapper.target_package

    def test_if_the_append_clear_file_method_s_input_is_a_template_with_a_target_path_to_an_existing_empty_file_that_belongs_to_the_template_package__the_method_just_updates_a_package_CONTENTS_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_clear_file_testfiles/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_file(template_wrapper)
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert not output_file_text
            assert template_wrapper.target_package.get_md5(target_path) ==\
                hashlib.md5(''.encode()).hexdigest()

    def test_if_the_append_clear_file_method_s_input_is_a_template_with_a_target_path_to_an_existing_not_empty_file_that_belongs_to_the_template_package__the_method_clears_a_target_file_and_updates_a_package_CONTENTS_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_clear_file_testfiles/file_1')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear'})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_file(template_wrapper)
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()
            assert not output_file_text
            assert template_wrapper.target_package.get_md5(target_path) ==\
                hashlib.md5(''.encode()).hexdigest()

    def test_if_the_append_clear_file_method_s_input_is_a_template_with_a_target_path_to_an_existing_not_empty_file_that_belongs_to_the_template_package_and_the_chown_and_chmod_parameters_are_set__the_method_clears_a_target_file_and_updates_a_package_CONTENTS_file(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_clear_file_testfiles/file_2')
        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'clear',
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_clear_file(template_wrapper)
        with open(template_wrapper.output_path, 'r') as output_file:
            output_file_text = output_file.read()

            assert not output_file_text
            assert template_wrapper.target_package.get_md5(target_path) ==\
                hashlib.md5(''.encode()).hexdigest()

        assert template_executor._get_file_owner(target_path) ==\
            chown_value
        assert template_executor._get_file_mode(target_path) ==\
            chmod_value

    def test_if_append_link_file_method_s_input_is_a_template_with_a_target_path_and_a_source_path_to_the_existing_file__the_method_creates_a_link_to_the_source_file_and_adds_this_link_to_the_package_CONTENTS_file(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_file_testfiles/link_file_0')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_file_testfiles/file_0')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_link_file(template_wrapper)
        assert os.path.exists(template_wrapper.output_path)
        assert os.path.islink(template_wrapper.output_path)
        assert os.readlink(template_wrapper.output_path) == source_path

        assert '/etc/append_link_file_testfiles/link_file_0'\
            in template_wrapper.target_package
        assert os.path.exists(template_wrapper.archive_path)

    def test_if_append_link_file_method_s_input_is_a_template_with_a_target_path_to_an_existing_link_without_user_changes_and_a_source_path_to_the_existing_file__the_method_(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_file_testfiles/link_file_2')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_file_testfiles/file_2')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_link_file(template_wrapper)
        assert os.path.exists(template_wrapper.output_path)
        assert os.path.islink(template_wrapper.output_path)
        assert os.readlink(template_wrapper.output_path) == source_path

        assert '/etc/append_link_file_testfiles/link_file_2'\
            in template_wrapper.target_package
        assert os.path.exists(template_wrapper.archive_path)

    def test_if_append_link_file_method_s_input_is_a_template_with_a_target_path_to_an_existing_link_with_user_changes_and_a_source_path_to_the_existing_file__the_method_(self):
        target_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_file_testfiles/link_file_3')
        source_path = join_paths(CHROOT_PATH,
                                 '/etc/append_link_file_testfiles/file_3')
        output_path = join_paths(
                       CHROOT_PATH,
                       '/etc/append_link_file_testfiles/._cfg0000_link_file_3')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_link_file(template_wrapper)
        assert os.path.exists(output_path)
        assert os.path.islink(output_path)
        assert os.readlink(target_path) == "file_5"
        assert os.readlink(output_path) == source_path

        assert '/etc/append_link_file_testfiles/link_file_3'\
            in template_wrapper.target_package
        assert (template_wrapper.target_package.contents_dictionary[
                '/etc/append_link_file_testfiles/link_file_3'][
                    'target'] == source_path)

        assert ('/etc/append_link_file_testfiles/link_file_3'
                in template_executor.calculate_config_file)

        assert (template_executor.calculate_config_file._config_dictionary[
                    '/etc/append_link_file_testfiles/link_file_3']
                == hashlib.md5('/etc/append_link_file_testfiles/file_3'
                               .encode()).hexdigest())

    def test_if_append_link_file_method_s_input_is_a_template_with_a_target_path_and_a_source_path_to_the_existing_file_and_the_chown_and_chmod_parameters_are_set__the_method_creates_a_link_to_the_source_file_and_adds_this_link_to_the_package_CONTENTS_file(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_link_file_testfiles/link_file_1')
        source_path = join_paths(
                                CHROOT_PATH,
                                '/etc/append_link_file_testfiles/file_1')

        chown_value = {'uid': os.getuid(), 'gid': os.getgid()}
        chmod_value = int(0o777)

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'link',
                                                 'source': source_path,
                                                 'chown': chown_value,
                                                 'chmod': chmod_value})
        template_wrapper = TemplateWrapper(
                                       target_path,
                                       parameters_object, FILE,
                                       '/path/to/template',
                                       chroot_path=CHROOT_PATH,
                                       config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_link_file(template_wrapper)
        assert os.path.exists(target_path)
        assert os.path.islink(target_path)

        assert os.readlink(target_path) == source_path
        assert '/etc/append_link_file_testfiles/link_file_1'\
            in template_wrapper.target_package

        assert template_executor._get_file_owner(target_path) == chown_value
        assert template_executor._get_file_mode(target_path) == chmod_value

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_run_parameter_and_a_target_path_to_an_existing_file_from_an_existing_directory_and_its_text_is_empty__the_method_does_nothing(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/dir_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           FILE,
                                           '/path/to/template',
                                           save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_run_parameter_and_a_target_path_to_an_existing_directory_and_its_text_is_correct__the_method_runs_a_template_text_in_the_target_directory_and_returns_the_object_with_its_stdout(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/dir_0/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        template_text = '''
import os
print(os.getcwd())'''
        output = template_executor.execute_template(
                                                   target_path,
                                                   parameters_object,
                                                   FILE,
                                                   '/path/to/template',
                                                   template_text=template_text,
                                                   save_changes=False)
        assert output['stdout'].strip() == os.path.dirname(target_path)
        assert output['stderr'] is None

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_run_parameter_and_a_directory_from_a_target_path_does_not_exist__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/dir_1/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               FILE,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_run_parameter_and_a_target_path_to_an_existing_file_and_its_text_is_correct__the_method_runs_a_template_text_in_a_directory_that_contains_a_file_from_a_target_path_and_returns_the_object_with_its_stdout(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        template_text = '''
import os
print(os.getcwd())'''
        output = template_executor.execute_template(
                                                   target_path,
                                                   parameters_object,
                                                   FILE,
                                                   '/path/to/template',
                                                   template_text=template_text,
                                                   save_changes=False)
        assert output['stdout'].strip() == os.path.dirname(target_path)
        assert output['stderr'] is None

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_run_parameter_and_a_target_path_to_an_unexisting_file_from_an_unexisting_directory__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/dir_1/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               FILE,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_run_parameter_and_a_target_path_to_an_unexisting_file_from_an_directory_that_replaced_to_a_file__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/dir_2/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               FILE,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_run_parameter_and_a_target_path_to_an_unexisting_directory__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/dir_1')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_run_parameter_and_a_target_path_to_an_existing_file__the_method_throws_TemplateExecutorError_exception(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/dir_2')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_run_parameter_a_target_path_to_an_unexisting_file_from_an_existing_directory_and_its_text_is_not_correct__the_method_runs_a_template_text_and_returns_the_object_with_its_stderr(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/dir_0/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/python'})
        traceback_text = '''Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
AttributeError: module 'os' has no attribute 'suspicious_attribute'
'''

        template_text = '''
import os
print(os.suspicious_attribute)'''
        output = template_executor.execute_template(
                                                   target_path,
                                                   parameters_object,
                                                   FILE,
                                                   '/path/to/template',
                                                   template_text=template_text,
                                                   save_changes=False)
        assert output['stdout'] is None
        assert output['stderr'] == traceback_text

    def test_if_the_execute_template_method_s_input_is_a_template_with_the_run_parameter_a_target_path_to_an_existing_directory_but_interpreter_from_the_run_parameter_does_not_exist__the_method_throws_the_TemplateExecutorError_exception(self):
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_parameter_testfiles/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'run': '/usr/bin/unknown'})
        template_text = '''
import os
print(os.getcwd())'''
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               FILE,
                                               '/path/to/template',
                                               template_text=template_text,
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_exec_parameter_and_a_target_path_to_an_unexisting_file_from_existing_directory_and_its_text_is_empty__the_method_creates_an_empty_exec_file_and_saves_a_path_to_exec_file_interpreter_and_a_target_path_as_cwd_path(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/exec_parameter_testfiles/dir_0/file_0')
        interpreter = '/usr/bin/python'
        execute_file_path = os.path.join(EXECUTE_ARCHIVE_PATH, 'exec_0001')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': interpreter})
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           FILE,
                                           '/path/to/template',
                                           save_changes=False)
        assert os.path.exists(execute_file_path)
        assert template_executor.execute_files[execute_file_path][
            'interpreter'] == interpreter
        assert template_executor.execute_files[execute_file_path][
            'cwd_path'] == os.path.dirname(target_path)
        with open(os.path.join(EXECUTE_ARCHIVE_PATH,
                               'exec_0001'), 'r') as exec_file:
            exec_file_text = exec_file.read()
            assert exec_file_text == ''

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_exec_parameter_and_a_target_path_to_an_unexisting_file_from_an_existing_directory_and_its_text_is_not_empty__the_method_creates_an_exec_file_and_saves_a_path_to_exec_file_interpreter_and_a_target_path_as_cwd_path(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/exec_parameter_testfiles/dir_0/file_0')
        interpreter = '/usr/bin/python'
        execute_file_path = os.path.join(EXECUTE_ARCHIVE_PATH, 'exec_0001')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': interpreter})
        template_text = '''
import os
print(os.getcwd())'''
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           FILE,
                                           '/path/to/template',
                                           template_text=template_text,
                                           save_changes=False)
        assert os.path.exists(execute_file_path)
        assert template_executor.execute_files[execute_file_path][
            'interpreter'] == interpreter
        assert template_executor.execute_files[execute_file_path][
            'cwd_path'] == os.path.dirname(target_path)
        with open(os.path.join(EXECUTE_ARCHIVE_PATH,
                               'exec_0001'), 'r') as exec_file:
            exec_file_text = exec_file.read()
            assert exec_file_text == template_text

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_exec_parameter_and_a_target_path_to_an_unexisting_directory__the_method_throws_TemplateExecutorError_exception(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        target_path = join_paths(CHROOT_PATH,
                                 '/etc/run_parameter_testfiles/dir_1')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_DIR_type_with_the_exec_parameter_and_a_target_path_to_an_existing_file__the_method_throws_TemplateExecutorError_exception(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/exec_parameter_testfiles/dir_4')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_exec_parameter_and_a_target_path_to_an_unexisting_file_in_the_directory_that_replaced_to_a_file__the_method_throws_TemplateExecutorError_exception(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        target_path = join_paths(CHROOT_PATH,
                                 '/etc/run_parameter_testfiles/dir_4/file_1')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               FILE,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_exec_parameter_and_a_target_path_to_an_unexisting_file_from_unexisting_directory__the_method_throws_TemplateExecutorError_exception(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        target_path = join_paths(CHROOT_PATH,
                                 '/etc/exec_parameter_testfiles/dir_1/file_0')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': '/usr/bin/python'})
        with pytest.raises(TemplateExecutorError):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               save_changes=False)

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_exec_parameter_and_a_target_path_to_an_existing_file_and_its_text_is_not_empty__the_method_creates_an_exec_file_and_saves_a_path_to_exec_file_interpreter_and_a_path_to_a_file_from_a_target_path_as_cwd_path(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        target_path = join_paths(CHROOT_PATH,
                                 '/etc/exec_parameter_testfiles/file_0')
        interpreter = '/usr/bin/python'
        execute_file_path = os.path.join(EXECUTE_ARCHIVE_PATH, 'exec_0001')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': interpreter})
        template_text = '''
import os
print(os.getcwd())'''
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           FILE,
                                           '/path/to/template',
                                           template_text=template_text,
                                           save_changes=False)
        assert os.path.exists(execute_file_path)
        assert template_executor.execute_files[execute_file_path][
            'interpreter'] == interpreter
        assert template_executor.execute_files[execute_file_path][
            'cwd_path'] == os.path.dirname(target_path)
        with open(os.path.join(EXECUTE_ARCHIVE_PATH,
                               'exec_0001'), 'r') as exec_file:
            exec_file_text = exec_file.read()
            assert exec_file_text == template_text

    def test_if_the_execute_template_method_s_input_is_a_template_of_the_FILE_type_with_the_exec_parameter_and_a_target_path_to_an_unexisting_file_from_the_existing_directory__the_method_saves_the_exec_file_and_sets_cwd_path_to_a_file_s_directory(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/exec_parameter_testfiles/file_1')
        interpreter = '/usr/bin/python'
        execute_file_path = os.path.join(EXECUTE_ARCHIVE_PATH, 'exec_0001')
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': '/usr/bin/python'})
        template_text = '''
import os
print(os.getcwd())'''
        template_executor.execute_template(target_path,
                                           parameters_object,
                                           FILE,
                                           '/path/to/template',
                                           template_text=template_text,
                                           save_changes=False)
        assert os.path.exists(execute_file_path)
        assert template_executor.execute_files[execute_file_path][
            'interpreter'] == interpreter
        assert template_executor.execute_files[execute_file_path][
            'cwd_path'] == os.path.dirname(target_path)
        with open(os.path.join(EXECUTE_ARCHIVE_PATH,
                               'exec_0001'), 'r') as exec_file:
            exec_file_text = exec_file.read()
            assert exec_file_text == template_text

    def test_if_the_execute_template_method_s_input_is_a_several_templates_with_the_exec_parameter_and_a_target_paths_to_an_existing_directories_and_files_and_its_text_is_not_empty__the_method_creates_some_exec_files_and_saves_a_paths_to_exec_files_its_interpreters_and_paths_to_a_directories_from_a_target_path_as_cwd_path(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        interpreter = '/usr/bin/python'
        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': '/usr/bin/python'})
        execute_file_paths = [os.path.join(EXECUTE_ARCHIVE_PATH, 'exec_0001'),
                              os.path.join(EXECUTE_ARCHIVE_PATH, 'exec_0002'),
                              os.path.join(EXECUTE_ARCHIVE_PATH, 'exec_0003')]
        target_paths = [join_paths(CHROOT_PATH,
                                   '/etc/exec_parameter_testfiles/file_2'),
                        join_paths(CHROOT_PATH,
                                   '/etc/exec_parameter_testfiles/dir_2'),
                        join_paths(CHROOT_PATH,
                                   '/etc/exec_parameter_testfiles/dir_3')]
        template_types = [FILE, DIR, DIR]
        counter = 1
        for target_path, template_type in zip(target_paths, template_types):
            template_text = "print('{}')".format(counter)
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               template_type,
                                               '/path/to/template',
                                               template_text=template_text,
                                               save_changes=False)
            counter += 1

        for exec_path, target_path in zip(execute_file_paths, target_paths):
            assert os.path.exists(exec_path)
            assert template_executor.execute_files[exec_path][
                'interpreter'] == interpreter
            assert template_executor.execute_files[exec_path][
                'cwd_path'] == os.path.dirname(target_path)\
                if os.path.isfile(target_path) else target_path

        counter = 1
        for exec_path in execute_file_paths:
            with open(exec_path, 'r') as exec_file:
                exec_file_text = exec_file.read()
                assert exec_file_text == "print('{}')".format(counter)
            counter += 1

    def test_if_some_exec_files_is_saved_and_contains_correct_scripts__the_execute_file_method_can_be_used_for_executing_this_exec_files_and_the_returns_its_stdout_and_stderr(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': '/usr/bin/python'})
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_exec_testfiles/dir_0')
        for number in range(1, 4):
            template_text = "print('{}')".format(number)
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               DIR,
                                               '/path/to/template',
                                               template_text=template_text,
                                               save_changes=False)

        counter = 1
        for exec_file_path in template_executor.execute_files:
            output = template_executor.execute_file(
                template_executor.execute_files[exec_file_path]['interpreter'],
                exec_file_path,
                template_executor.execute_files[exec_file_path]['cwd_path'])
            assert output['stdout'].strip() == str(counter)
            assert output['stderr'] is None
            counter += 1

    def test_if_some_exec_files_is_saved_and_contains_not_correct_scripts__the_execute_file_method_can_be_used_for_executing_this_exec_files_and_returns_its_stderr_and_stdout(self):
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(EXECUTE_ARCHIVE_PATH)
        template_executor.execute_files = OrderedDict()

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'exec': '/usr/bin/python'})
        target_path = join_paths(
                                CHROOT_PATH,
                                '/etc/run_exec_testfiles/dir_0/template_name')
        template_text = '''
import os
print(os.suspicious_attribute)'''
        stderr_text = '''Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
AttributeError: module 'os' has no attribute 'suspicious_attribute'
'''
        for number in range(1, 4):
            template_executor.execute_template(target_path,
                                               parameters_object,
                                               FILE,
                                               '/path/to/template',
                                               template_text=template_text,
                                               save_changes=False)

        counter = 1
        for exec_file_path in template_executor.execute_files:
            output = template_executor.execute_file(
                template_executor.execute_files[exec_file_path]['interpreter'],
                exec_file_path,
                template_executor.execute_files[exec_file_path]['cwd_path'])
            assert output['stdout'] is None
            assert output['stderr'] == stderr_text
            counter += 1

    def test_using_mirror_for_coping_files(self):
        target_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_replace_file_testfiles/file_2.png')
        source_path = join_paths(
                              CHROOT_PATH,
                              '/etc/append_replace_file_testfiles/logo.png')

        parameters_object = ParametersContainer({'package': test_package_name,
                                                 'append': 'replace',
                                                 'format': 'raw',
                                                 'mirror': True})

        template_wrapper = TemplateWrapper(
                                     target_path,
                                     parameters_object, FILE,
                                     '/path/to/template',
                                     template_text='',
                                     chroot_path=CHROOT_PATH,
                                     config_archive_path=CONFIG_ARCHIVE_PATH)
        template_executor._append_join_file(template_wrapper)

    def test_raw_format_error(self):
        pass

    def test_to_remove_changed_testfiles(self):
        shutil.rmtree(os.path.join(CHROOT_PATH, 'etc'))
        shutil.rmtree(os.path.join(CHROOT_PATH, 'unprotected'))
        shutil.rmtree(os.path.join(CHROOT_PATH,
                                   'var/lib/calculate/config-archive'))
        if os.path.exists(EXECUTE_ARCHIVE_PATH):
            shutil.rmtree(os.path.join(EXECUTE_ARCHIVE_PATH))
