From 76452a1eb72883dd830655d314cad8645dd4a0bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=81?= Date: Thu, 30 Apr 2020 18:36:10 +0300 Subject: [PATCH] New version of the directory processor is completed and debugged. --- calculate/templates/template_engine.py | 50 +++-- calculate/templates/template_processor.py | 210 ++++++++++---------- calculate/utils/package.py | 197 ++++++++++-------- tests/templates/test_directory_processor.py | 21 +- tests/utils/test_package.py | 185 +++++++++-------- 5 files changed, 354 insertions(+), 309 deletions(-) diff --git a/calculate/templates/template_engine.py b/calculate/templates/template_engine.py index 62f80e8..842e6e0 100644 --- a/calculate/templates/template_engine.py +++ b/calculate/templates/template_engine.py @@ -8,6 +8,7 @@ from jinja2.runtime import Context, Undefined from collections.abc import MutableMapping from collections import OrderedDict from importlib import import_module +from pprint import pprint import copy import re import os @@ -181,7 +182,8 @@ class ParametersProcessor: else: checked_value = parameters[parameter_name] - if parameter_name in self.inheritable_parameters: + if (template_type == DIR and + parameter_name in self.inheritable_parameters): if parameter_name in self.inherit_conditions: if self.inherit_conditions[parameter_name]( parameters[parameter_name]): @@ -198,15 +200,15 @@ class ParametersProcessor: def check_package_parameter(self, parameter_value): try: - self.package_atom_parser.parse_package_parameter(parameter_value) + atom_object = self.package_atom_parser.parse_package_parameter( + parameter_value) except PackageAtomError as error: if error.errno == NOTEXIST: raise ConditionFailed(error.message, self.lineno) else: raise IncorrectParameter(error.message) - parameter_value = self.package_atom_parser.atom_name - return parameter_value + return atom_object def check_append_parameter(self, parameter_value): if parameter_value not in self.available_appends: @@ -221,8 +223,9 @@ class ParametersProcessor: for package_name in packages_names: package_name = package_name.strip() - self.package_atom_parser.parse_package_parameter(package_name) - packages_list.append(self.package_atom_parser.atom_name) + atom_object = self.package_atom_parser.parse_package_parameter( + package_name) + packages_list.append(atom_object) return packages_list @@ -339,7 +342,6 @@ class ParametersProcessor: raise IncorrectParameter("'force' parameter value is not bool") def check_autoupdate_parameter(self, parameter_value): - print('autoupdate value = {}'.format(parameter_value)) if isinstance(parameter_value, bool): return parameter_value else: @@ -476,20 +478,26 @@ def resolve_or_missing(context, key, missing=missing, env={}): '''Переопределение функции из для поиска значений переменных из jinja2. Ищет переменные в datavars.''' datavars = context.parent['__datavars__'] + if key in context.vars: return context.vars[key] + if key in context.parent: return context.parent[key] + if key in datavars: return datavars[key] + for name in env: if name in datavars and key in datavars[name]: return datavars[name][key] + return missing class CalculateContext(Context): - '''Класс контекста позволяющий искать значения datavars и сохранять их.''' + '''Класс контекста позволяющий использовать значения datavars и + сохранять их.''' _env_set = set() def resolve(self, key): @@ -516,10 +524,11 @@ class ParametersContainer(MutableMapping): '''Класс для хранения параметров, взятых из шаблона, и передачи их шаблонизатору.''' def __init__(self, parameters_dictionary={}): + # Слой ненаследуемых параметров. self.__parameters = {} - self.__inheritable = parameters_dictionary - self._new_template = True + # Слой наследуемых параметров. + self.__inheritable = parameters_dictionary def set_parameter(self, item_to_add: dict): self.__parameters.update(item_to_add) @@ -530,15 +539,15 @@ class ParametersContainer(MutableMapping): def get_inheritables(self): return ParametersContainer(copy.deepcopy(self.__inheritable)) + def remove_not_inheritable(self): + self.__parameters.clear() + def print_parameters_for_debug(self): print('Parameters:') - for parameter_name in self.__parameters: - print('{0}: {1}'.format(parameter_name, - self.__parameters[parameter_name])) + pprint(self.__parameters) + print('Inherited:') - for parameter_name in self.__inheritable: - print('{0}: {1}'.format(parameter_name, - self.__inheritable[parameter_name])) + pprint(self.__inheritable) def __getattr__(self, parameter_name): if (parameter_name not in @@ -578,7 +587,8 @@ class ParametersContainer(MutableMapping): return len(set(self.__parameters).union(self.__inheritable)) def __repr__(self): - return ''.format(self.__parameters) + return ''.\ + format(self.__parameters, self.__inheritable) @property def parameters(self): @@ -793,7 +803,6 @@ def pkg(context, *args): try: package_atom_parser.parse_package_parameter(package_atom) atom_dictionary = package_atom_parser.atom_dictionary - print('atom dictionary = {}'.format(atom_dictionary['version'])) return atom_dictionary['version'] except PackageAtomError: return Version() @@ -844,13 +853,14 @@ class TemplateEngine: self._parameters_object = parameters if self._parameters_object.env: - CalculateContext._env_set = self._parameters_object.env.copy + CalculateContext._env_set = self._parameters_object.env.copy() else: CalculateContext._env_set = set() template = self.environment.get_template(template_path) - self.parameters_processor._parameters_container = None + self.parameters_processor._parameters_container =\ + self._parameters_object self._template_text = template.render( __datavars__=self._datavars_module, __parameters__=self._parameters_object, diff --git a/calculate/templates/template_processor.py b/calculate/templates/template_processor.py index ba9e58e..c9cda1b 100644 --- a/calculate/templates/template_processor.py +++ b/calculate/templates/template_processor.py @@ -438,10 +438,12 @@ class DirectoryProcessor: chmod_regex = re.compile(r'\d{3}') def __init__(self, action, datavars_module=Variables(), package='', - output_module=IOModule()): + output_module=IOModule(), without_execution=False): self.action = action self.cl_chroot_path = datavars_module.main.cl_chroot_path + self.without_execution = without_execution + self.datavars_module = datavars_module self.output = output_module self.template_action = TemplateAction(output_module=self.output, @@ -535,12 +537,14 @@ class DirectoryProcessor: directory_parameters, directories_queue=[]): template_files = [] template_directories = [] + directory_name = os.path.basename(current_directory_path) current_target_path = target_path entries = os.scandir(current_directory_path) self.template_engine.change_directory(current_directory_path) + for node in entries: # Временное, вместо этого добавить переменную ignore_files. if node.name.endswith('.swp'): @@ -554,7 +558,6 @@ class DirectoryProcessor: # обрабатываем в первую очередь шаблон директории. if '.calculate_directory' in template_files: template_files.remove('.calculate_directory') - try: self.template_engine.process_template( '.calculate_directory', @@ -564,19 +567,17 @@ class DirectoryProcessor: self.output.set_warning('{}.\nTemplate: {}'. format(str(error), current_directory_path)) - self.output.console_output.print_default('\n') return except Exception as error: - self.output.set_error('Template error: {0} \nTemplate: {1}'. + self.output.set_error('Template error: {0}\nTemplate: {1}'. format(str(error), current_directory_path)) return - - print('Current dir params:\n', directory_parameters) + directory_parameters.print_parameters_for_debug() # Если есть параметр name -- меняем имя текущего каталога. if directory_parameters.name: - directory_name = directory_parameters.path + directory_name = directory_parameters.name # Если есть параметр path -- меняем текущий путь к целевому # каталогу. @@ -585,54 +586,35 @@ class DirectoryProcessor: directory_parameters.path) if directory_parameters.append != 'skip': - current_target_path = os.path.join(current_target_path, - directory_name) - if directory_parameters.action != self.action: - self.output.set_error( - ("Action parameter '{0}' not found or not relevant." - "\nTemplate: {}").format(directory_parameters.action, - directory_name)) + if self.check_package_and_action(directory_parameters, + current_directory_path): + current_target_path = os.path.join(current_target_path, + directory_name) + else: return + else: + # Если .calculate_directory отсутствует -- создаем директорию + # используя унаследованные параметры и имя самой директории. + if not self.check_package_and_action(directory_parameters, + current_directory_path): + return + + directory_parameters.set_parameter({'append': 'join'}) + current_target_path = os.path.join(current_target_path, + directory_name) - # Если шаблоны обрабатываются для одного пакета -- проверяем - # параметр package и собираем пути к директориям других - # пакетов, необходимые для merge. - if self.for_package: - if not directory_parameters.package: - self.output.set_warning( - "'package' parameter is not defined for template: {}". - format(current_directory_path) - ) - # считаем наличие параметра package необязательным. - # return - elif directory_parameters.package != self.for_package: - package_name = directory_parameters.package - if package_name in self.packages_file_paths: - self.packages_file_paths[package_name].append( - current_directory_path - ) - else: - self.packages_file_paths[package_name] =\ - [current_directory_path] - self.output.set_warning( - "'package' parameter is not actual in {}". - format(current_directory_path) - ) - return - - # Если есть параметр merge -- собираем указанные в нем пакеты - # в списке имен пакетов для последующей обработки. - if self.for_package and directory_parameters.merge: - self.packages_to_merge.append(directory_parameters.merge) - - # Выполняем действие с директорией. + # Выполняем действие с директорией. + if not self.without_execution: self.output.set_success('Processing directory: {}'. format(current_directory_path)) self.template_action.process_template_directory( - current_target_path, - template_path=current_directory_path, - parameters=directory_parameters) + current_target_path, + template_path=current_directory_path, + parameters=directory_parameters) + else: + self.output.set_success('Processing directory: {}'. + format(current_directory_path)) if directories_queue: next_node = directories_queue.pop() @@ -647,93 +629,105 @@ class DirectoryProcessor: # обрабатываем файлы шаблонов хранящихся в директории. for template_name in template_files: - template_parameters = directory_parameters.get_inheritables() + directory_parameters.remove_not_inheritable() template_path = os.path.join(current_directory_path, template_name) try: self.template_engine.process_template( - template_name, FILE, - parameters=template_parameters) + template_name, FILE, + parameters=directory_parameters) except ConditionFailed as error: - self.output.set_warning('{}.\nTemplate: {}'. + self.output.set_warning('{0}.\nTemplate: {1}'. format(str(error), current_directory_path)) - self.output.console_output.print_default('\n') return except Exception as error: self.output.set_error('Template error: {0} \nTemplate: {1}'. format(str(error), current_directory_path)) return + directory_parameters.print_parameters_for_debug() template_text = self.template_engine.template_text - if template_parameters.action != self.action: - self.output.set_warning( - 'Action parameter not found or not relevant.' - ) + if not self.check_package_and_action(directory_parameters, + template_path): continue - if self.for_package: - if not template_parameters.package: - self.output.set_warning("'package' is not defined for {}". - format(template_path)) - # считаем параметр package необязательным. - # continue - elif template_parameters['package'] != self.for_package: - package_name = template_parameters['package'] - if package_name in self.packages_file_paths: - self.packages_file_paths[package_name].append( - template_path - ) - else: - self.packages_file_paths[package_name] =\ - [template_path] - self.output.set_warning( - "'package' parameter is not actual in {}". - format(template_name) - ) - continue - - if 'merge' in template_parameters: - merge_list = template_parameters['merge'].split(',') - del(template_parameters['merge']) - for package_name in merge_list: - if package_name not in self.processed_packages: - self.packages_to_merge.append(package_name.strip()) - - # Если параметр env содержит несуществующий модуль -- шаблон не - # выполняем. - if 'env' in template_parameters: - env_to_check = template_parameters['env'].split(',') - for name in env_to_check: - if name.strip() not in self.datavars_module: - continue - del(template_parameters['env']) - - if 'name' in template_parameters: - template_name = template_parameters['name'] - - if 'path' in template_parameters: + if directory_parameters.name: + template_name = directory_parameters.name + + if directory_parameters.path: target_file_path = join_paths(self.cl_chroot_path, - template_parameters['path'], + directory_parameters.path, template_name) else: target_file_path = join_paths(current_target_path, template_name) # Выполняем действие с использованием шаблона. - self.output.set_success('Processing template: {}...'. - format(template_name)) - self.template_action.process_template_file( - target_file_path, - template_path, - template_text=template_text, - parameters=template_parameters) + if not self.without_execution: + self.output.set_success('Processing template: {}...'. + format(template_path)) + + self.template_action.process_template_file( + target_file_path, + template_path, + template_text=template_text, + parameters=directory_parameters) + else: + self.output.set_success('Processing template: {}...'. + format(template_path)) # проходимся далее по директориям. for directory_path in template_directories: self.walk_directory_tree(directory_path, current_target_path, - directory_parameters, current_env, + directory_parameters.get_inheritables(), directories_queue=directories_queue) + + def check_package_and_action(self, parameters, template_path): + if not parameters.action: + self.output.set_warning( + ("Action parameter value '{0}' not found." + "\nTemplate: {1}").format(parameters.action, + template_path)) + return False + elif parameters.action != self.action: + self.output.set_warning( + ("Action parameter value '{0}' does not match its" + " current value '{1}'.\nTemplate: {2}").format( + parameters.action, + template_path)) + return False + + if self.for_package: + if not parameters.package: + self.output.set_warning( + "'package' parameter is not defined.\nTemplate: {}". + format(template_path)) + # считаем наличие параметра package необязательным. + # return False + + elif parameters.package != self.for_package: + package_name = parameters.package + + # DIRECTORIES_QUEUE + if package_name in self.packages_file_paths: + self.packages_file_paths[package_name].append( + template_path + ) + else: + self.packages_file_paths[package_name] = [template_path] + + self.output.set_warning( + ("'package' parameter value '{0}' does not " + "match its current target package.\nTemplate: {1}"). + format(parameters.package, template_path) + ) + return False + + if self.for_package and parameters.merge: + self.packages_to_merge.extend(parameters.merge) + + return True diff --git a/calculate/utils/package.py b/calculate/utils/package.py index cf64361..533a648 100644 --- a/calculate/utils/package.py +++ b/calculate/utils/package.py @@ -43,7 +43,11 @@ class Version: "Can't initialize Version object using '{0}'" " value with type {1}".format(version_value, type(version_value))) - self._version_string = str(version_value) + if isinstance(version_value, str): + self._version_string = version_value.strip('-') + else: + self._version_string = str(version_value) + self._version_value = value def _get_version_value(self, version): @@ -60,6 +64,7 @@ class Version: version_value.append(int(version_part.strip())) elif isinstance(version, str): + version = version.strip('-') version_value = [] if '-' in version: @@ -93,8 +98,20 @@ class Version: version_value.append(0) for lvalue, rvalue in zip(version_value, other_value): + if lvalue == rvalue: + continue + if compare_operator(lvalue, rvalue): return True + else: + return False + else: + if (compare_operator != operator.lt and + compare_operator != operator.gt and + compare_operator != operator.ne): + return True + else: + return False def __lt__(self, other): '''Перегрузка x < y.''' @@ -174,43 +191,63 @@ class Version: class PackageAtomName: def __init__(self, atom_dictionary): - self._atom_dictionary = atom_dictionary + self._package_directory = atom_dictionary['pkg_path'] + self._version = atom_dictionary['version'] - def __getattr__(self, name): - if name in self._atom_dictionary: - return self._atom_dictionary[name] - else: - return False + @property + def name(self): + return os.path.basename(self._package_directory) - def __getitem__(self, key): - if key in self._atom_dictionary: - return self._atom_dictionary[key] - else: - return False + @property + def category(self): + return os.path.basename(os.path.dirname(self._package_directory)) + + @property + def version(self): + return self._version + + @property + def use_flags(self): + use_path = os.path.join(self._package_directory, 'USE') + try: + return read_file(use_path).strip('\n').split(' ') + except FilesError: + raise PackageAtomError("could not read use flags for 'package'" + " parameter: {}".format(self.package_atom)) + + @property + def pkg_path(self): + return self._package_directory - def __setitem__(self, key, value): - self._atom_dictionary[key] = value + @property + def slot(self): + slot_path = os.path.join(self._package_directory, 'SLOT') + try: + return read_file(slot_path).strip('\n') + except FilesError: + raise PackageAtomError("could not read slot value for" + " 'package': {}".format(self.package_atom)) def __eq__(self, other): if isinstance(other, PackageAtomName): - return (self._atom_dictionary['contents'] == - other._atom_dictionary.contents) - elif isinstance(other, dict): - return self._atom_dictionary['contents'] == other['contents'] + return (self._package_directory == + other._package_directory) else: return False def __ne__(self, other): if isinstance(other, PackageAtomName): - return (self._atom_dictionary['contents'] != - other._atom_dictionary.contents) - elif isinstance(other, dict): - return self._atom_dictionary['contents'] != other['contents'] + return (self._package_directory != + other._package_directory) else: return False def __bool__(self): - return bool(self._atom_dictionary) + return bool(self._package_directory) + + def __repr__(self): + return ''.format(self.category, + self.name) class PackageAtomParser: @@ -238,8 +275,6 @@ class PackageAtomParser: self._atom_dictionary = {} parsing_result = self.atom_regex.search(package_atom) - print('pkg_path = {}'.format(self.pkg_path)) - print('parsing result: {}'.format(parsing_result.groupdict())) if (not parsing_result or parsing_result.string != package_atom or not parsing_result.groupdict()['category'] or @@ -257,7 +292,6 @@ class PackageAtomParser: version_value = parsing_result.groupdict()['version'].strip('-') self._atom_dictionary['version'] = Version(version_value) - print('version = {}'.format(version_value)) if (parsing_result.groupdict()['slot'] and parsing_result.groupdict()['slot'] != ':'): @@ -274,6 +308,10 @@ class PackageAtomParser: self._check_package_existance() + atom_name_object = PackageAtomName(self._atom_dictionary) + self._atom_dictionary.clear() + return atom_name_object + def _check_package_existance(self, package_atom=''): if package_atom: self.parse_package_parameter(package_atom) @@ -286,11 +324,6 @@ class PackageAtomParser: full_name = self._atom_dictionary['name'] if 'version' not in self._atom_dictionary: - print('contents_path:') - print(r'{0}/{1}/{2}-[0-9]*/CONTENTS'.format( - self.pkg_path, - self._atom_dictionary['category'], - full_name)) glob_result = glob.glob( r'{0}/{1}/{2}-[0-9]*/CONTENTS'.format( self.pkg_path, @@ -304,32 +337,34 @@ class PackageAtomParser: full_name)) if not glob_result: - print('glob is empty') raise PackageAtomError("Package from 'package' parameter value" " '{}' does not exist".format( self.package_atom), errno=NOTEXIST) if len(glob_result) == 1: - contents_path = next(iter(glob_result)) - self._check_slot_value(contents_path) - self._check_use_flags_value(contents_path) - - self._atom_dictionary['name'] = contents_path.split('/')[-2] - self._atom_dictionary['contents'] = contents_path + pkg_path = os.path.dirname(next(iter(glob_result))) + self._check_slot_value(pkg_path) + self._check_use_flags_value(pkg_path) + + parsed_name = self._atom_dictionary['name'] + full_name = os.path.basename(pkg_path) + self._atom_dictionary['version'] = Version( + full_name[len(parsed_name):]) + self._atom_dictionary['pkg_path'] = pkg_path else: packages = dict() for contents_path in glob_result: - package_info = dict() + pkg_path = os.path.dirname(contents_path) try: - self._check_slot_value(contents_path) - self._check_use_flags_value(contents_path) - package_info['name'] = contents_path.split('/')[-2] - package_info['version'] = Version( - package_info['name'].split('-', 1)[1]) + self._check_slot_value(pkg_path) + self._check_use_flags_value(pkg_path) + parsed_name = self._atom_dictionary['name'] + full_name = os.path.basename(pkg_path) + packages[pkg_path] = Version( + full_name[len(parsed_name):]) except PackageAtomError: continue - packages[contents_path] = package_info if not packages: raise PackageAtomError( @@ -339,19 +374,19 @@ class PackageAtomParser: errno=NOTEXIST) if len(packages) == 1: - contents_path = next(iter(packages.keys())) - self._atom_dictionary['contents'] = contents_path - self._atom_dictionary.update(packages[contents_path]) + pkg_path = next(iter(packages.keys())) + self._atom_dictionary['pkg_path'] = pkg_path + self._atom_dictionary['version'] = packages[pkg_path] else: - contents_path = sorted( - packages.keys(), - key=lambda path: packages[path]['version'])[-1] - self._atom_dictionary['contents'] = contents_path - self._atom_dictionary.update(packages[contents_path]) + # Берем старшую версию. + pkg_path = sorted(packages.keys(), + key=lambda path: packages[path])[-1] + self._atom_dictionary['pkg_path'] = pkg_path + self._atom_dictionary['version'] = packages[pkg_path] - def _check_slot_value(self, contents_path): + def _check_slot_value(self, pkg_path): if 'slot' in self._atom_dictionary: - slot = self._get_slot_value(contents_path) + slot = self._get_slot_value(pkg_path) if slot != self._atom_dictionary['slot']: raise PackageAtomError("Package from 'package' parameter value" @@ -359,9 +394,9 @@ class PackageAtomParser: self.package_atom), errno=NOTEXIST) - def _check_use_flags_value(self, contents_path): + def _check_use_flags_value(self, pkg_path): if 'use_flags' in self._atom_dictionary: - use_flags = self._get_use_flags_value(contents_path) + use_flags = self._get_use_flags_value(pkg_path) for use_flag in self._atom_dictionary['use_flags']: if use_flag not in use_flags: @@ -371,16 +406,16 @@ class PackageAtomParser: self.package_atom), errno=NOTEXIST) - def _get_slot_value(self, contents_path): - slot_path = os.path.join(os.path.dirname(contents_path), 'SLOT') + def _get_slot_value(self, pkg_path): + slot_path = os.path.join(pkg_path, 'SLOT') try: return read_file(slot_path).strip('\n') except FilesError: raise PackageAtomError("could not read slot value for" " 'package': {}".format(self.package_atom)) - def _get_use_flags_value(self, contents_path): - use_path = os.path.join(os.path.dirname(contents_path), 'USE') + def _get_use_flags_value(self, pkg_path): + use_path = os.path.join(pkg_path, 'USE') try: return read_file(use_path).strip('\n').split(' ') except FilesError: @@ -464,25 +499,11 @@ class Package: def __init__(self, package_atom, pkg_path='/var/db/pkg', chroot_path='/'): self.chroot_path = chroot_path - self._get_package_atom(package_atom) - - if 'contents' in self._atom_dictionary: - self.contents_file_path = self._atom_dictionary['contents'] - else: - if ('name' in self._atom_dictionary and - 'category' in self._atom_dictionary): - self.contents_file_path = '{0}/{1}/{2}'.format( - pkg_path, - self._atom_dictionary['category'], - self._atom_dictionary['name']) - if chroot_path != '/': - self.contents_file_path = join_paths( - chroot_path, - self.contents_file_path) - else: - raise PackageError( - "Incorrect 'pakage_atom' value: '{}', type: '{}'". - format(package_atom, type(package_atom))) + self.contents_file_path = self._get_contents_path(package_atom) + if (chroot_path != '/' and + not self.contents_file_path.startswith(chroot_path)): + self.contents_file_path = join_paths(chroot_path, + self.contents_file_path) if not os.path.exists(self.contents_file_path): raise PackageError("Can not find CONTENTS file in path: {}".format( @@ -491,17 +512,17 @@ class Package: self.contents_dictionary = OrderedDict() self.read_contents_file() - def _get_package_atom(self, package_atom): - print('in get package: {}'.format(package_atom)) + def _get_contents_path(self, package_atom): if isinstance(package_atom, str): package_atom_parser = PackageAtomParser( chroot_path=self.chroot_path) - package_atom_parser.parse_package_parameter(package_atom) - self._atom_dictionary = package_atom_parser.atom_dictionary - elif isinstance(package_atom, PackageAtomParser): - self._atom_dictionary = package_atom._atom_dictionary - elif isinstance(package_atom, dict): - self._atom_dictionary = package_atom + atom_name = package_atom_parser.parse_package_parameter( + package_atom) + return os.path.join(atom_name.pkg_path, + 'CONTENTS') + if isinstance(package_atom, PackageAtomName): + return os.path.join(package_atom.pkg_path, + 'CONTENTS') else: raise PackageError( "Incorrect 'pakage_atom' value: '{}', type: '{}''". diff --git a/tests/templates/test_directory_processor.py b/tests/templates/test_directory_processor.py index 431ab34..3250d94 100644 --- a/tests/templates/test_directory_processor.py +++ b/tests/templates/test_directory_processor.py @@ -45,16 +45,15 @@ datavars = Variables({'install': install, @pytest.mark.directory_processor class TestDirectoryProcessor: def test_just_for_debug(self): - start_time = time.time() - try: - dir_processor = DirectoryProcessor( - 'install', - datavars_module=datavars, - package='xfce-extra/xfce4-screenshooter', - test_mode=True) - dir_processor.process_template_directories() - except Exception as error: - pytest.fail('Unexpected exception: {}'.format(str(error))) + # start_time = time.time() + # try: + dir_processor = DirectoryProcessor( + 'install', + datavars_module=datavars, + without_execution=True) + dir_processor.process_template_directories() + # except Exception as error: + # pytest.fail('Unexpected exception: {}'.format(str(error))) # print('time: {}'.format(time.time() - start_time)) - # assert False + assert False diff --git a/tests/utils/test_package.py b/tests/utils/test_package.py index 52abdb5..a2bff47 100644 --- a/tests/utils/test_package.py +++ b/tests/utils/test_package.py @@ -15,6 +15,35 @@ package_atom = PackageAtomParser(chroot_path=CHROOT_PATH) @pytest.mark.package_utils class TestContents: + def test_if_two_Version_objects_compared_using_lt_operation_and_the_left_version_value_is_less_than_the_right_version__the_result_of_the_comparing_would_be_True(self): + version_1 = Version('12.5.6-r1') + version_2 = Version('12.7.6') + assert version_1 < version_2 + + def test_if_two_Version_objects_compared_using_le_operation_and_the_left_version_value_is_less_than_or_equal_to_the_right_version__the_result_of_the_comparing_would_be_True(self): + version_1 = Version('3.7.2-r1') + version_2 = Version('3.9') + version_3 = Version('3.9.0') + assert (version_1 <= version_2 and version_2 <= version_3) + + def test_if_two_Version_objects_compared_using_gt_operation_and_the_left_version_value_is_less_than_the_right_version__the_result_of_the_comparing_would_be_True(self): + version_1 = Version('3.5.6-r1') + version_2 = Version('2.5.6') + assert version_1 > version_2 + + def test_if_two_Version_objects_compared_using_ge_operation_and_the_left_version_value_is_less_than_or_equal_to_the_right_version__the_result_of_the_comparing_would_be_True(self): + version_1 = Version('13.0') + version_2 = Version('12.7.6-r1') + assert (version_1 >= version_2 and version_2 >= '12.7.6') + + def test_if_two_Version_objects_compared_using_ne_operation_and_the_left_version_value_is_less_than_or_equal_to_the_right_version__the_result_of_the_comparing_would_be_True(self): + version_1 = Version('13.0') + assert (version_1 != '12.7.6') + + def test_if_two_Version_objects_compared_using_eq_operation_and_the_left_version_value_is_less_than_or_equal_to_the_right_version__the_result_of_the_comparing_would_be_True(self): + version_1 = Version('13.1.0') + assert (version_1 == '13.1') + def test_if_PackageContents_object_initialized_by_existing_package__it_contains_dictionary_of_items_from_contents_file(self): result = OrderedDict({ '/usr': @@ -104,81 +133,75 @@ sym /etc/test_dir_2/symlink -> file_2.cfg 1587117567 print(contents_object.render_contents_file()) assert contents_object.render_contents_file() == result - def test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_but_without_a_slot_and_use_flags__the_PackageAtom_object_contains_name_and_category_values(self): - package_atom.parse_package_parameter('dev-lang/python-3.6.9') - parsing_result = { - 'category': 'dev-lang', - 'contents': join_paths( - CHROOT_PATH, - '/var/db/pkg/dev-lang/python-3.6.9/CONTENTS'), - 'name': 'python-3.6.9', - 'version': Version('3.6.9') - } - assert package_atom._atom_dictionary == parsing_result - - def test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_a_slot_value__the_PackageAtom_object_contains_name_category_values_and_slot_value(self): - package_atom.parse_package_parameter('dev-lang/python-3.6:3.6/3.6m') - parsing_result = { - 'category': 'dev-lang', - 'contents': join_paths( - CHROOT_PATH, - '/var/db/pkg/dev-lang/python-3.6.9/CONTENTS'), - 'name': 'python-3.6.9', - 'version': Version('3.6.9'), - 'slot': '3.6/3.6m' - } - assert package_atom._atom_dictionary == parsing_result - - def test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_an_empty_slot_value__the_PackageAtom_object_contains_name_category_values_and_slot_value(self): - package_atom.parse_package_parameter('dev-lang/python-3.6:') - parsing_result = { - 'category': 'dev-lang', - 'contents': join_paths( - CHROOT_PATH, - '/var/db/pkg/dev-lang/python-3.6.9/CONTENTS'), - 'name': 'python-3.6.9', - 'version': Version('3.6.9') - } - assert package_atom._atom_dictionary == parsing_result - - def test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_a_uses_value__the_PackageAtom_object_contains_name_category_values_and_slot_value(self): - package_atom.parse_package_parameter('dev-lang/python-3.6 [abi_x86_64 ssl]') - parsing_result = { - 'category': 'dev-lang', - 'contents': join_paths( + def test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_but_without_a_slot_and_use_flags__the_PackageAtom_object_returns_atom_name_of_package(self): + atom_name = package_atom.parse_package_parameter( + 'dev-lang/python-3.6.9') + + assert (atom_name.category == 'dev-lang' and + atom_name.name == 'python-3.6.9' and + atom_name.version == Version('3.6.9') and + atom_name.pkg_path == join_paths( CHROOT_PATH, - '/var/db/pkg/dev-lang/python-3.6.9/CONTENTS'), - 'name': 'python-3.6.9', - 'use_flags': ['abi_x86_64', 'ssl'], - 'version': Version('3.6.9') - } - assert package_atom._atom_dictionary == parsing_result + '/var/db/pkg/dev-lang/python-3.6.9')) + + def test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_a_slot_value__the_PackageAtom_returns_atom_name_of_package_with_this_slot(self): + atom_name = package_atom.parse_package_parameter( + 'dev-lang/python-3.6:3.6/3.6m') + + assert (atom_name.category == 'dev-lang' and + atom_name.name == 'python-3.6.9' and + atom_name.version == Version('3.6.9') and + atom_name.pkg_path == join_paths( + CHROOT_PATH, + '/var/db/pkg/dev-lang/python-3.6.9') and + atom_name.slot == '3.6/3.6m') + + def test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_an_empty_slot_value__the_PackageAtom_object_returns_atom_name_of_package(self): + atom_name = package_atom.parse_package_parameter( + 'dev-lang/python-3.6:') + assert (atom_name.category == 'dev-lang' and + atom_name.name == 'python-3.6.9' and + atom_name.version == Version('3.6.9') and + atom_name.pkg_path == join_paths( + CHROOT_PATH, + '/var/db/pkg/dev-lang/python-3.6.9')) + + def test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_a_uses_value__the_PackageAtom_object_returns_atom_name_of_package_with_this_use_flags(self): + atom_name = package_atom.parse_package_parameter( + 'dev-lang/python-3.6 [abi_x86_64 ssl]') + + assert (atom_name.category == 'dev-lang' and + atom_name.name == 'python-3.6.9' and + atom_name.version == Version('3.6.9') and + atom_name.pkg_path == join_paths( + CHROOT_PATH, + '/var/db/pkg/dev-lang/python-3.6.9') and + 'abi_x86_64' in atom_name.use_flags and + 'ssl' in atom_name.use_flags) def test_if_the_PackageAtom_object_parses_a_correct_package_atom_name_without_version_value_but_with_slot_value__the_PackageAtom_object_looks_for_package_with_assigned_slot_value(self): - package_atom.parse_package_parameter('dev-lang/python:3.6/3.6m') - parsing_result = { - 'category': 'dev-lang', - 'contents': join_paths( - CHROOT_PATH, - '/var/db/pkg/dev-lang/python-3.6.9/CONTENTS'), - 'name': 'python-3.6.9', - 'slot': '3.6/3.6m', - 'version': Version('3.6.9') - } - assert package_atom._atom_dictionary == parsing_result + atom_name = package_atom.parse_package_parameter( + 'dev-lang/python:3.6/3.6m') + + assert (atom_name.category == 'dev-lang' and + atom_name.name == 'python-3.6.9' and + atom_name.version == Version('3.6.9') and + atom_name.pkg_path == join_paths( + CHROOT_PATH, + '/var/db/pkg/dev-lang/python-3.6.9') and + atom_name.slot == '3.6/3.6m') def test_if_the_PackageAtom_object_parses_a_correct_package_atom_name_without_version_value_but_with_use_flags_value__the_PackageAtom_object_looks_for_package_with_assigned_use_flags(self): - package_atom.parse_package_parameter('dev-lang/python [specific_flag]') - parsing_result = { - 'category': 'dev-lang', - 'contents': join_paths( - CHROOT_PATH, - '/var/db/pkg/dev-lang/python-3.6.9/CONTENTS'), - 'name': 'python-3.6.9', - 'use_flags': ['specific_flag'], - 'version': Version('3.6.9') - } - assert package_atom._atom_dictionary == parsing_result + atom_name = package_atom.parse_package_parameter( + 'dev-lang/python [specific_flag]') + + assert (atom_name.category == 'dev-lang' and + atom_name.name == 'python-3.6.9' and + atom_name.version == Version('3.6.9') and + atom_name.pkg_path == join_paths( + CHROOT_PATH, + '/var/db/pkg/dev-lang/python-3.6.9') and + 'specific_flag' in atom_name.use_flags) def test_if_the_PackageAtom_object_tried_to_parse_an_incorrect_package_atom_name__the_PackageAtom_object_throws_the_PackageAtomError_exception(self): with pytest.raises(PackageAtomError): @@ -188,19 +211,17 @@ sym /etc/test_dir_2/symlink -> file_2.cfg 1587117567 def test_if_the_PackageAtom_object_tried_to_parse_an_package_atom_name_with_incorrect_use_flags__the_PackageAtom_object_throws_the_PackageAtomError_exception(self): with pytest.raises(PackageAtomError): package_atom.parse_package_parameter( - 'dev-lang/python [strange_use]') + 'dev-lang/python [strange_use]') - def test_if_the_PackageAtom_object_tried_to_parse_an_correct_package_atom_name_that_matches_multiple_packages__the_PackageAtom_object_gets_info_for_package_with_olader_version(self): - package_atom.parse_package_parameter('dev-lang/python') - parsing_result = { - 'category': 'dev-lang', - 'contents': join_paths( - CHROOT_PATH, - '/var/db/pkg/dev-lang/python-3.6.9/CONTENTS'), - 'name': 'python-3.6.9', - 'version': Version('3.6.9') - } - assert package_atom._atom_dictionary == parsing_result + def test_if_the_PackageAtom_object_tried_to_parse_an_correct_package_atom_name_that_matches_multiple_packages__the_PackageAtom_object_gets_info_for_package_with_older_version(self): + atom_name = package_atom.parse_package_parameter('dev-lang/python') + + assert (atom_name.category == 'dev-lang' and + atom_name.name == 'python-3.6.9' and + atom_name.version == Version('3.6.9') and + atom_name.pkg_path == join_paths( + CHROOT_PATH, + '/var/db/pkg/dev-lang/python-3.6.9')) def test_if_the_get_file_package_method_of_the_PackageAtom_object_is_called_with_a_name_of_a_file_that_belongs_to_any_package__the_PackageAtom_object_contains_dictionary_with_an_owner_package(self): package_atom_regex = re.compile(r'dev-lang/python-3(\.\d+)+')