def setUp(self): # Build some test RPMs with some dependencies on each other self.rpm_0 = _make_unit( models.RPM, 'firefox', '0', '23.0.0', '1', 'x86_64', 'sha256', 'some_sum', requires=[{'name': 'xulrunner', 'version': '23.0', 'release': '1', 'flags': depsolve.Requirement.GE}], provides=[{'name': 'webbrowser'}]) self.rpm_1 = _make_unit( models.RPM, 'firefox', '0', '23.0.2', '1', 'x86_64', 'sha256', 'some_sum', requires=[{'name': 'xulrunner', 'version': '23.0', 'release': '1', 'flags': depsolve.Requirement.GE}], provides=[{'name': 'webbrowser'}]) self.rpm_2 = _make_unit( models.RPM, 'xulrunner', '0', '23.0.1', '1', 'x86_64', 'sha256', 'some_sum', requires=[{'name': 'sqlite', 'version': '3.7.17', 'flags': depsolve.Requirement.GE}]) self.rpm_3 = _make_unit( models.RPM, 'sqlite', '0', '3.7.17', '1', 'x86_64', 'sha256', 'some_sum', requires=[]) # Nothing depends on this one, so it shouldn't be returned by anything self.rpm_4 = _make_unit( models.RPM, 'gnome-calculator', '0', '3.8.2', '1', 'x86_64', 'sha256', 'some_sum', requires=[{'name': 'glib2'}], provides=[{'name': 'calculator'}]) self.rpm_5 = _make_unit( models.RPM, 'glib2', '0', '2.36.3', '3', 'x86_64', 'sha256', 'some_sum', requires=[]) self.rpm_6 = _make_unit( models.RPM, 'gcalctool', '0', '5.28.2', '3', 'x86_64', 'sha256', 'some_sum', requires=[], provides=[{'name': 'calculator'}]) # list of all the rpms just created so they can be easily modified in bulk if needed self.rpms = [getattr(self, 'rpm_%s' % i) for i in range(7)] # fake repo for the solver to use, just needs a repo_id self.repo = mock.Mock() self.repo.repo_id = 'depsolving_repo' # the main thing being tested, the dependency Solver self.solver = depsolve.Solver(self.repo) # replace calls out to the repo controller by mocking out the unit generator, since # the repo controller will try to read from the db and never find matches there # to properly use this mock, you probably want to use self._rpm_generator, # since it has the same return signature as Solver._unit_generator search_patcher = mock.patch.object(depsolve.Solver, '_unit_generator') self.unit_generator = search_patcher.start() self.addCleanup(search_patcher.stop)
def setUp(self): """ Build some test RPMs with some dependencies. """ self.rpm_0 = models.RPM( 'firefox', '0', '23.0.0', '1', 'x86_64', 'sha256', 'some_sum', {'requires': [{'name': 'xulrunner', 'version': '23.0', 'release': '1', 'flags': depsolve.Requirement.GE}], 'provides': [{'name': 'webbrowser'}]}) self.rpm_1 = models.RPM( 'firefox', '0', '23.0.2', '1', 'x86_64', 'sha256', 'some_sum', {'requires': [{'name': 'xulrunner', 'version': '23.0', 'release': '1', 'flags': depsolve.Requirement.GE}], 'provides': [{'name': 'webbrowser'}]}) self.rpm_2 = models.RPM( 'xulrunner', '0', '23.0.1', '1', 'x86_64', 'sha256', 'some_sum', {'requires': [{'name': 'sqlite', 'version': '3.7.17', 'flags': depsolve.Requirement.GE}]}) self.rpm_3 = models.RPM( 'sqlite', '0', '3.7.17', '1', 'x86_64', 'sha256', 'some_sum', {'requires': []}) # Nothing depends on this one, so it shouldn't be returned by anything self.rpm_4 = models.RPM( 'gnome-calculator', '0', '3.8.2', '1', 'x86_64', 'sha256', 'some_sum', {'requires': [{'name': 'glib2'}], 'provides': [{'name': 'calculator'}]}) self.rpm_5 = models.RPM( 'glib2', '0', '2.36.3', '3', 'x86_64', 'sha256', 'some_sum', {'requires': []}) self.rpm_6 = models.RPM( 'gcalctool', '0', '5.28.2', '3', 'x86_64', 'sha256', 'some_sum', {'requires': [], 'provides': [{'name': 'calculator'}]}) self.rpms = [getattr(self, 'rpm_%s' % i) for i in range(7)] self._make_units(self.rpms) self.mock_search = mock.MagicMock() self.solver = depsolve.Solver(self.mock_search)
def copy_rpms(units, source_repo, dest_repo, import_conduit, copy_deps, solver=None): """ Copy RPMs from the source repo to the destination repo, and optionally copy dependencies as well. Dependencies are resolved recursively. :param units: iterable of Units :type units: iterable of pulp_rpm.plugins.db.models.RPM :param source_repo: The repository we are copying units from. :type source_repo: pulp.server.db.model.Repository :param dest_repo: The repository we are copying units to :type dest_repo: pulp.server.db.model.Repository :param import_conduit: import conduit passed to the Importer :type import_conduit: pulp.plugins.conduits.unit_import.ImportUnitConduit :param copy_deps: if True, copies dependencies as specified in "Requires" lines in the RPM metadata. Matches against NEVRAs and Provides declarations that are found in the source repository. Silently skips any dependencies that cannot be resolved within the source repo. :param solver: an object that can be used for dependency solving. this is useful so that data can be cached in the depsolving object and re-used by each iteration of this method. :type solver: pulp_rpm.plugins.importers.yum.depsolve.Solver :return: set of pulp.plugins.models.Unit that were copied :rtype: set """ unit_set = set() for unit in units: # we are passing in units that may have flattened "provides" metadata. # This flattened field is not used by associate_single_unit(). repo_controller.associate_single_unit(dest_repo, unit) unit_set.add(unit) if copy_deps and unit_set: if solver is None: solver = depsolve.Solver(source_repo) # This returns units that have a flattened 'provides' metadata field # for memory purposes (RHBZ #1185868) deps = solver.find_dependent_rpms(unit_set) # remove rpms already in the destination repo existing_units = set( existing.get_existing_units([dep.unit_key for dep in deps], models.RPM, dest_repo)) # the hash comparison for Units is unit key + type_id, the metadata # field is not used. to_copy = deps - existing_units _LOGGER.debug('Copying deps: %s' % str(sorted([x.name for x in to_copy]))) if to_copy: unit_set |= copy_rpms(to_copy, source_repo, dest_repo, import_conduit, copy_deps, solver) return unit_set