def test_matching(self): strexact = values.StrExactMatch args = malleable_obj(category="foon", package="dar") self.assertMatches(self.kls("category", strexact("foon")), args) self.assertMatches(self.kls("package", strexact("dar")), args) self.assertNotMatches( self.kls("package", strexact("dar"), negate=True), args) self.assertNotMatches(self.kls("package", strexact("foon")), args) self.assertMatches(self.kls("package", strexact("foon"), negate=True), args) excepts = [] # no msg should be thrown, it wasn't an unexpected exception log.logging.root.addHandler(callback_logger(excepts.append)) self.assertNotMatches(self.kls("foon", AlwaysSelfIntersect), args) self.assertFalse(excepts) self.assertMatches(self.kls("foon", AlwaysSelfIntersect, negate=True), args) self.assertFalse(excepts) class foo: def __getattr__(self, attr): if attr.startswith("exc"): raise exceptions_d.get(attr[4:], None)() raise AttributeError("monkey lover") exceptions_d = { "KeyboardInterrupt": KeyboardInterrupt, "RuntimeError": RuntimeError, "SystemExit": SystemExit } for mode in ("match", "force_True", "force_False"): excepts[:] = [] self.assertRaises( AttributeError, getattr(self.kls("foon", AlwaysSelfIntersect), mode), foo()) self.assertEqual(len(excepts), 1, msg=f"expected one exception, got {excepts!r}") # ensure various exceptions are passed through for k in (KeyboardInterrupt, RuntimeError, SystemExit): self.assertRaises( k, getattr(self.kls(f"exc_{k.__name__}", AlwaysSelfIntersect), mode), foo()) # check that it only does string comparison in exception catching. class foo: def __cmp__(self, other): raise TypeError def __getattr__(self, attr): raise AttributeError(self, attr) self.assertFalse(self.kls("foon", AlwaysSelfIntersect).match(foo()))
def test_matching(self): strexact = values.StrExactMatch args = malleable_obj(category="foon", package="dar") self.assertMatches(self.kls("category", strexact("foon")), args) self.assertMatches(self.kls("package", strexact("dar")), args) self.assertNotMatches(self.kls("package", strexact("dar"), negate=True), args) self.assertNotMatches(self.kls("package", strexact("foon")), args) self.assertMatches(self.kls("package", strexact("foon"), negate=True), args) excepts = [] # no msg should be thrown, it wasn't an unexpected exception log.logging.root.addHandler(callback_logger(excepts.append)) self.assertNotMatches(self.kls("foon", AlwaysSelfIntersect), args) self.assertFalse(excepts) self.assertMatches(self.kls("foon", AlwaysSelfIntersect, negate=True), args) self.assertFalse(excepts) class foo: def __getattr__(self, attr): if attr.startswith("exc"): raise exceptions_d.get(attr[4:], None)() raise AttributeError("monkey lover") exceptions_d = {"KeyboardInterrupt":KeyboardInterrupt, "RuntimeError":RuntimeError, "SystemExit":SystemExit} for mode in ("match", "force_True", "force_False"): excepts[:] = [] self.assertRaises(AttributeError, getattr(self.kls("foon", AlwaysSelfIntersect), mode), foo()) self.assertEqual( len(excepts), 1, msg=f"expected one exception, got {excepts!r}") # ensure various exceptions are passed through for k in (KeyboardInterrupt, RuntimeError, SystemExit): self.assertRaises( k, getattr(self.kls(f"exc_{k.__name__}", AlwaysSelfIntersect), mode), foo()) # check that it only does string comparison in exception catching. class foo: def __cmp__(self, other): raise TypeError def __getattr__(self, attr): raise AttributeError(self, attr) self.assertFalse(self.kls("foon", AlwaysSelfIntersect).match(foo()))
def fake_pkg(cat='dev-util', pkg='bsdiff', ver='1.0', **attrs): d = {} d['category'] = cat d['pkg'] = pkg d['ver'] = ver d['key'] = "%s/%s" % (cat, pkg) d["cpvstr"] = "%s/%s-%s" % (cat, pkg, ver) d['built'] = False d.update(attrs) return malleable_obj(**d)
def fake_pkg(cat='dev-util', pkg='bsdiff', ver='1.0', **attrs): d = {} d['category'] = cat d['pkg'] = pkg d['ver'] = ver d['key'] = f"{cat}/{pkg}" d["cpvstr"] = f"{cat}/{pkg}-{ver}" d['built'] = False d.update(attrs) return malleable_obj(**d)
def test_get_ebuild_mtime(self): f = pjoin(self.dir, "temp-0.ebuild") open(f, 'w').close() cur = os.stat_float_times() try: for x in (False, True): os.stat_float_times(x) self.assertEqual(self.mkinst(repo=malleable_obj( _get_ebuild_path=lambda s:f))._get_ebuild_mtime(None), os.stat(f).st_mtime) finally: os.stat_float_times(cur)
def test_get_metadata(self): ec = FakeEclassCache('/nonexistent/path') pkg = malleable_obj(_mtime_=100, cpvstr='dev-util/diffball-0.71', path='bollocks') class fake_cache(dict): readonly = False validate_result = False def validate_entry(self, *args): return self.validate_result cache1 = fake_cache({pkg.cpvstr: {'_mtime_':100, 'marker':1} }) cache2 = fake_cache({}) class explode_kls(AssertionError): pass def explode(name, *args, **kwargs): raise explode_kls("%s was called with %r and %r, " "shouldn't be invoked." % (name, args, kwargs)) pf = self.mkinst(cache=(cache2, cache1), eclasses=ec, _update_metadata=partial(explode, '_update_metadata')) cache1.validate_result = True self.assertEqual(pf._get_metadata(pkg), {'marker':1, '_mtime_':100}, reflective=False) self.assertEqual(cache1.keys(), [pkg.cpvstr]) self.assertFalse(cache2) # mtime was wiped, thus no longer is usable. # note also, that the caches are writable. cache1.validate_result = False self.assertRaises(explode_kls, pf._get_metadata, pkg) self.assertFalse(cache2) self.assertFalse(cache1) # Note that this is known crap eclass data; partially lazyness, partially # to validate the eclass validation is left to ec cache only. cache2.update({pkg.cpvstr: {'_mtime_':200, '_eclasses_':{'eclass1':(None, 100)}, 'marker':2} }) cache2.readonly = True self.assertRaises(explode_kls, pf._get_metadata, pkg) self.assertEqual(cache2.keys(), [pkg.cpvstr]) # keep in mind the backend assumes it gets its own copy of the data. # thus, modifying (popping _mtime_) _is_ valid self.assertEqual(cache2[pkg.cpvstr], {'_eclasses_':{'eclass1':(None, 100)}, 'marker':2, '_mtime_':200})
def test_get_metadata(self): ec = FakeEclassCache('/nonexistent/path') pkg = malleable_obj(_mtime_=100, cpvstr='dev-util/diffball-0.71', path='bollocks') class fake_cache(dict): readonly = False validate_result = False def validate_entry(self, *args): return self.validate_result cache1 = fake_cache({pkg.cpvstr: {'_mtime_':100, 'marker':1} }) cache2 = fake_cache({}) class explode_kls(AssertionError): pass def explode(name, *args, **kwargs): raise explode_kls("%s was called with %r and %r, " "shouldn't be invoked." % (name, args, kwargs)) pf = self.mkinst(cache=(cache2, cache1), eclasses=ec, _update_metadata=partial(explode, '_update_metadata')) cache1.validate_result = True self.assertEqual(pf._get_metadata(pkg), {'marker':1, '_mtime_':100}, reflective=False) self.assertEqual(cache1.keys(), [pkg.cpvstr]) self.assertFalse(cache2) # mtime was wiped, thus no longer is usable. # note also, that the caches are writable. cache1.validate_result = False self.assertRaises(explode_kls, pf._get_metadata, pkg) self.assertFalse(cache2) self.assertFalse(cache1) # Note that this is known crap eclass data; partially lazyness, partially # to validate the eclass validation is left to ec cache only. cache2.update({pkg.cpvstr: {'_mtime_':200, '_eclasses_':{'eclass1':(None, 100)}, 'marker':2} }) cache2.readonly = True self.assertRaises(explode_kls, pf._get_metadata, pkg) self.assertEqual(cache2.keys(), [pkg.cpvstr]) # keep in mind the backend assumes it gets it's own copy of the data. # thus, modifying (popping _mtime_) _is_ valid self.assertEqual(cache2[pkg.cpvstr], {'_eclasses_':{'eclass1':(None, 100)}, 'marker':2, '_mtime_':200})
def test_get_metadata(self): ec = FakeEclassCache('/nonexistent/path') pkg = malleable_obj(_mtime_=100, cpvstr='dev-util/diffball-0.71', path='bollocks') class fake_cache(dict): readonly = False validate_result = False def validate_entry(self, *args): return self.validate_result cache1 = fake_cache({pkg.cpvstr: {'_mtime_': 100, 'marker': 1}}) cache2 = fake_cache({}) class explode_kls(AssertionError): pass def explode(name, *args, **kwargs): raise explode_kls( f"{name} was called with {args!r} and {kwargs!r}, shouldn't be invoked.") pf = self.mkinst( cache=(cache2, cache1), eclasses=ec, _update_metadata=partial(explode, '_update_metadata')) cache1.validate_result = True assert pf._get_metadata(pkg) == {'marker': 1, '_mtime_': 100} assert list(cache1.keys()) == [pkg.cpvstr] assert not cache2 # mtime was wiped, thus no longer is usable. # note also, that the caches are writable. cache1.validate_result = False with pytest.raises(explode_kls): pf._get_metadata(pkg) assert not cache2 assert not cache1 # Note that this is known crap eclass data; partially lazyness, partially # to validate the eclass validation is left to ec cache only. cache2.update({pkg.cpvstr: {'_mtime_': 200, '_eclasses_': {'eclass1': (None, 100)}, 'marker': 2} }) cache2.readonly = True with pytest.raises(explode_kls): pf._get_metadata(pkg) assert list(cache2.keys()) == [pkg.cpvstr] # keep in mind the backend assumes it gets its own copy of the data. # thus, modifying (popping _mtime_) _is_ valid assert cache2[pkg.cpvstr] == \ {'_eclasses_': {'eclass1': (None, 100)}, 'marker': 2, '_mtime_': 200}
def test_get_ebuild_mtime(self, tmpdir): f = pjoin(str(tmpdir), "temp-0.ebuild") open(f, 'w').close() mtime = self.mkinst( repo=malleable_obj(_get_ebuild_path=lambda s: f))._get_ebuild_mtime(None) assert mtime == os.stat(f).st_mtime
def test_get_ebuild_src(self): assert ( self.mkinst( repo=malleable_obj(_get_ebuild_src=lambda s: f"lincoln haunts me: {s}") ).get_ebuild_src("1") == "lincoln haunts me: 1")
def test_get_ebuild_src(self): self.assertEqual(self.mkinst(repo=malleable_obj( _get_ebuild_src=lambda s:"lincoln haunts me: %s" % s) ).get_ebuild_src("1"), "lincoln haunts me: 1")
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")))
def test_identify_candidates(self): with pytest.raises(TypeError): self.repo.match("asdf") rc = packages.PackageRestriction("category", values.StrExactMatch("dev-util")) assert \ sorted(set(x.package for x in self.repo.itermatch(rc))) == \ sorted(["diffball", "bsdiff"]) rp = packages.PackageRestriction("package", values.StrExactMatch("diffball")) assert list( x.version for x in self.repo.itermatch(rp, sorter=sorted)) == ["0.7", "1.0"] assert \ self.repo.match(packages.OrRestriction(rc, rp), sorter=sorted) == \ sorted(VersionedCPV(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")) assert \ sorted(self.repo.itermatch(packages.AndRestriction(rc, rp))) == \ sorted(VersionedCPV(x) for x in ( "dev-util/diffball-0.7", "dev-util/diffball-1.0")) assert 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. assert \ 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")) assert sorted(self.repo.itermatch(packages.AndRestriction(rp, rc2))) == [] # note this mixes a category level match, and a pkg level # match. they *must* be treated as an or. assert \ sorted(self.repo.itermatch(packages.OrRestriction(rp, rc2))) == \ sorted(VersionedCPV(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) assert \ sorted(self.repo.itermatch(r)) == \ sorted(VersionedCPV(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")) assert \ sorted(self.repo.itermatch( packages.OrRestriction(packages.AlwaysTrue, rp2))) == \ sorted(VersionedCPV(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")) assert \ sorted(self.repo.itermatch(packages.PackageRestriction( 'category', values.StrExactMatch('dev-util', negate=True)))) == \ sorted(VersionedCPV(x) for x in ("dev-lib/fake-1.0", "dev-lib/fake-1.0-r1")) obj = malleable_obj(livefs=False) pkg_cls = post_curry(MutatedPkg, {'repo': obj}) assert \ 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_cls=pkg_cls)) == \ sorted(VersionedCPV(x) for x in ( "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1")) assert \ sorted(self.repo.itermatch(packages.PackageRestriction( 'category', values.StrExactMatch('dev-lib', negate=True), negate=True))) == \ sorted(VersionedCPV(x) for x in ( "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1")) assert \ sorted(self.repo.itermatch(packages.PackageRestriction( 'category', values.StrExactMatch('dev-lib', negate=True), negate=True))) == \ sorted(VersionedCPV(x) for x in ( "dev-lib/fake-1.0", "dev-lib/fake-1.0-r1"))