def test_score_multiple_one_path(self): package_tuple1 = ("flask", "1.0.2", "https://pypi.org/simple") package_tuple2 = ("werkzeug", "0.15.4", "https://pypi.org/simple") package_tuple3 = ("click", "0.1.2", "https://pypi.org/simple") dg = DependencyGraphAdaptation.from_paths( direct_dependencies=[package_tuple1], paths=[ (package_tuple1, package_tuple2), (package_tuple2, package_tuple3), ]) dg.score_package_tuple(package_tuple1, 2.0) dg.score_package_tuple(package_tuple2, 1.0) pairs = list( sorted(dg.to_scored_package_tuple_pairs(), key=operator.itemgetter(0))) pairs_expected = [ (0.0, (package_tuple2, package_tuple3)), (1.0, (package_tuple1, package_tuple2)), (2.0, (None, package_tuple1)), ] assert pairs == pairs_expected
def test_remove_transitive_cyclic(self): package_tuple1 = ("flask", "1.0.2", "https://pypi.org/simple") package_tuple2 = ("werkzeug", "0.15.4", "https://pypi.org/simple") package_tuple3 = ("click", "0.1.2", "https://pypi.org/simple") package_tuple4 = ("werkzeug", "0.16.0", "https://pypi.org/simple") package_tuple5 = ("click", "1.0.0", "https://pypi.org/simple") dg = DependencyGraphAdaptation.from_paths( direct_dependencies=[package_tuple1], paths=[ (package_tuple1, package_tuple2), (package_tuple2, package_tuple3), (package_tuple3, package_tuple2), (package_tuple1, package_tuple4), (package_tuple4, package_tuple5), ]) with dg.remove_package_tuples(package_tuple3) as txn: txn.commit() pairs = dg.to_scored_package_tuple_pairs() pairs_expected = [ (0.0, (None, package_tuple1)), (0.0, (package_tuple1, package_tuple4)), (0.0, (package_tuple4, package_tuple5)), ] assert pairs == pairs_expected
def from_paths( cls, direct_dependencies: Dict[Tuple[str, str, str], PackageVersion], paths: Dict[Tuple[str, str, str], List[Tuple[Tuple[str, str, str], Tuple[str, str, str]]]], ) -> "StepContext": """Instantiate step context from paths.""" packages = dict(direct_dependencies) unsolved_packages = {} for direct_dependency_tuple, dependency_paths in paths.items(): for package_tuples in dependency_paths: for package_tuple in package_tuples: if package_tuple in packages: continue if cls.is_unsolved_package_tuple(package_tuple): # Not fully resolved yet. key = (package_tuple[0], package_tuple[1], None) if key not in unsolved_packages: unsolved_packages[key] = UnsolvedPackage( package_name=package_tuple[0], package_version=package_tuple[1], develop=direct_dependencies[ direct_dependency_tuple].develop, ) else: package_version = PackageVersion( name=package_tuple[0], version="==" + package_tuple[1], develop=direct_dependencies[ direct_dependency_tuple].develop, index=Source(package_tuple[2]), ) packages[package_tuple] = package_version path_tuples = [] for dependency_paths in paths.values(): for path in dependency_paths: path_tuples.append(path) _LOGGER.debug( "Total number of packages considered including all transitive dependencies: %d", len(packages)) _LOGGER.debug( "Total number of unsolved packages in the dependency graph: %d", len(unsolved_packages)) _LOGGER.info( "Instantiating step context and constructing dependency graph adaptation" ) return cls( packages=packages, unsolved_packages=unsolved_packages, dependency_graph_adaptation=DependencyGraphAdaptation.from_paths( direct_dependencies=direct_dependencies.keys(), paths=path_tuples, ), )
def test_score_one(self): package_tuple = ("daiquiri", "1.5.0", "https://pypi.org/simple") dg = DependencyGraphAdaptation.from_paths( direct_dependencies=[package_tuple], paths=[], ) dg.score_package_tuple(package_tuple, 2.0) dg.score_package_tuple(package_tuple, 1.0) pairs = dg.to_scored_package_tuple_pairs() assert pairs == [(3.0, (None, package_tuple))]
def test_remove_direct_one_error(self): package_tuple1 = ("flask", "1.0.2", "https://pypi.org/simple") package_tuple2 = ("werkzeug", "0.15.4", "https://pypi.org/simple") dg = DependencyGraphAdaptation.from_paths( direct_dependencies=[package_tuple1], paths=[(package_tuple1, package_tuple2)]) with pytest.raises(CannotRemovePackage): with dg.remove_package_tuples(package_tuple1): pass pairs = dg.to_scored_package_tuple_pairs() pairs_expected = [(0.0, (None, package_tuple1)), (0.0, (package_tuple1, package_tuple2))] assert pairs == pairs_expected
def test_remove_transitive_one_error(self): package_tuple0 = ("daiquiri", "1.5.0", "https://pypi.org/simple") package_tuple1 = ("flask", "1.0.2", "https://pypi.org/simple") package_tuple2 = ("werkzeug", "0.15.4", "https://pypi.org/simple") package_tuple3 = ("click", "0.1.2", "https://pypi.org/simple") dg = DependencyGraphAdaptation.from_paths( direct_dependencies=[package_tuple0, package_tuple1], paths=[ (package_tuple1, package_tuple2), (package_tuple2, package_tuple3), ]) with pytest.raises(CannotRemovePackage): with dg.remove_package_tuples(package_tuple3): pass
def test_score_multiple_paths(self): package_tuple0 = ("daiquiri", "1.5.0", "https://pypi.org/simple") package_tuple1 = ("flask", "1.0.2", "https://pypi.org/simple") package_tuple2 = ("werkzeug", "0.15.4", "https://pypi.org/simple") package_tuple3 = ("click", "0.1.2", "https://pypi.org/simple") package_tuple4 = ("click", "0.2.0", "https://pypi.org/simple") package_tuple5 = ("werkzeug", "0.16.0", "https://pypi.org/simple") dg = DependencyGraphAdaptation.from_paths( direct_dependencies=[ package_tuple0, package_tuple1, ], paths=[ (package_tuple1, package_tuple2), (package_tuple2, package_tuple3), (package_tuple1, package_tuple2), (package_tuple2, package_tuple4), (package_tuple1, package_tuple5), (package_tuple5, package_tuple4), (package_tuple1, package_tuple5), (package_tuple5, package_tuple3), ]) dg.score_package_tuple(package_tuple1, +2.0) dg.score_package_tuple(package_tuple2, +1.0) dg.score_package_tuple(package_tuple5, -1.0) dg.score_package_tuple(package_tuple4, -3.0) dg.score_package_tuple(package_tuple5, -1.0) pairs = list( sorted(dg.to_scored_package_tuple_pairs(), key=operator.itemgetter(0))) pairs_expected = [(-3.0, (package_tuple2, package_tuple4)), (-3.0, (package_tuple5, package_tuple4)), (-2.0, (package_tuple1, package_tuple5)), (0.0, (None, package_tuple0)), (0.0, (package_tuple2, package_tuple3)), (0.0, (package_tuple5, package_tuple3)), (1.0, (package_tuple1, package_tuple2)), (2.0, (None, package_tuple1))] assert pairs == pairs_expected
def test_remove_direct_multiple(self): package_tuple1 = ("flask", "1.0.2", "https://pypi.org/simple") package_tuple2 = ("flask", "0.12.0", "https://pypi.org/simple") package_tuple3 = ("werkzeug", "0.15.4", "https://pypi.org/simple") dg = DependencyGraphAdaptation.from_paths( direct_dependencies=[package_tuple1, package_tuple2], paths=[ (package_tuple1, package_tuple3), (package_tuple2, package_tuple3), ]) with dg.remove_package_tuples(package_tuple1) as txn: txn.commit() pairs = dg.to_scored_package_tuple_pairs() pairs_expected = [ (0.0, (None, package_tuple2)), (0.0, (package_tuple2, package_tuple3)), ] assert pairs == pairs_expected
def test_empty_paths(self): direct_dependencies = [("selinon", "1.0.0", "https://pypi.org/simple")] dg = DependencyGraphAdaptation.from_paths(direct_dependencies, []) pairs = dg.to_scored_package_tuple_pairs() assert pairs == [(0.0, (None, ('selinon', '1.0.0', 'https://pypi.org/simple')))]
def test_empty(self): with pytest.raises(ValueError): DependencyGraphAdaptation.from_paths([], [])