def check_range(self, vuln_range, ver_matches, ver_nonmatches): self.mk_glsa([("dev-util/diffball", ([], [vuln_range]))]) restrict = list(OrRestriction(*tuple(glsa.GlsaDirSet(self.dir)))) self.assertEqual(len(restrict), 1) restrict = restrict[0] for ver in ver_matches: pkg = cpv.versioned_CPV("dev-util/diffball-%s" % ver) self.assertTrue(restrict.match(pkg), msg="pkg %s must match for %r: %s" % (pkg, vuln_range, restrict)) for ver in ver_nonmatches: pkg = cpv.versioned_CPV("dev-util/diffball-%s" % ver) self.assertFalse(restrict.match(pkg), msg="pkg %s must not match for %r: %s" % (pkg, vuln_range, restrict))
def _simple_redirect_test(self, attr, arg1='=dev-util/diffball-1.0', arg2=None): l = [] uniq_obj = object() def f(*a, **kw): a = a[1:-1] l.extend((a, kw)) return uniq_obj # if replace, override _replace since replace reflects to it class my_ops(operations): locals()['_cmd_implementation_%s' % attr] = f self.repo.operations_kls = my_ops args = [self.repo.match(atom(arg1))] if arg2: args.append(versioned_CPV(arg2)) self.repo.frozen = False op = getattr(self.repo.operations, attr) def simple_check(op, args, **kw): l[:] = [] self.assertEqual(op(*args, **kw), uniq_obj) self.assertEqual(len(l), 2) self.assertEqual(list(l[0]), args) self.assertTrue(l) self.assertTrue(self.repo.operations.supports(attr)) simple_check(op, args) self.assertFalse(l[1]) simple_check(op, args) self.assertNotIn('force', l[1]) self.repo.frozen = True self.assertFalse(self.repo.operations.supports(attr)) self.assertFalse(hasattr(self.repo.operations, attr))
def test_iter(self): self.assertEqual( sorted(self.repo), sorted(versioned_CPV(x) for x in ( "dev-util/diffball-1.0", "dev-util/diffball-0.7", "dev-util/bsdiff-0.4.1", "dev-util/bsdiff-0.4.2", "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1")))
def test_notify_add(self): pkg = versioned_CPV("dev-util/diffball-1.2") self.repo.notify_add_package(pkg) self.assertEqual(sorted(self.repo.versions[(pkg.category, pkg.package)]), sorted(["1.0", "1.2", "0.7"])) pkg = versioned_CPV("foo/bar-1.0") self.repo.notify_add_package(pkg) self.assertIn(pkg.category, self.repo.categories) self.assertIn(pkg.category, self.repo.packages) ver_key = (pkg.category, pkg.package) self.assertIn(ver_key, self.repo.versions) self.assertEqual(list(self.repo.versions[ver_key]), ["1.0"]) pkg = versioned_CPV("foo/cows-1.0") self.repo.notify_add_package(pkg) self.assertIn((pkg.category, pkg.package), self.repo.versions)
def test_filtering(self): repo, vrepo = self.setup_repos() a = atom("dev-lib/fake") a2 = atom("dev-util/diffball") self.assertEqual( sorted(vrepo.itermatch(a)), sorted(repo.itermatch(a))) self.assertEqual(sorted(vrepo.itermatch(a2)), sorted([])) repo, vrepo = self.setup_repos(atom("=dev-util/diffball-1.0")) self.assertEqual( sorted(vrepo.itermatch(a)), sorted(repo.itermatch(a))) self.assertEqual( sorted(vrepo.itermatch(a2)), sorted([versioned_CPV("dev-util/diffball-0.7")])) repo, vrepo = self.setup_repos(packages.PackageRestriction( "package", values.OrRestriction( *[values.StrExactMatch(x) for x in ("diffball", "fake")]))) self.assertEqual( sorted(vrepo.itermatch(packages.AlwaysTrue)), sorted(repo.itermatch(atom("dev-util/bsdiff")))) # check sentinel value handling. vrepo = filtered.tree(repo, a2, sentinel_val=True) self.assertEqual( sorted(x.cpvstr for x in vrepo), sorted(['dev-util/diffball-0.7', 'dev-util/diffball-1.0']))
def __init__(self, cpvstr, mtime, data=None, shared=None, repo=None): if data is None: data = {} cpv = versioned_CPV(cpvstr) package.__init__(self, shared, repo, cpv.category, cpv.package, cpv.fullver) object.__setattr__(self, "data", data) object.__setattr__(self, "_mtime_", mtime)
def test_notify_add(self): pkg = versioned_CPV("dev-util/diffball-1.2") self.repo.notify_add_package(pkg) self.assertEqual(sorted(self.repo.versions[ (pkg.category, pkg.package)]), sorted(["1.0", "1.2", "0.7"])) pkg = versioned_CPV("foo/bar-1.0") self.repo.notify_add_package(pkg) self.assertIn(pkg.category, self.repo.categories) self.assertIn(pkg.category, self.repo.packages) ver_key = (pkg.category, pkg.package) self.assertIn(ver_key, self.repo.versions) self.assertEqual(list(self.repo.versions[ver_key]), ["1.0"]) pkg = versioned_CPV("foo/cows-1.0") self.repo.notify_add_package(pkg) self.assertIn((pkg.category, pkg.package), self.repo.versions)
def test_pkg_groupped_iter(self): self.mk_glsa(pkgs_set + (("dev-util/bsdiff", ([], ["~>=2-r1"])),)) g = glsa.GlsaDirSet(self.dir) l = list(g.pkg_grouped_iter()) self.assertEqual([x.key for x in l], ["dev-util/diffball", "dev-util/bsdiff"]) # main interest is dev-util/bsdiff r = l[1] pkgs = [cpv.versioned_CPV("dev-util/bsdiff-%s" % ver) for ver in ("0", "1", "1.1", "2", "2-r1")] self.assertEqual([x.fullver for x in pkgs if r.match(x)], ["1.1", "2-r1"])
def check_range(self, vuln_range, ver_matches, ver_nonmatches): self.mk_glsa([("dev-util/diffball", ([], [vuln_range]))]) restrict = list(OrRestriction(*tuple(glsa.GlsaDirSet(self.dir)))) if len(restrict) == 0: # exception thrown restrict.append(AlwaysBool(negate=False)) self.assertEqual(len(restrict), 1) restrict = restrict[0] for ver in ver_matches: pkg = cpv.versioned_CPV(f"dev-util/diffball-{ver}") self.assertTrue( restrict.match(pkg), msg=f"pkg {pkg} must match for {vuln_range!r}: {restrict}") for ver in ver_nonmatches: pkg = cpv.versioned_CPV(f"dev-util/diffball-{ver}") self.assertFalse( restrict.match(pkg), msg="pkg {pkg} must not match for {vuln_range!r}: {restrict}")
def test_notify_remove(self): pkg = versioned_CPV("dev-util/diffball-1.0") self.repo.notify_remove_package(pkg) self.assertEqual(list(self.repo.versions[(pkg.category, pkg.package)]), ["0.7"]) # test version being emptied, and package updated pkg = versioned_CPV("dev-util/diffball-0.7") self.repo.notify_remove_package(pkg) self.assertNotIn((pkg.category, pkg.package), self.repo.versions) self.assertNotIn(pkg.package, self.repo.packages[pkg.category]) # test no remaining packages, category updated pkg = versioned_CPV("dev-util/bsdiff-0.4.1") self.repo.notify_remove_package(pkg) pkg = versioned_CPV("dev-util/bsdiff-0.4.2") self.repo.notify_remove_package(pkg) self.assertNotIn((pkg.category, pkg.package), self.repo.versions) self.assertNotIn(pkg.category, self.repo.packages) self.assertNotIn(pkg.category, self.repo.categories)
def __init__(self, cpvstr, repo, data=None, shared=None): if data is None: data = {} cpv = versioned_CPV(cpvstr) super().__init__(shared, factory(repo), cpv.category, cpv.package, cpv.fullver) object.__setattr__(self, "data", data) object.__setattr__( self, "path", pjoin(repo.location, cpv.category, cpv.package, f'{cpv.package}-{cpv.fullver}.ebuild'))
def test_pkg_grouped_iter(self): self.mk_glsa(pkgs_set + (("dev-util/bsdiff", ([], ["~>=2-r1"])),)) g = glsa.GlsaDirSet(self.dir) l = list(g.pkg_grouped_iter(sorter=sorted)) self.assertEqual(set(x.key for x in l), set(['dev-util/diffball', 'dev-util/bsdiff'])) # main interest is dev-util/bsdiff r = l[0] pkgs = [cpv.versioned_CPV(f"dev-util/bsdiff-{ver}") for ver in ("0", "1", "1.1", "2", "2-r1")] self.assertEqual([x.fullver for x in pkgs if r.match(x)], ["1.1", "2-r1"])
def __init__(self, cpvstr, data=None, shared=None, parent=None): if data is None: data = {} for x in ("DEPEND", "RDEPEND", "PDEPEND", "IUSE", "LICENSE"): data.setdefault(x, "") cpv = versioned_CPV(cpvstr) package.__init__(self, shared, parent, cpv.category, cpv.package, cpv.fullver) package.local_use = ImmutableDict() object.__setattr__(self, "data", data)
def test_notify_remove(self): pkg = versioned_CPV("dev-util/diffball-1.0") self.repo.notify_remove_package(pkg) self.assertEqual(list(self.repo.versions[ (pkg.category, pkg.package)]), ["0.7"]) # test version being emptied, and package updated pkg = versioned_CPV("dev-util/diffball-0.7") self.repo.notify_remove_package(pkg) self.assertNotIn((pkg.category, pkg.package), self.repo.versions) self.assertNotIn(pkg.package, self.repo.packages[pkg.category]) # test no remaining packages, category updated pkg = versioned_CPV("dev-util/bsdiff-0.4.1") self.repo.notify_remove_package(pkg) pkg = versioned_CPV("dev-util/bsdiff-0.4.2") self.repo.notify_remove_package(pkg) self.assertNotIn((pkg.category, pkg.package), self.repo.versions) self.assertNotIn(pkg.category, self.repo.packages) self.assertNotIn(pkg.category, self.repo.categories)
def test_pkg_grouped_iter(self): self.mk_glsa(pkgs_set + (("dev-util/bsdiff", ([], ["~>=2-r1"])), )) g = glsa.GlsaDirSet(self.dir) l = list(g.pkg_grouped_iter(sorter=sorted)) self.assertEqual(set(x.key for x in l), set(['dev-util/diffball', 'dev-util/bsdiff'])) # main interest is dev-util/bsdiff r = l[0] pkgs = [ cpv.versioned_CPV("dev-util/bsdiff-%s" % ver) for ver in ("0", "1", "1.1", "2", "2-r1") ] self.assertEqual([x.fullver for x in pkgs if r.match(x)], ["1.1", "2-r1"])
def _get_packages(self, category): cpath = pjoin(self.location, category.lstrip(os.path.sep)) l = set() d = {} bad = False try: for x in listdir_dirs(cpath): if x.startswith(".tmp.") or x.endswith(".lockfile") \ or x.startswith("-MERGING-"): continue try: pkg = versioned_CPV(category + "/" + x) except InvalidCPV: bad = True if bad or not pkg.fullver: if '-scm' in x: bad = 'scm' elif '-try' in x: bad = 'try' else: raise InvalidCPV( "%s/%s: no version component" % (category, x)) logger.error( "merged -%s pkg detected: %s/%s. " "throwing exception due to -%s not being a valid" " version component. Silently ignoring that " "specific version is not viable either since it " "would result in pkgcore stomping whatever it was " "that -%s version merged. " "This is why embrace and extend is bad, mm'kay. " "Use the offending pkg manager that merged it to " "unmerge it." % (bad, category, x, bad, bad)) raise InvalidCPV( "%s/%s: -%s version component is " "not standard." % (category, x, bad)) l.add(pkg.package) d.setdefault((category, pkg.package), []).append(pkg.fullver) except EnvironmentError as e: compatibility.raise_from(KeyError( "failed fetching packages for category %s: %s" % (pjoin(self.location, category.lstrip(os.path.sep)), str(e)))) self._versions_tmp_cache.update(d) return tuple(l)
def _get_packages(self, category): cpath = pjoin(self.location, category.lstrip(os.path.sep)) l = set() d = {} bad = False try: for x in listdir_dirs(cpath): if x.startswith(".tmp.") or x.endswith(".lockfile") \ or x.startswith("-MERGING-"): continue try: pkg = versioned_CPV(f'{category}/{x}') except InvalidCPV: bad = True if bad or not pkg.fullver: if '-scm' in x: bad = 'scm' elif '-try' in x: bad = 'try' else: raise InvalidCPV( f"{category}/{x}: no version component") logger.error( f'merged -{bad} pkg detected: {category}/{x}. ' f'throwing exception due to -{bad} not being a valid' ' version component. Silently ignoring that ' 'specific version is not viable either since it ' 'would result in pkgcore stomping whatever it was ' f'that -{bad} version merged. ' 'Use the offending pkg manager that merged it to ' 'unmerge it.') raise InvalidCPV( f"{category}/{x}: -{bad} version component is not standard." ) l.add(pkg.package) d.setdefault((category, pkg.package), []).append(pkg.fullver) except EnvironmentError as e: category = pjoin(self.location, category.lstrip(os.path.sep)) raise KeyError( f'failed fetching packages for category {category}: {e}' ) from e self._versions_tmp_cache.update(d) return tuple(l)
def _get_packages(self, category): cpath = pjoin(self.location, category.lstrip(os.path.sep)) l = set() d = {} bad = False try: for x in listdir_dirs(cpath): if x.startswith(".tmp.") or x.endswith(".lockfile") \ or x.startswith("-MERGING-"): continue try: pkg = versioned_CPV(category + "/" + x) except InvalidCPV: bad = True if bad or not pkg.fullver: if '-scm' in x: bad = 'scm' elif '-try' in x: bad = 'try' else: raise InvalidCPV("%s/%s: no version component" % (category, x)) logger.error( "merged -%s pkg detected: %s/%s. " "throwing exception due to -%s not being a valid" " version component. Silently ignoring that " "specific version is not viable either since it " "would result in pkgcore stomping whatever it was " "that -%s version merged. " "This is why embrace and extend is bad, mm'kay. " "Use the offending pkg manager that merged it to " "unmerge it.", bad, category, x, bad, bad) raise InvalidCPV("%s/%s: -%s version component is " "not standard." % (category, x, bad)) l.add(pkg.package) d.setdefault((category, pkg.package), []).append(pkg.fullver) except EnvironmentError as e: compatibility.raise_from( KeyError( "failed fetching packages for category %s: %s" % (pjoin( self.location, category.lstrip(os.path.sep)), str(e)))) self._versions_tmp_cache.update(d) return tuple(l)
def _get_packages(self, category): cpath = pjoin(self.base, category.lstrip(os.path.sep)) l = set() d = {} lext = len(self.extension) bad = False try: for x in listdir_files(cpath): # don't use lstat; symlinks may exist if (x.endswith(".lockfile") or not x[-lext:].lower() == self.extension or x.startswith(".tmp.")): continue pv = x[:-lext] try: pkg = versioned_CPV(category+"/"+pv) except InvalidCPV: bad = True if bad or not pkg.fullver: if '-scm' in pv: bad = 'scm' elif '-try' in pv: bad = 'try' else: raise InvalidCPV( "%s/%s: no version component" % (category, pv)) if self.ignore_paludis_versioning: bad = False continue raise InvalidCPV( "%s/%s: -%s version component is " "not standard." % (category, pv, bad)) l.add(pkg.package) d.setdefault((category, pkg.package), []).append(pkg.fullver) except EnvironmentError as e: raise_from(KeyError( "failed fetching packages for category %s: %s" % (pjoin(self.base, category.lstrip(os.path.sep)), str(e)))) self._versions_tmp_cache.update(d) return tuple(l)
def _get_packages(self, category): cpath = pjoin(self.location, category.lstrip(os.path.sep)) l = set() d = {} bad = False try: for x in listdir_dirs(cpath): if x.startswith(".tmp.") or x.endswith(".lockfile") \ or x.startswith("-MERGING-"): continue try: pkg = versioned_CPV(f'{category}/{x}') except InvalidCPV: bad = True if bad or not pkg.fullver: if '-scm' in x: bad = 'scm' elif '-try' in x: bad = 'try' else: raise InvalidCPV(f"{category}/{x}: no version component") logger.error( f'merged -{bad} pkg detected: {category}/{x}. ' f'throwing exception due to -{bad} not being a valid' ' version component. Silently ignoring that ' 'specific version is not viable either since it ' 'would result in pkgcore stomping whatever it was ' f'that -{bad} version merged. ' 'Use the offending pkg manager that merged it to ' 'unmerge it.') raise InvalidCPV( f"{category}/{x}: -{bad} version component is not standard.") l.add(pkg.package) d.setdefault((category, pkg.package), []).append(pkg.fullver) except EnvironmentError as e: category = pjoin(self.location, category.lstrip(os.path.sep)) raise KeyError(f'failed fetching packages for category {category}: {e}') from e self._versions_tmp_cache.update(d) return tuple(l)
def _get_packages(self, category): cpath = pjoin(self.base, category.lstrip(os.path.sep)) l = set() d = {} lext = len(self.extension) bad = False try: for x in listdir_files(cpath): # don't use lstat; symlinks may exist if (x.endswith(".lockfile") or not x[-lext:].lower() == self.extension or x.startswith(".tmp.")): continue pv = x[:-lext] pkg = versioned_CPV(f'{category}/{pv}') l.add(pkg.package) d.setdefault((category, pkg.package), []).append(pkg.fullver) except EnvironmentError as e: raise KeyError( "failed fetching packages for category %s: %s" % (pjoin(self.base, category.lstrip(os.path.sep)), str(e))) from e self._versions_tmp_cache.update(d) return tuple(l)
def test_identify_candidates(self): self.assertRaises(TypeError, self.repo.match, ("asdf")) rc = packages.PackageRestriction( "category", values.StrExactMatch("dev-util")) self.assertEqual( sorted(set(x.package for x in self.repo.itermatch(rc))), sorted(["diffball", "bsdiff"])) rp = packages.PackageRestriction( "package", values.StrExactMatch("diffball")) self.assertEqual( list(x.version for x in self.repo.itermatch(rp, sorter=sorted)), ["0.7", "1.0"]) self.assertEqual( self.repo.match(packages.OrRestriction(rc, rp), sorter=sorted), sorted(versioned_CPV(x) for x in ( "dev-util/diffball-0.7", "dev-util/diffball-1.0", "dev-util/bsdiff-0.4.1", "dev-util/bsdiff-0.4.2"))) self.assertEqual( sorted(self.repo.itermatch(packages.AndRestriction(rc, rp))), sorted(versioned_CPV(x) for x in ( "dev-util/diffball-0.7", "dev-util/diffball-1.0"))) self.assertEqual( sorted(self.repo), self.repo.match(packages.AlwaysTrue, sorter=sorted)) # mix/match cat/pkg to check that it handles that corner case # properly for sorting. self.assertEqual( sorted(self.repo, reverse=True), self.repo.match(packages.OrRestriction( rc, rp, packages.AlwaysTrue), sorter=partial(sorted, reverse=True))) rc2 = packages.PackageRestriction( "category", values.StrExactMatch("dev-lib")) self.assertEqual( sorted(self.repo.itermatch(packages.AndRestriction(rp, rc2))), sorted([])) # note this mixes a category level match, and a pkg level # match. they *must* be treated as an or. self.assertEqual( sorted(self.repo.itermatch(packages.OrRestriction(rp, rc2))), sorted(versioned_CPV(x) for x in ( "dev-util/diffball-0.7", "dev-util/diffball-1.0", "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1"))) # this is similar to the test above, but mixes a cat/pkg # candidate with a pkg candidate rp2 = packages.PackageRestriction( "package", values.StrExactMatch("fake")) r = packages.OrRestriction(atom("dev-util/diffball"), rp2) self.assertEqual( sorted(self.repo.itermatch(r)), sorted(versioned_CPV(x) for x in ( "dev-util/diffball-0.7", "dev-util/diffball-1.0", "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1"))) self.assertEqual( sorted(self.repo.itermatch( packages.OrRestriction(packages.AlwaysTrue, rp2))), sorted(versioned_CPV(x) for x in ( "dev-util/diffball-0.7", "dev-util/diffball-1.0", "dev-util/bsdiff-0.4.1", "dev-util/bsdiff-0.4.2", "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1"))) self.assertEqual( sorted(self.repo.itermatch( packages.PackageRestriction( 'category', values.StrExactMatch('dev-util', negate=True)))), sorted(versioned_CPV(x) for x in ("dev-lib/fake-1.0", "dev-lib/fake-1.0-r1"))) obj = malleable_obj(livefs=False) pkg_kls_override = post_curry(MutatedPkg, {'repo': obj}) self.assertEqual( sorted(self.repo.itermatch( boolean.AndRestriction( boolean.OrRestriction( packages.PackageRestriction( "repo.livefs", values.EqualityMatch(False)), packages.PackageRestriction( "category", values.StrExactMatch("virtual"))), atom("dev-lib/fake")), pkg_klass_override=pkg_kls_override)), sorted(versioned_CPV(x) for x in ( "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1"))) self.assertEqual( sorted(self.repo.itermatch( packages.PackageRestriction( 'category', values.StrExactMatch('dev-lib', negate=True), negate=True))), sorted(versioned_CPV(x) for x in ( "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1"))) self.assertEqual( sorted(self.repo.itermatch( packages.PackageRestriction( 'category', values.StrExactMatch('dev-lib', negate=True), negate=True))), sorted(versioned_CPV(x) for x in ( "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1")))