diff options
author | 2022-12-29 19:51:23 +0200 | |
---|---|---|
committer | 2022-12-29 19:51:23 +0200 | |
commit | ae7dd4184f63185880738c5133f326fe47c6606a (patch) | |
tree | d6d0e55d9684fef5bca6a9035a37763dca8b8402 /tests | |
parent | bump snakeoil minimal version (diff) | |
download | pkgcheck-ae7dd4184f63185880738c5133f326fe47c6606a.tar.gz pkgcheck-ae7dd4184f63185880738c5133f326fe47c6606a.tar.bz2 pkgcheck-ae7dd4184f63185880738c5133f326fe47c6606a.zip |
format using black
Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
Diffstat (limited to 'tests')
35 files changed, 3172 insertions, 2867 deletions
diff --git a/tests/addons/test_addons.py b/tests/addons/test_addons.py index 32226927..87c59359 100644 --- a/tests/addons/test_addons.py +++ b/tests/addons/test_addons.py @@ -11,70 +11,68 @@ from ..misc import FakePkg, FakeProfile, Profile class TestArchesAddon: - @pytest.fixture(autouse=True) def _setup(self, tool, repo): self.tool = tool self.repo = repo - self.args = ['scan', '--repo', repo.location] + self.args = ["scan", "--repo", repo.location] def test_empty_default(self): options, _ = self.tool.parse_args(self.args) assert options.arches == frozenset() def test_repo_default(self): - with open(pjoin(self.repo.location, 'profiles', 'arch.list'), 'w') as f: + with open(pjoin(self.repo.location, "profiles", "arch.list"), "w") as f: f.write("arm64\namd64\n") options, _ = self.tool.parse_args(self.args) - assert options.arches == frozenset(['amd64', 'arm64']) + assert options.arches == frozenset(["amd64", "arm64"]) def test_enabled(self): data = ( - ('x86', ['x86']), - ('ppc', ['ppc']), - ('x86,ppc', ['ppc', 'x86']), + ("x86", ["x86"]), + ("ppc", ["ppc"]), + ("x86,ppc", ["ppc", "x86"]), ) for arg, expected in data: - for opt in ('-a', '--arches'): - options, _ = self.tool.parse_args(self.args + [f'{opt}={arg}']) + for opt in ("-a", "--arches"): + options, _ = self.tool.parse_args(self.args + [f"{opt}={arg}"]) assert options.arches == frozenset(expected) def test_disabled(self): # set repo defaults - with open(pjoin(self.repo.location, 'profiles', 'arch.list'), 'w') as f: + with open(pjoin(self.repo.location, "profiles", "arch.list"), "w") as f: f.write("arm64\namd64\narm64-linux\n") data = ( - ('-x86', ['amd64', 'arm64']), - ('-x86,-amd64', ['arm64']), + ("-x86", ["amd64", "arm64"]), + ("-x86,-amd64", ["arm64"]), ) for arg, expected in data: - for opt in ('-a', '--arches'): - options, _ = self.tool.parse_args(self.args + [f'{opt}={arg}']) + for opt in ("-a", "--arches"): + options, _ = self.tool.parse_args(self.args + [f"{opt}={arg}"]) assert options.arches == frozenset(expected) def test_unknown(self, capsys): # unknown arch checking requires repo defaults - with open(pjoin(self.repo.location, 'profiles', 'arch.list'), 'w') as f: + with open(pjoin(self.repo.location, "profiles", "arch.list"), "w") as f: f.write("arm64\namd64\narm64-linux\n") - for arg in ('foo', 'bar'): - for opt in ('-a', '--arches'): + for arg in ("foo", "bar"): + for opt in ("-a", "--arches"): with pytest.raises(SystemExit) as excinfo: - self.tool.parse_args(self.args + [f'{opt}={arg}']) + self.tool.parse_args(self.args + [f"{opt}={arg}"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out - assert f'unknown arch: {arg}' in err + assert f"unknown arch: {arg}" in err class TestStableArchesAddon: - @pytest.fixture(autouse=True) def _setup(self, tool, repo): self.tool = tool self.repo = repo - self.args = ['scan', '--repo', repo.location] + self.args = ["scan", "--repo", repo.location] def test_empty_default(self): options, _ = self.tool.parse_args(self.args) @@ -82,40 +80,56 @@ class TestStableArchesAddon: def test_repo_arches_default(self): """Use GLEP 72 arches.desc file if it exists.""" - with open(pjoin(self.repo.location, 'profiles', 'arch.list'), 'w') as f: + with open(pjoin(self.repo.location, "profiles", "arch.list"), "w") as f: f.write("arm64\namd64\nriscv\n") - with open(pjoin(self.repo.location, 'profiles', 'arches.desc'), 'w') as f: + with open(pjoin(self.repo.location, "profiles", "arches.desc"), "w") as f: f.write("arm64 stable\namd64 stable\nriscv testing") options, _ = self.tool.parse_args(self.args) - assert options.stable_arches == {'amd64', 'arm64'} + assert options.stable_arches == {"amd64", "arm64"} def test_repo_profiles_default(self): """Otherwise arch stability is determined from the profiles.desc file.""" - with open(pjoin(self.repo.location, 'profiles', 'arch.list'), 'w') as f: + with open(pjoin(self.repo.location, "profiles", "arch.list"), "w") as f: f.write("arm64\namd64\nriscv\n") - os.mkdir(pjoin(self.repo.location, 'profiles', 'default')) - with open(pjoin(self.repo.location, 'profiles', 'profiles.desc'), 'w') as f: + os.mkdir(pjoin(self.repo.location, "profiles", "default")) + with open(pjoin(self.repo.location, "profiles", "profiles.desc"), "w") as f: f.write("arm64 default dev\namd64 default stable\nriscv default exp") options, _ = self.tool.parse_args(self.args) - assert options.stable_arches == {'amd64'} + assert options.stable_arches == {"amd64"} def test_selected_arches(self): - for opt in ('-a', '--arches'): - options, _ = self.tool.parse_args(self.args + [f'{opt}=amd64']) - assert options.stable_arches == {'amd64'} + for opt in ("-a", "--arches"): + options, _ = self.tool.parse_args(self.args + [f"{opt}=amd64"]) + assert options.stable_arches == {"amd64"} class Test_profile_data: - - def assertResults(self, profile, known_flags, required_immutable, - required_forced, cpv="dev-util/diffball-0.1", - key_override=None, data_override=None): + def assertResults( + self, + profile, + known_flags, + required_immutable, + required_forced, + cpv="dev-util/diffball-0.1", + key_override=None, + data_override=None, + ): profile_data = addons.profiles.ProfileData( - "test-repo", "test-profile", key_override, + "test-repo", + "test-profile", + key_override, profile.provides_repo, - packages.AlwaysFalse, profile.iuse_effective, - profile.use, profile.pkg_use, profile.masked_use, profile.forced_use, {}, set(), - 'stable', False) + packages.AlwaysFalse, + profile.iuse_effective, + profile.use, + profile.pkg_use, + profile.masked_use, + profile.forced_use, + {}, + set(), + "stable", + False, + ) pkg = FakePkg(cpv, data=data_override) immutable, enabled = profile_data.identify_use(pkg, set(known_flags)) assert immutable == set(required_immutable) @@ -140,15 +154,15 @@ class Test_profile_data: self.assertResults(profile, ["lib", "bar"], ["lib"], ["lib"]) profile = FakeProfile( - forced_use={"dev-util/diffball": ["lib"]}, - masked_use={"dev-util/diffball": ["lib"]}) + forced_use={"dev-util/diffball": ["lib"]}, masked_use={"dev-util/diffball": ["lib"]} + ) self.assertResults(profile, [], [], []) # check that masked use wins out over forced. self.assertResults(profile, ["lib", "bar"], ["lib"], []) profile = FakeProfile( - forced_use={"dev-util/diffball": ["lib"]}, - masked_use={"dev-util/diffball": ["lib"]}) + forced_use={"dev-util/diffball": ["lib"]}, masked_use={"dev-util/diffball": ["lib"]} + ) self.assertResults(profile, [], [], []) # check that masked use wins out over forced. self.assertResults(profile, ["lib", "bar"], ["lib"], []) @@ -162,7 +176,7 @@ class TestProfileAddon: def _setup(self, tool, repo, tmp_path): self.tool = tool self.repo = repo - self.args = ['scan', '--cache-dir', str(tmp_path), '--repo', repo.location] + self.args = ["scan", "--cache-dir", str(tmp_path), "--repo", repo.location] def assertProfiles(self, addon, key, *profile_names): actual = sorted(x.name for y in addon.profile_evaluate_dict[key] for x in y) @@ -171,34 +185,34 @@ class TestProfileAddon: def test_defaults(self): profiles = [ - Profile('profile1', 'x86'), - Profile('profile1/2', 'x86'), + Profile("profile1", "x86"), + Profile("profile1/2", "x86"), ] self.repo.create_profiles(profiles) - self.repo.arches.add('x86') + self.repo.arches.add("x86") options, _ = self.tool.parse_args(self.args) addon = addons.init_addon(self.addon_kls, options) - assert sorted(addon.profile_evaluate_dict) == ['x86', '~x86'] - self.assertProfiles(addon, 'x86', 'profile1', 'profile1/2') + assert sorted(addon.profile_evaluate_dict) == ["x86", "~x86"] + self.assertProfiles(addon, "x86", "profile1", "profile1/2") def test_profiles_base(self): profiles = [ - Profile('default-linux/dep', 'x86', deprecated=True), - Profile('default-linux', 'x86', 'dev'), - Profile('default-linux/x86', 'x86'), + Profile("default-linux/dep", "x86", deprecated=True), + Profile("default-linux", "x86", "dev"), + Profile("default-linux/x86", "x86"), ] self.repo.create_profiles(profiles) - self.repo.arches.add('x86') + self.repo.arches.add("x86") options, _ = self.tool.parse_args(self.args) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux', 'default-linux/x86') + self.assertProfiles(addon, "x86", "default-linux", "default-linux/x86") def test_nonexistent(self, capsys): - profile = Profile('x86', 'x86') + profile = Profile("x86", "x86") self.repo.create_profiles([profile]) - for profiles in ('bar', '-bar', 'x86,bar', 'bar,x86', 'x86,-bar'): + for profiles in ("bar", "-bar", "x86,bar", "bar,x86", "x86,-bar"): with pytest.raises(SystemExit) as excinfo: - self.tool.parse_args(self.args + [f'--profiles={profiles}']) + self.tool.parse_args(self.args + [f"--profiles={profiles}"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out @@ -206,149 +220,150 @@ class TestProfileAddon: def test_profiles_args(self): profiles = [ - Profile('default-linux/dep', 'x86', deprecated=True), - Profile('default-linux/dev', 'x86', 'dev'), - Profile('default-linux/exp', 'x86', 'exp'), - Profile('default-linux', 'x86'), + Profile("default-linux/dep", "x86", deprecated=True), + Profile("default-linux/dev", "x86", "dev"), + Profile("default-linux/exp", "x86", "exp"), + Profile("default-linux", "x86"), ] self.repo.create_profiles(profiles) - self.repo.arches.add('x86') + self.repo.arches.add("x86") # enable stable - options, _ = self.tool.parse_args(self.args + ['--profiles=stable']) + options, _ = self.tool.parse_args(self.args + ["--profiles=stable"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux') + self.assertProfiles(addon, "x86", "default-linux") # disable stable - options, _ = self.tool.parse_args(self.args + ['--profiles=-stable']) + options, _ = self.tool.parse_args(self.args + ["--profiles=-stable"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux/dev', 'default-linux/exp') + self.assertProfiles(addon, "x86", "default-linux/dev", "default-linux/exp") # enable dev - options, _ = self.tool.parse_args(self.args + ['--profiles=dev']) + options, _ = self.tool.parse_args(self.args + ["--profiles=dev"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux/dev') + self.assertProfiles(addon, "x86", "default-linux/dev") # disable dev - options, _ = self.tool.parse_args(self.args + ['--profiles=-dev']) + options, _ = self.tool.parse_args(self.args + ["--profiles=-dev"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux', 'default-linux/exp') + self.assertProfiles(addon, "x86", "default-linux", "default-linux/exp") # enable exp - options, _ = self.tool.parse_args(self.args + ['--profiles=exp']) + options, _ = self.tool.parse_args(self.args + ["--profiles=exp"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux/exp') + self.assertProfiles(addon, "x86", "default-linux/exp") # disable exp - options, _ = self.tool.parse_args(self.args + ['--profiles=-exp']) + options, _ = self.tool.parse_args(self.args + ["--profiles=-exp"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux', 'default-linux/dev') + self.assertProfiles(addon, "x86", "default-linux", "default-linux/dev") # enable deprecated - options, _ = self.tool.parse_args(self.args + ['--profiles=deprecated']) + options, _ = self.tool.parse_args(self.args + ["--profiles=deprecated"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux/dep') + self.assertProfiles(addon, "x86", "default-linux/dep") # disable deprecated - options, _ = self.tool.parse_args(self.args + ['--profiles=-deprecated']) + options, _ = self.tool.parse_args(self.args + ["--profiles=-deprecated"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux', 'default-linux/dev', 'default-linux/exp') + self.assertProfiles(addon, "x86", "default-linux", "default-linux/dev", "default-linux/exp") # enable specific profile - options, _ = self.tool.parse_args(self.args + ['--profiles', 'default-linux/exp']) + options, _ = self.tool.parse_args(self.args + ["--profiles", "default-linux/exp"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux/exp') + self.assertProfiles(addon, "x86", "default-linux/exp") # disable specific profile - options, _ = self.tool.parse_args(self.args + ['--profiles=-default-linux']) + options, _ = self.tool.parse_args(self.args + ["--profiles=-default-linux"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux/dev', 'default-linux/exp') + self.assertProfiles(addon, "x86", "default-linux/dev", "default-linux/exp") def test_auto_enable_exp_profiles(self): profiles = [ - Profile('default-linux/dep', 'x86', deprecated=True), - Profile('default-linux/dev', 'x86', 'dev'), - Profile('default-linux/exp', 'x86', 'exp'), - Profile('default-linux/amd64', 'amd64', 'exp'), - Profile('default-linux', 'x86'), + Profile("default-linux/dep", "x86", deprecated=True), + Profile("default-linux/dev", "x86", "dev"), + Profile("default-linux/exp", "x86", "exp"), + Profile("default-linux/amd64", "amd64", "exp"), + Profile("default-linux", "x86"), ] self.repo.create_profiles(profiles) - self.repo.arches.update(['amd64', 'x86']) + self.repo.arches.update(["amd64", "x86"]) # experimental profiles aren't enabled by default options, _ = self.tool.parse_args(self.args) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'x86', 'default-linux', 'default-linux/dev') + self.assertProfiles(addon, "x86", "default-linux", "default-linux/dev") # but are auto-enabled when an arch with only exp profiles is selected - options, _ = self.tool.parse_args(self.args + ['-a', 'amd64']) + options, _ = self.tool.parse_args(self.args + ["-a", "amd64"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'amd64', 'default-linux/amd64') + self.assertProfiles(addon, "amd64", "default-linux/amd64") # or a result keyword is selected that requires them - options, _ = self.tool.parse_args(self.args + ['-k', 'NonsolvableDepsInExp']) + options, _ = self.tool.parse_args(self.args + ["-k", "NonsolvableDepsInExp"]) addon = addons.init_addon(self.addon_kls, options) - self.assertProfiles(addon, 'amd64', 'default-linux/amd64') - self.assertProfiles(addon, 'x86', 'default-linux', 'default-linux/dev', 'default-linux/exp') + self.assertProfiles(addon, "amd64", "default-linux/amd64") + self.assertProfiles(addon, "x86", "default-linux", "default-linux/dev", "default-linux/exp") def test_addon_dict(self): """ProfileAddon has methods that allow it to act like a dict of profile filters.""" profiles = [ - Profile('linux/x86', 'x86'), - Profile('linux/ppc', 'ppc'), + Profile("linux/x86", "x86"), + Profile("linux/ppc", "ppc"), ] self.repo.create_profiles(profiles) - self.repo.arches.update(['x86', 'ppc']) + self.repo.arches.update(["x86", "ppc"]) options, _ = self.tool.parse_args(self.args) addon = addons.init_addon(self.addon_kls, options) assert len(addon) == 4 - assert set(x.name for x in addon) == {'linux/x86', 'linux/ppc'} - assert len(addon['x86']) == 1 - assert [x.name for x in addon['~x86']] == ['linux/x86'] - assert addon.get('foo', ['foo']) == ['foo'] - assert addon.get('foo') is None + assert set(x.name for x in addon) == {"linux/x86", "linux/ppc"} + assert len(addon["x86"]) == 1 + assert [x.name for x in addon["~x86"]] == ["linux/x86"] + assert addon.get("foo", ["foo"]) == ["foo"] + assert addon.get("foo") is None def test_profile_collapsing(self): profiles = [ - Profile('default-linux', 'x86'), - Profile('default-linux/x86', 'x86'), - Profile('default-linux/ppc', 'ppc'), + Profile("default-linux", "x86"), + Profile("default-linux/x86", "x86"), + Profile("default-linux/ppc", "ppc"), ] self.repo.create_profiles(profiles) - self.repo.arches.update(['x86', 'ppc']) + self.repo.arches.update(["x86", "ppc"]) options, _ = self.tool.parse_args(self.args) addon = addons.init_addon(self.addon_kls, options) # assert they're collapsed properly. - self.assertProfiles(addon, 'x86', 'default-linux', 'default-linux/x86') - assert len(addon.profile_evaluate_dict['x86']) == 1 - assert len(addon.profile_evaluate_dict['x86'][0]) == 2 - self.assertProfiles(addon, 'ppc', 'default-linux/ppc') + self.assertProfiles(addon, "x86", "default-linux", "default-linux/x86") + assert len(addon.profile_evaluate_dict["x86"]) == 1 + assert len(addon.profile_evaluate_dict["x86"][0]) == 2 + self.assertProfiles(addon, "ppc", "default-linux/ppc") - groups = addon.identify_profiles(FakePkg("d-b/ab-1", data={'KEYWORDS': 'x86'})) + groups = addon.identify_profiles(FakePkg("d-b/ab-1", data={"KEYWORDS": "x86"})) assert len(groups) == 2, f"checking for profile collapsing: {groups!r}" assert len(groups[0]) == 2, f"checking for proper # of profiles: {groups[0]!r}" - assert sorted(x.name for x in groups[0]) == sorted(['default-linux', 'default-linux/x86']) + assert sorted(x.name for x in groups[0]) == sorted(["default-linux", "default-linux/x86"]) # check arch vs ~arch runs (i.e. arch KEYWORDS should also trigger ~arch runs) - groups = addon.identify_profiles(FakePkg("d-b/ab-1", data={'KEYWORDS': '~x86'})) + groups = addon.identify_profiles(FakePkg("d-b/ab-1", data={"KEYWORDS": "~x86"})) assert len(groups) == 1, f"checking for profile collapsing: {groups!r}" assert len(groups[0]) == 2, f"checking for proper # of profiles: {groups[0]!r}" - assert sorted(x.name for x in groups[0]) == sorted(['default-linux', 'default-linux/x86']) + assert sorted(x.name for x in groups[0]) == sorted(["default-linux", "default-linux/x86"]) # check keyword collapsing - groups = addon.identify_profiles(FakePkg("d-b/ab-2", data={'KEYWORDS': 'ppc'})) + groups = addon.identify_profiles(FakePkg("d-b/ab-2", data={"KEYWORDS": "ppc"})) assert len(groups) == 2, f"checking for profile collapsing: {groups!r}" assert len(groups[0]) == 1, f"checking for proper # of profiles: {groups[0]!r}" - assert groups[0][0].name == 'default-linux/ppc' + assert groups[0][0].name == "default-linux/ppc" - groups = addon.identify_profiles(FakePkg("d-b/ab-2", data={'KEYWORDS': 'foon'})) + groups = addon.identify_profiles(FakePkg("d-b/ab-2", data={"KEYWORDS": "foon"})) assert len(groups) == 0, f"checking for profile collapsing: {groups!r}" try: import requests + net_skip = False except ImportError: net_skip = True @@ -356,33 +371,33 @@ except ImportError: @pytest.mark.skipif(net_skip, reason="requests isn't installed") class TestNetAddon: - def test_failed_import(self, tool): - options, _ = tool.parse_args(['scan']) + options, _ = tool.parse_args(["scan"]) addon = addons.NetAddon(options) - with patch('pkgcheck.addons.net.Session') as net: - net.side_effect = ImportError('import failed', name='foo') + with patch("pkgcheck.addons.net.Session") as net: + net.side_effect = ImportError("import failed", name="foo") with pytest.raises(ImportError): addon.session # failing to import requests specifically returns a nicer user exception - net.side_effect = ImportError('import failed', name='requests') - with pytest.raises(PkgcheckUserException, match='network checks require requests'): + net.side_effect = ImportError("import failed", name="requests") + with pytest.raises(PkgcheckUserException, match="network checks require requests"): addon.session def test_custom_timeout(self, tool): - options, _ = tool.parse_args(['scan', '--timeout', '10']) + options, _ = tool.parse_args(["scan", "--timeout", "10"]) addon = addons.NetAddon(options) assert isinstance(addon.session, requests.Session) assert addon.session.timeout == 10 # a timeout of zero disables timeouts entirely - options, _ = tool.parse_args(['scan', '--timeout', '0']) + options, _ = tool.parse_args(["scan", "--timeout", "0"]) addon = addons.NetAddon(options) assert addon.session.timeout is None def test_args(self, tool): options, _ = tool.parse_args( - ['scan', '--timeout', '10', '--tasks', '50', '--user-agent', 'firefox']) + ["scan", "--timeout", "10", "--tasks", "50", "--user-agent", "firefox"] + ) addon = addons.NetAddon(options) - with patch('pkgcheck.addons.net.Session') as net: + with patch("pkgcheck.addons.net.Session") as net: addon.session - net.assert_called_once_with(concurrent=50, timeout=10, user_agent='firefox') + net.assert_called_once_with(concurrent=50, timeout=10, user_agent="firefox") diff --git a/tests/addons/test_eclass.py b/tests/addons/test_eclass.py index 4e1b26db..c6c045b2 100644 --- a/tests/addons/test_eclass.py +++ b/tests/addons/test_eclass.py @@ -13,26 +13,29 @@ from snakeoil.osutils import pjoin class TestEclass: - @pytest.fixture(autouse=True) def _setup(self, tmp_path): - path = str(tmp_path / 'foo.eclass') - with open(path, 'w') as f: - f.write(textwrap.dedent("""\ - # eclass header - foo () { :; } - """)) - self.eclass1 = Eclass('foo', path) - path = str(tmp_path / 'bar.eclass') - self.eclass2 = Eclass('bar', path) + path = str(tmp_path / "foo.eclass") + with open(path, "w") as f: + f.write( + textwrap.dedent( + """\ + # eclass header + foo () { :; } + """ + ) + ) + self.eclass1 = Eclass("foo", path) + path = str(tmp_path / "bar.eclass") + self.eclass2 = Eclass("bar", path) def test_lines(self): - assert self.eclass1.lines == ('# eclass header\n', 'foo () { :; }\n') + assert self.eclass1.lines == ("# eclass header\n", "foo () { :; }\n") assert self.eclass2.lines == () def test_lt(self): assert self.eclass2 < self.eclass1 - assert self.eclass1 < 'zoo.eclass' + assert self.eclass1 < "zoo.eclass" def test_hash(self): eclasses = {self.eclass1, self.eclass2} @@ -46,23 +49,22 @@ class TestEclass: class TestEclassAddon: - @pytest.fixture(autouse=True) def _setup(self, tool, tmp_path, repo): self.repo = repo self.cache_dir = str(tmp_path) - self.eclass_dir = pjoin(repo.location, 'eclass') + self.eclass_dir = pjoin(repo.location, "eclass") - args = ['scan', '--cache-dir', self.cache_dir, '--repo', repo.location] + args = ["scan", "--cache-dir", self.cache_dir, "--repo", repo.location] options, _ = tool.parse_args(args) self.addon = EclassAddon(options) self.cache_file = self.addon.cache_file(self.repo) def test_cache_disabled(self, tool): - args = ['scan', '--cache', 'no', '--repo', self.repo.location] + args = ["scan", "--cache", "no", "--repo", self.repo.location] options, _ = tool.parse_args(args) - with pytest.raises(CacheDisabled, match='eclass cache support required'): + with pytest.raises(CacheDisabled, match="eclass cache support required"): init_addon(EclassAddon, options) def test_no_eclasses(self): @@ -73,18 +75,18 @@ class TestEclassAddon: def test_eclasses(self): # non-eclass files are ignored - for f in ('foo.eclass', 'bar'): + for f in ("foo.eclass", "bar"): touch(pjoin(self.eclass_dir, f)) self.addon.update_cache() - assert list(self.addon.eclasses) == ['foo'] + assert list(self.addon.eclasses) == ["foo"] assert not self.addon.deprecated def test_cache_load(self): - touch(pjoin(self.eclass_dir, 'foo.eclass')) + touch(pjoin(self.eclass_dir, "foo.eclass")) self.addon.update_cache() - assert list(self.addon.eclasses) == ['foo'] + assert list(self.addon.eclasses) == ["foo"] - with patch('pkgcheck.addons.caches.CachedAddon.save_cache') as save_cache: + with patch("pkgcheck.addons.caches.CachedAddon.save_cache") as save_cache: self.addon.update_cache() # verify the cache was loaded and not regenerated save_cache.assert_not_called() @@ -93,9 +95,9 @@ class TestEclassAddon: save_cache.assert_called_once() def test_outdated_cache(self): - touch(pjoin(self.eclass_dir, 'foo.eclass')) + touch(pjoin(self.eclass_dir, "foo.eclass")) self.addon.update_cache() - assert list(self.addon.eclasses) == ['foo'] + assert list(self.addon.eclasses) == ["foo"] # increment cache version and dump cache cache = self.addon.load_cache(self.cache_file) @@ -103,68 +105,72 @@ class TestEclassAddon: self.addon.save_cache(cache, self.cache_file) # verify cache load causes regen - with patch('pkgcheck.addons.caches.CachedAddon.save_cache') as save_cache: + with patch("pkgcheck.addons.caches.CachedAddon.save_cache") as save_cache: self.addon.update_cache() save_cache.assert_called_once() def test_eclass_changes(self): """The cache stores eclass mtimes and regenerates entries if they differ.""" - eclass_path = pjoin(self.eclass_dir, 'foo.eclass') + eclass_path = pjoin(self.eclass_dir, "foo.eclass") touch(eclass_path) self.addon.update_cache() - assert list(self.addon.eclasses) == ['foo'] + assert list(self.addon.eclasses) == ["foo"] sleep(1) - with open(eclass_path, 'w') as f: - f.write('# changed eclass\n') - with patch('pkgcheck.addons.caches.CachedAddon.save_cache') as save_cache: + with open(eclass_path, "w") as f: + f.write("# changed eclass\n") + with patch("pkgcheck.addons.caches.CachedAddon.save_cache") as save_cache: self.addon.update_cache() save_cache.assert_called_once() def test_error_loading_cache(self): - touch(pjoin(self.eclass_dir, 'foo.eclass')) + touch(pjoin(self.eclass_dir, "foo.eclass")) self.addon.update_cache() - assert list(self.addon.eclasses) == ['foo'] + assert list(self.addon.eclasses) == ["foo"] - with patch('pkgcheck.addons.caches.pickle.load') as pickle_load: + with patch("pkgcheck.addons.caches.pickle.load") as pickle_load: # catastrophic errors are raised - pickle_load.side_effect = MemoryError('unpickling failed') - with pytest.raises(MemoryError, match='unpickling failed'): + pickle_load.side_effect = MemoryError("unpickling failed") + with pytest.raises(MemoryError, match="unpickling failed"): self.addon.update_cache() # but various load failure exceptions cause cache regen - pickle_load.side_effect = Exception('unpickling failed') - with patch('pkgcheck.addons.caches.CachedAddon.save_cache') as save_cache: + pickle_load.side_effect = Exception("unpickling failed") + with patch("pkgcheck.addons.caches.CachedAddon.save_cache") as save_cache: self.addon.update_cache() save_cache.assert_called_once() def test_error_dumping_cache(self): - touch(pjoin(self.eclass_dir, 'foo.eclass')) + touch(pjoin(self.eclass_dir, "foo.eclass")) # verify IO related dump failures are raised - with patch('pkgcheck.addons.caches.pickle.dump') as pickle_dump: - pickle_dump.side_effect = IOError('unpickling failed') - with pytest.raises(PkgcheckUserException, match='failed dumping eclass cache'): + with patch("pkgcheck.addons.caches.pickle.dump") as pickle_dump: + pickle_dump.side_effect = IOError("unpickling failed") + with pytest.raises(PkgcheckUserException, match="failed dumping eclass cache"): self.addon.update_cache() def test_eclass_removal(self): - for name in ('foo', 'bar'): - touch(pjoin(self.eclass_dir, f'{name}.eclass')) + for name in ("foo", "bar"): + touch(pjoin(self.eclass_dir, f"{name}.eclass")) self.addon.update_cache() - assert sorted(self.addon.eclasses) == ['bar', 'foo'] - os.unlink(pjoin(self.eclass_dir, 'bar.eclass')) + assert sorted(self.addon.eclasses) == ["bar", "foo"] + os.unlink(pjoin(self.eclass_dir, "bar.eclass")) self.addon.update_cache() - assert list(self.addon.eclasses) == ['foo'] + assert list(self.addon.eclasses) == ["foo"] def test_deprecated(self): - with open(pjoin(self.eclass_dir, 'foo.eclass'), 'w') as f: - f.write(textwrap.dedent(""" - # @ECLASS: foo.eclass - # @MAINTAINER: - # Random Person <random.person@random.email> - # @AUTHOR: - # Random Person <random.person@random.email> - # @BLURB: Example deprecated eclass with replacement. - # @DEPRECATED: foo2 - """)) + with open(pjoin(self.eclass_dir, "foo.eclass"), "w") as f: + f.write( + textwrap.dedent( + """\ + # @ECLASS: foo.eclass + # @MAINTAINER: + # Random Person <random.person@random.email> + # @AUTHOR: + # Random Person <random.person@random.email> + # @BLURB: Example deprecated eclass with replacement. + # @DEPRECATED: foo2 + """ + ) + ) self.addon.update_cache() - assert list(self.addon.eclasses) == ['foo'] - assert self.addon.deprecated == {'foo': 'foo2'} + assert list(self.addon.eclasses) == ["foo"] + assert self.addon.deprecated == {"foo": "foo2"} diff --git a/tests/addons/test_git.py b/tests/addons/test_git.py index cf39efc3..da88d501 100644 --- a/tests/addons/test_git.py +++ b/tests/addons/test_git.py @@ -18,146 +18,147 @@ from snakeoil.process import CommandNotFound, find_binary # skip testing module if git isn't installed try: - find_binary('git') + find_binary("git") except CommandNotFound: - pytestmark = pytest.mark.skipif(True, reason='git not installed') + pytestmark = pytest.mark.skipif(True, reason="git not installed") class TestPkgcheckScanCommitsParseArgs: - @pytest.fixture(autouse=True) def _setup(self, tool): self.tool = tool - self.args = ['scan'] + self.args = ["scan"] def test_commits_with_targets(self, capsys): with pytest.raises(SystemExit) as excinfo: - options, _func = self.tool.parse_args(self.args + ['--commits', 'ref', 'dev-util/foo']) + options, _func = self.tool.parse_args(self.args + ["--commits", "ref", "dev-util/foo"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - assert err.strip() == \ - "pkgcheck scan: error: --commits is mutually exclusive with target: dev-util/foo" + assert ( + err.strip() + == "pkgcheck scan: error: --commits is mutually exclusive with target: dev-util/foo" + ) def test_commits_git_unavailable(self, capsys): - with patch('subprocess.run') as git_diff: + with patch("subprocess.run") as git_diff: git_diff.side_effect = FileNotFoundError("no such file 'git'") with pytest.raises(SystemExit) as excinfo: - options, _func = self.tool.parse_args(self.args + ['--commits']) + options, _func = self.tool.parse_args(self.args + ["--commits"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert err.strip() == "pkgcheck scan: error: no such file 'git'" def test_git_error(self, capsys): - with patch('subprocess.run') as git_diff: - git_diff.side_effect = subprocess.CalledProcessError(1, 'git') - git_diff.side_effect.stderr = 'git error: foobar' + with patch("subprocess.run") as git_diff: + git_diff.side_effect = subprocess.CalledProcessError(1, "git") + git_diff.side_effect.stderr = "git error: foobar" with pytest.raises(SystemExit) as excinfo: - options, _func = self.tool.parse_args(self.args + ['--commits']) + options, _func = self.tool.parse_args(self.args + ["--commits"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') - assert err[-1].startswith('pkgcheck scan: error: failed running git: ') + err = err.strip().split("\n") + assert err[-1].startswith("pkgcheck scan: error: failed running git: ") def test_commits_nonexistent(self, make_repo, make_git_repo, tmp_path): parent = make_repo() origin = make_git_repo(parent.location, commit=True) local = make_git_repo(str(tmp_path), commit=False) - local.run(['git', 'remote', 'add', 'origin', origin.path]) - local.run(['git', 'pull', 'origin', 'main']) - local.run(['git', 'remote', 'set-head', 'origin', 'main']) + local.run(["git", "remote", "add", "origin", origin.path]) + local.run(["git", "pull", "origin", "main"]) + local.run(["git", "remote", "set-head", "origin", "main"]) with pytest.raises(SystemExit) as excinfo: - options, _func = self.tool.parse_args(self.args + ['-r', local.path, '--commits']) + options, _func = self.tool.parse_args(self.args + ["-r", local.path, "--commits"]) assert excinfo.value.code == 0 def test_commits_existing(self, make_repo, make_git_repo, tmp_path): # create parent repo parent = make_repo() origin = make_git_repo(parent.location, commit=True) - parent.create_ebuild('cat/pkg-0') - origin.add_all('cat/pkg-0') + parent.create_ebuild("cat/pkg-0") + origin.add_all("cat/pkg-0") # create child repo and pull from parent local = make_git_repo(str(tmp_path), commit=False) - local.run(['git', 'remote', 'add', 'origin', origin.path]) - local.run(['git', 'pull', 'origin', 'main']) - local.run(['git', 'remote', 'set-head', 'origin', 'main']) + local.run(["git", "remote", "add", "origin", origin.path]) + local.run(["git", "pull", "origin", "main"]) + local.run(["git", "remote", "set-head", "origin", "main"]) child = make_repo(local.path) # create local commits on child repo - child.create_ebuild('cat/pkg-1') - local.add_all('cat/pkg-1') - child.create_ebuild('cat/pkg-2') - local.add_all('cat/pkg-2') - - options, _func = self.tool.parse_args(self.args + ['-r', local.path, '--commits']) - atom_restricts = [atom_cls('cat/pkg')] - assert list(options.restrictions) == \ - [(base.package_scope, packages.OrRestriction(*atom_restricts))] + child.create_ebuild("cat/pkg-1") + local.add_all("cat/pkg-1") + child.create_ebuild("cat/pkg-2") + local.add_all("cat/pkg-2") + + options, _func = self.tool.parse_args(self.args + ["-r", local.path, "--commits"]) + atom_restricts = [atom_cls("cat/pkg")] + assert list(options.restrictions) == [ + (base.package_scope, packages.OrRestriction(*atom_restricts)) + ] def test_commits_eclasses(self, make_repo, make_git_repo, tmp_path): # create parent repo parent = make_repo() origin = make_git_repo(parent.location, commit=True) - parent.create_ebuild('cat/pkg-0') - origin.add_all('cat/pkg-0') + parent.create_ebuild("cat/pkg-0") + origin.add_all("cat/pkg-0") # create child repo and pull from parent local = make_git_repo(str(tmp_path), commit=False) - local.run(['git', 'remote', 'add', 'origin', origin.path]) - local.run(['git', 'pull', 'origin', 'main']) - local.run(['git', 'remote', 'set-head', 'origin', 'main']) + local.run(["git", "remote", "add", "origin", origin.path]) + local.run(["git", "pull", "origin", "main"]) + local.run(["git", "remote", "set-head", "origin", "main"]) child = make_repo(local.path) # create local commits on child repo - with open(pjoin(local.path, 'cat', 'pkg', 'metadata.xml'), 'w') as f: + with open(pjoin(local.path, "cat", "pkg", "metadata.xml"), "w") as f: f.write('<?xml version="1.0" encoding="UTF-8"?>\n') - local.add_all('cat/pkg: metadata') - child.create_ebuild('cat/pkg-1') - local.add_all('cat/pkg-1') - os.makedirs(pjoin(local.path, 'eclass')) - with open(pjoin(local.path, 'eclass', 'foo.eclass'), 'w') as f: - f.write('data\n') - local.add_all('foo.eclass') - - options, _func = self.tool.parse_args(self.args + ['-r', local.path, '--commits']) - atom_restricts = [atom_cls('cat/pkg')] + local.add_all("cat/pkg: metadata") + child.create_ebuild("cat/pkg-1") + local.add_all("cat/pkg-1") + os.makedirs(pjoin(local.path, "eclass")) + with open(pjoin(local.path, "eclass", "foo.eclass"), "w") as f: + f.write("data\n") + local.add_all("foo.eclass") + + options, _func = self.tool.parse_args(self.args + ["-r", local.path, "--commits"]) + atom_restricts = [atom_cls("cat/pkg")] restrictions = list(options.restrictions) assert len(restrictions) == 2 - assert restrictions[0] == \ - (base.package_scope, packages.OrRestriction(*atom_restricts)) + assert restrictions[0] == (base.package_scope, packages.OrRestriction(*atom_restricts)) assert restrictions[1][0] == base.eclass_scope - assert restrictions[1][1] == frozenset(['foo']) + assert restrictions[1][1] == frozenset(["foo"]) def test_commits_profiles(self, make_repo, make_git_repo, tmp_path): # create parent repo parent = make_repo() origin = make_git_repo(parent.location, commit=True) - parent.create_ebuild('cat/pkg-0') - origin.add_all('cat/pkg-0') + parent.create_ebuild("cat/pkg-0") + origin.add_all("cat/pkg-0") # create child repo and pull from parent local = make_git_repo(str(tmp_path), commit=False) - local.run(['git', 'remote', 'add', 'origin', origin.path]) - local.run(['git', 'pull', 'origin', 'main']) - local.run(['git', 'remote', 'set-head', 'origin', 'main']) + local.run(["git", "remote", "add", "origin", origin.path]) + local.run(["git", "pull", "origin", "main"]) + local.run(["git", "remote", "set-head", "origin", "main"]) child = make_repo(local.path) # create local commits on child repo - with open(pjoin(local.path, 'cat', 'pkg', 'metadata.xml'), 'w') as f: + with open(pjoin(local.path, "cat", "pkg", "metadata.xml"), "w") as f: f.write('<?xml version="1.0" encoding="UTF-8"?>\n') - local.add_all('cat/pkg: metadata') - child.create_ebuild('cat/pkg-1') - local.add_all('cat/pkg-1') - with open(pjoin(local.path, 'profiles', 'package.mask'), 'w') as f: - f.write('data\n') - local.add_all('package.mask') - - options, _func = self.tool.parse_args(self.args + ['-r', local.path, '--commits']) - atom_restricts = [atom_cls('cat/pkg')] + local.add_all("cat/pkg: metadata") + child.create_ebuild("cat/pkg-1") + local.add_all("cat/pkg-1") + with open(pjoin(local.path, "profiles", "package.mask"), "w") as f: + f.write("data\n") + local.add_all("package.mask") + + options, _func = self.tool.parse_args(self.args + ["-r", local.path, "--commits"]) + atom_restricts = [atom_cls("cat/pkg")] restrictions = [ (base.package_scope, packages.OrRestriction(*atom_restricts)), - (base.profile_node_scope, frozenset(['profiles/package.mask'])), + (base.profile_node_scope, frozenset(["profiles/package.mask"])), ] assert restrictions == options.restrictions @@ -165,33 +166,32 @@ class TestPkgcheckScanCommitsParseArgs: # create parent repo parent = make_repo() origin = make_git_repo(parent.location, commit=True) - parent.create_ebuild('cat/pkg-0') - origin.add_all('cat/pkg-0') + parent.create_ebuild("cat/pkg-0") + origin.add_all("cat/pkg-0") # create child repo and pull from parent local = make_git_repo(str(tmp_path), commit=False) - local.run(['git', 'remote', 'add', 'origin', origin.path]) - local.run(['git', 'pull', 'origin', 'main']) - local.run(['git', 'remote', 'set-head', 'origin', 'main']) + local.run(["git", "remote", "add", "origin", origin.path]) + local.run(["git", "pull", "origin", "main"]) + local.run(["git", "remote", "set-head", "origin", "main"]) # create local commits on child repo - os.makedirs(pjoin(local.path, 'foo')) - with open(pjoin(local.path, 'foo', 'bar.txt'), 'w') as f: - f.write('data\n') - os.makedirs(pjoin(local.path, 'eclass', 'tests')) - with open(pjoin(local.path, 'eclass', 'tests', 'test.sh'), 'w') as f: - f.write('data\n') - local.add_all('add files') + os.makedirs(pjoin(local.path, "foo")) + with open(pjoin(local.path, "foo", "bar.txt"), "w") as f: + f.write("data\n") + os.makedirs(pjoin(local.path, "eclass", "tests")) + with open(pjoin(local.path, "eclass", "tests", "test.sh"), "w") as f: + f.write("data\n") + local.add_all("add files") with pytest.raises(SystemExit) as excinfo: - self.tool.parse_args(self.args + ['-r', local.path, '--commits']) + self.tool.parse_args(self.args + ["-r", local.path, "--commits"]) assert excinfo.value.code == 0 class TestGitStash: - def test_non_git_repo(self, tmp_path): - with pytest.raises(ValueError, match='not a git repo'): + with pytest.raises(ValueError, match="not a git repo"): with git.GitStash(str(tmp_path)): pass @@ -200,7 +200,7 @@ class TestGitStash: pass def test_untracked_file(self, git_repo): - path = pjoin(git_repo.path, 'foo') + path = pjoin(git_repo.path, "foo") touch(path) assert os.path.exists(path) with git.GitStash(git_repo.path): @@ -208,37 +208,36 @@ class TestGitStash: assert os.path.exists(path) def test_failed_stashing(self, git_repo): - path = pjoin(git_repo.path, 'foo') + path = pjoin(git_repo.path, "foo") touch(path) assert os.path.exists(path) - with patch('subprocess.run') as run: - err = subprocess.CalledProcessError(1, 'git stash') - err.stderr = 'git stash failed' - run.side_effect = [Mock(stdout='foo'), err] - with pytest.raises(UserException, match='git failed stashing files'): + with patch("subprocess.run") as run: + err = subprocess.CalledProcessError(1, "git stash") + err.stderr = "git stash failed" + run.side_effect = [Mock(stdout="foo"), err] + with pytest.raises(UserException, match="git failed stashing files"): with git.GitStash(git_repo.path): pass def test_failed_unstashing(self, git_repo): - path = pjoin(git_repo.path, 'foo') + path = pjoin(git_repo.path, "foo") touch(path) assert os.path.exists(path) - with pytest.raises(UserException, match='git failed applying stash'): + with pytest.raises(UserException, match="git failed applying stash"): with git.GitStash(git_repo.path): assert not os.path.exists(path) touch(path) class TestGitRepoCommits: - def test_non_git(self, tmp_path): - with pytest.raises(git.GitError, match='failed running git log'): - git.GitRepoCommits(str(tmp_path), 'HEAD') + with pytest.raises(git.GitError, match="failed running git log"): + git.GitRepoCommits(str(tmp_path), "HEAD") def test_empty_repo(self, make_git_repo): git_repo = make_git_repo() - with pytest.raises(git.GitError, match='failed running git log'): - git.GitRepoCommits(git_repo.path, 'HEAD') + with pytest.raises(git.GitError, match="failed running git log"): + git.GitRepoCommits(git_repo.path, "HEAD") def test_parsing(self, make_repo, make_git_repo): git_repo = make_git_repo() @@ -246,135 +245,134 @@ class TestGitRepoCommits: path = git_repo.path # make an initial commit - git_repo.add('foo', msg='foo', create=True) - commits = list(git.GitRepoCommits(path, 'HEAD')) + git_repo.add("foo", msg="foo", create=True) + commits = list(git.GitRepoCommits(path, "HEAD")) assert len(commits) == 1 - assert commits[0].message == ['foo'] + assert commits[0].message == ["foo"] assert commits[0].pkgs == {} orig_commit = commits[0] # make another commit - git_repo.add('bar', msg='bar', create=True) - commits = list(git.GitRepoCommits(path, 'HEAD')) + git_repo.add("bar", msg="bar", create=True) + commits = list(git.GitRepoCommits(path, "HEAD")) assert len(commits) == 2 - assert commits[0].message == ['bar'] + assert commits[0].message == ["bar"] assert commits[0].pkgs == {} assert commits[1] == orig_commit assert len(set(commits)) == 2 # make a pkg commit - repo.create_ebuild('cat/pkg-0') - git_repo.add_all('cat/pkg-0') - commits = list(git.GitRepoCommits(path, 'HEAD')) + repo.create_ebuild("cat/pkg-0") + git_repo.add_all("cat/pkg-0") + commits = list(git.GitRepoCommits(path, "HEAD")) assert len(commits) == 3 - assert commits[0].message == ['cat/pkg-0'] - assert commits[0].pkgs == {'A': {atom_cls('=cat/pkg-0')}} + assert commits[0].message == ["cat/pkg-0"] + assert commits[0].pkgs == {"A": {atom_cls("=cat/pkg-0")}} # make a multiple pkg commit - repo.create_ebuild('newcat/newpkg-0') - repo.create_ebuild('newcat/newpkg-1') - git_repo.add_all('newcat: various updates') - commits = list(git.GitRepoCommits(path, 'HEAD')) + repo.create_ebuild("newcat/newpkg-0") + repo.create_ebuild("newcat/newpkg-1") + git_repo.add_all("newcat: various updates") + commits = list(git.GitRepoCommits(path, "HEAD")) assert len(commits) == 4 - assert commits[0].message == ['newcat: various updates'] + assert commits[0].message == ["newcat: various updates"] assert commits[0].pkgs == { - 'A': {atom_cls('=newcat/newpkg-0'), atom_cls('=newcat/newpkg-1')}} + "A": {atom_cls("=newcat/newpkg-0"), atom_cls("=newcat/newpkg-1")} + } # remove the old version - git_repo.remove('newcat/newpkg/newpkg-0.ebuild') - commits = list(git.GitRepoCommits(path, 'HEAD')) + git_repo.remove("newcat/newpkg/newpkg-0.ebuild") + commits = list(git.GitRepoCommits(path, "HEAD")) assert len(commits) == 5 - assert commits[0].pkgs == {'D': {atom_cls('=newcat/newpkg-0')}} + assert commits[0].pkgs == {"D": {atom_cls("=newcat/newpkg-0")}} # rename the pkg - git_repo.move('newcat', 'newcat2') - commits = list(git.GitRepoCommits(path, 'HEAD')) + git_repo.move("newcat", "newcat2") + commits = list(git.GitRepoCommits(path, "HEAD")) assert len(commits) == 6 assert commits[0].pkgs == { - 'A': {atom_cls('=newcat2/newpkg-1')}, - 'D': {atom_cls('=newcat/newpkg-1')}, + "A": {atom_cls("=newcat2/newpkg-1")}, + "D": {atom_cls("=newcat/newpkg-1")}, } # malformed atoms don't show up as pkgs - repo.create_ebuild('cat/pkg-3') - git_repo.add_all('cat/pkg-3') - with patch('pkgcheck.addons.git.atom_cls') as fake_atom: - fake_atom.side_effect = MalformedAtom('bad atom') - commits = list(git.GitRepoCommits(path, 'HEAD')) + repo.create_ebuild("cat/pkg-3") + git_repo.add_all("cat/pkg-3") + with patch("pkgcheck.addons.git.atom_cls") as fake_atom: + fake_atom.side_effect = MalformedAtom("bad atom") + commits = list(git.GitRepoCommits(path, "HEAD")) assert len(commits) == 7 assert commits[0].pkgs == {} class TestGitRepoPkgs: - def test_non_git(self, tmp_path): - with pytest.raises(git.GitError, match='failed running git log'): - git.GitRepoPkgs(str(tmp_path), 'HEAD') + with pytest.raises(git.GitError, match="failed running git log"): + git.GitRepoPkgs(str(tmp_path), "HEAD") def test_empty_repo(self, make_git_repo): git_repo = make_git_repo() - with pytest.raises(git.GitError, match='failed running git log'): - git.GitRepoPkgs(git_repo.path, 'HEAD') + with pytest.raises(git.GitError, match="failed running git log"): + git.GitRepoPkgs(git_repo.path, "HEAD") def test_parsing(self, repo, make_git_repo): git_repo = make_git_repo(repo.location, commit=True) path = git_repo.path # empty repo contains no packages - pkgs = list(git.GitRepoPkgs(path, 'HEAD')) + pkgs = list(git.GitRepoPkgs(path, "HEAD")) assert len(pkgs) == 0 # create a pkg and commit it - repo.create_ebuild('cat/pkg-0') - git_repo.add_all('cat/pkg-0') - pkgs = list(git.GitRepoPkgs(path, 'HEAD')) + repo.create_ebuild("cat/pkg-0") + git_repo.add_all("cat/pkg-0") + pkgs = list(git.GitRepoPkgs(path, "HEAD")) assert len(pkgs) == 1 pkg = pkgs[0] - assert pkg.atom == atom_cls('=cat/pkg-0') - assert pkg.status == 'A' + assert pkg.atom == atom_cls("=cat/pkg-0") + assert pkg.status == "A" # add a new version and commit it - repo.create_ebuild('cat/pkg-1') - git_repo.add_all('cat/pkg-1') - pkgs = list(git.GitRepoPkgs(path, 'HEAD')) + repo.create_ebuild("cat/pkg-1") + git_repo.add_all("cat/pkg-1") + pkgs = list(git.GitRepoPkgs(path, "HEAD")) assert len(pkgs) == 2 pkg = pkgs[0] - assert pkg.atom == atom_cls('=cat/pkg-1') - assert pkg.status == 'A' + assert pkg.atom == atom_cls("=cat/pkg-1") + assert pkg.status == "A" # remove the old version - git_repo.remove('cat/pkg/pkg-0.ebuild') - pkgs = list(git.GitRepoPkgs(path, 'HEAD')) + git_repo.remove("cat/pkg/pkg-0.ebuild") + pkgs = list(git.GitRepoPkgs(path, "HEAD")) assert len(pkgs) == 3 pkg = pkgs[0] - assert pkg.atom == atom_cls('=cat/pkg-0') - assert pkg.status == 'D' + assert pkg.atom == atom_cls("=cat/pkg-0") + assert pkg.status == "D" # rename the pkg - git_repo.move('cat', 'cat2') - pkgs = list(git.GitRepoPkgs(path, 'HEAD')) + git_repo.move("cat", "cat2") + pkgs = list(git.GitRepoPkgs(path, "HEAD")) assert len(pkgs) == 5 new_pkg, old_pkg = pkgs[:2] - assert old_pkg.atom == atom_cls('=cat/pkg-1') - assert old_pkg.status == 'D' - assert new_pkg.atom == atom_cls('=cat2/pkg-1') - assert new_pkg.status == 'A' + assert old_pkg.atom == atom_cls("=cat/pkg-1") + assert old_pkg.status == "D" + assert new_pkg.atom == atom_cls("=cat2/pkg-1") + assert new_pkg.status == "A" # malformed atoms don't show up as pkgs - with patch('pkgcheck.addons.git.atom_cls') as fake_atom: - fake_atom.side_effect = MalformedAtom('bad atom') - pkgs = list(git.GitRepoPkgs(path, 'HEAD')) + with patch("pkgcheck.addons.git.atom_cls") as fake_atom: + fake_atom.side_effect = MalformedAtom("bad atom") + pkgs = list(git.GitRepoPkgs(path, "HEAD")) assert len(pkgs) == 0 class TestGitChangedRepo: - def test_pkg_history(self, repo, make_git_repo): git_repo = make_git_repo(repo.location, commit=True) pkg_history = partial(git.GitAddon.pkg_history, repo) # initialize the dict cache - data = pkg_history('HEAD') + data = pkg_history("HEAD") assert data == {} # overlay repo objects on top of the dict cache @@ -388,10 +386,10 @@ class TestGitChangedRepo: assert len(removed_repo) == 0 # create a pkg and commit it - repo.create_ebuild('cat/pkg-0') - git_repo.add_all('cat/pkg-0') + repo.create_ebuild("cat/pkg-0") + git_repo.add_all("cat/pkg-0") # update the dict cache - data = pkg_history('HEAD', data=data) + data = pkg_history("HEAD", data=data) commit = git_repo.HEAD # overlay repo objects on top of the dict cache @@ -405,10 +403,10 @@ class TestGitChangedRepo: assert len(removed_repo) == 0 # add a new version and commit it - repo.create_ebuild('cat/pkg-1') - git_repo.add_all('cat/pkg-1') + repo.create_ebuild("cat/pkg-1") + git_repo.add_all("cat/pkg-1") # update the dict cache - data = pkg_history(f'{commit}..HEAD', data=data) + data = pkg_history(f"{commit}..HEAD", data=data) commit = git_repo.HEAD # overlay repo objects on top of the dict cache @@ -422,9 +420,9 @@ class TestGitChangedRepo: assert len(removed_repo) == 0 # remove the old version - git_repo.remove('cat/pkg/pkg-0.ebuild') + git_repo.remove("cat/pkg/pkg-0.ebuild") # update the dict cache - data = pkg_history(f'{commit}..HEAD', data=data) + data = pkg_history(f"{commit}..HEAD", data=data) commit = git_repo.HEAD # overlay repo objects on top of the dict cache @@ -438,9 +436,9 @@ class TestGitChangedRepo: assert len(removed_repo) == 1 # rename the pkg - git_repo.move('cat', 'cat2') + git_repo.move("cat", "cat2") # update the dict cache - data = pkg_history(f'{commit}..HEAD', data=data) + data = pkg_history(f"{commit}..HEAD", data=data) commit = git_repo.HEAD # overlay repo objects on top of the dict cache @@ -455,51 +453,50 @@ class TestGitChangedRepo: class TestGitAddon: - @pytest.fixture(autouse=True) def _setup(self, tool, tmp_path, repo): self.repo = repo self.cache_dir = str(tmp_path) - args = ['scan', '--cache-dir', self.cache_dir, '--repo', self.repo.location] + args = ["scan", "--cache-dir", self.cache_dir, "--repo", self.repo.location] options, _ = tool.parse_args(args) self.addon = git.GitAddon(options) self.cache_file = self.addon.cache_file(self.repo) def test_git_unavailable(self, tool): - args = ['scan', '--cache-dir', self.cache_dir, '--repo', self.repo.location] + args = ["scan", "--cache-dir", self.cache_dir, "--repo", self.repo.location] options, _ = tool.parse_args(args) - with patch('pkgcheck.addons.git.find_binary') as find_binary: - find_binary.side_effect = CommandNotFound('git not found') - with pytest.raises(CacheDisabled, match='git cache support required'): + with patch("pkgcheck.addons.git.find_binary") as find_binary: + find_binary.side_effect = CommandNotFound("git not found") + with pytest.raises(CacheDisabled, match="git cache support required"): git.GitAddon(options) def test_no_gitignore(self): assert self.addon._gitignore is None - assert not self.addon.gitignored('') + assert not self.addon.gitignored("") def test_failed_gitignore(self): - with open(pjoin(self.repo.location, '.gitignore'), 'w') as f: - f.write('.*.swp\n') - with patch('pkgcheck.addons.git.open') as fake_open: - fake_open.side_effect = IOError('file reading failure') + with open(pjoin(self.repo.location, ".gitignore"), "w") as f: + f.write(".*.swp\n") + with patch("pkgcheck.addons.git.open") as fake_open: + fake_open.side_effect = IOError("file reading failure") assert self.addon._gitignore is None def test_gitignore(self): - for path in ('.gitignore', '.git/info/exclude'): + for path in (".gitignore", ".git/info/exclude"): file_path = pjoin(self.repo.location, path) os.makedirs(os.path.dirname(file_path), exist_ok=True) - with open(file_path, 'w') as f: - f.write('.*.swp\n') - assert self.addon.gitignored('.foo.swp') - assert self.addon.gitignored(pjoin(self.repo.location, '.foo.swp')) - assert not self.addon.gitignored('foo.swp') - assert not self.addon.gitignored(pjoin(self.repo.location, 'foo.swp')) + with open(file_path, "w") as f: + f.write(".*.swp\n") + assert self.addon.gitignored(".foo.swp") + assert self.addon.gitignored(pjoin(self.repo.location, ".foo.swp")) + assert not self.addon.gitignored("foo.swp") + assert not self.addon.gitignored(pjoin(self.repo.location, "foo.swp")) def test_cache_disabled(self, tool): - args = ['scan', '--cache', 'no', '--repo', self.repo.location] + args = ["scan", "--cache", "no", "--repo", self.repo.location] options, _ = tool.parse_args(args) - with pytest.raises(CacheDisabled, match='git cache support required'): + with pytest.raises(CacheDisabled, match="git cache support required"): init_addon(git.GitAddon, options) def test_non_git_repo(self): @@ -516,26 +513,26 @@ class TestGitAddon: """Cache file isn't updated if no relevant commits exist.""" parent_repo = make_git_repo(commit=True) child_repo = make_git_repo(self.repo.location, commit=False) - child_repo.run(['git', 'remote', 'add', 'origin', parent_repo.path]) - child_repo.run(['git', 'pull', 'origin', 'main']) - child_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + child_repo.run(["git", "remote", "add", "origin", parent_repo.path]) + child_repo.run(["git", "pull", "origin", "main"]) + child_repo.run(["git", "remote", "set-head", "origin", "main"]) self.addon.update_cache() assert not os.path.exists(self.cache_file) def test_cache_creation_and_load(self, repo, make_git_repo): parent_repo = make_git_repo(repo.location, commit=True) # create a pkg and commit it - repo.create_ebuild('cat/pkg-0') - parent_repo.add_all('cat/pkg-0') + repo.create_ebuild("cat/pkg-0") + parent_repo.add_all("cat/pkg-0") child_repo = make_git_repo(self.repo.location, commit=False) - child_repo.run(['git', 'remote', 'add', 'origin', parent_repo.path]) - child_repo.run(['git', 'pull', 'origin', 'main']) - child_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + child_repo.run(["git", "remote", "add", "origin", parent_repo.path]) + child_repo.run(["git", "pull", "origin", "main"]) + child_repo.run(["git", "remote", "set-head", "origin", "main"]) self.addon.update_cache() - assert atom_cls('=cat/pkg-0') in self.addon.cached_repo(git.GitAddedRepo) + assert atom_cls("=cat/pkg-0") in self.addon.cached_repo(git.GitAddedRepo) - with patch('pkgcheck.addons.caches.CachedAddon.save_cache') as save_cache: + with patch("pkgcheck.addons.caches.CachedAddon.save_cache") as save_cache: # verify the cache was loaded and not regenerated self.addon.update_cache() save_cache.assert_not_called() @@ -544,28 +541,28 @@ class TestGitAddon: save_cache.assert_called_once() # create another pkg and commit it to the parent repo - repo.create_ebuild('cat/pkg-1') - parent_repo.add_all('cat/pkg-1') + repo.create_ebuild("cat/pkg-1") + parent_repo.add_all("cat/pkg-1") self.addon.update_cache() - assert atom_cls('=cat/pkg-1') not in self.addon.cached_repo(git.GitAddedRepo) + assert atom_cls("=cat/pkg-1") not in self.addon.cached_repo(git.GitAddedRepo) # new package is seen after child repo pulls changes - child_repo.run(['git', 'pull', 'origin', 'main']) + child_repo.run(["git", "pull", "origin", "main"]) self.addon.update_cache() - assert atom_cls('=cat/pkg-1') in self.addon.cached_repo(git.GitAddedRepo) + assert atom_cls("=cat/pkg-1") in self.addon.cached_repo(git.GitAddedRepo) def test_outdated_cache(self, repo, make_git_repo): parent_repo = make_git_repo(repo.location, commit=True) # create a pkg and commit it - repo.create_ebuild('cat/pkg-0') - parent_repo.add_all('cat/pkg-0') + repo.create_ebuild("cat/pkg-0") + parent_repo.add_all("cat/pkg-0") child_repo = make_git_repo(self.repo.location, commit=False) - child_repo.run(['git', 'remote', 'add', 'origin', parent_repo.path]) - child_repo.run(['git', 'pull', 'origin', 'main']) - child_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + child_repo.run(["git", "remote", "add", "origin", parent_repo.path]) + child_repo.run(["git", "pull", "origin", "main"]) + child_repo.run(["git", "remote", "set-head", "origin", "main"]) self.addon.update_cache() - assert atom_cls('=cat/pkg-0') in self.addon.cached_repo(git.GitAddedRepo) + assert atom_cls("=cat/pkg-0") in self.addon.cached_repo(git.GitAddedRepo) # increment cache version and dump cache cache = self.addon.load_cache(self.cache_file) @@ -573,79 +570,79 @@ class TestGitAddon: self.addon.save_cache(cache, self.cache_file) # verify cache load causes regen - with patch('pkgcheck.addons.caches.CachedAddon.save_cache') as save_cache: + with patch("pkgcheck.addons.caches.CachedAddon.save_cache") as save_cache: self.addon.update_cache() save_cache.assert_called_once() def test_error_creating_cache(self, repo, make_git_repo): parent_repo = make_git_repo(repo.location, commit=True) # create a pkg and commit it - repo.create_ebuild('cat/pkg-0') - parent_repo.add_all('cat/pkg-0') + repo.create_ebuild("cat/pkg-0") + parent_repo.add_all("cat/pkg-0") child_repo = make_git_repo(self.repo.location, commit=False) - child_repo.run(['git', 'remote', 'add', 'origin', parent_repo.path]) - child_repo.run(['git', 'pull', 'origin', 'main']) - child_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + child_repo.run(["git", "remote", "add", "origin", parent_repo.path]) + child_repo.run(["git", "pull", "origin", "main"]) + child_repo.run(["git", "remote", "set-head", "origin", "main"]) - with patch('pkgcheck.addons.git.GitLog') as git_log: - git_log.side_effect = git.GitError('git parsing failed') - with pytest.raises(PkgcheckUserException, match='git parsing failed'): + with patch("pkgcheck.addons.git.GitLog") as git_log: + git_log.side_effect = git.GitError("git parsing failed") + with pytest.raises(PkgcheckUserException, match="git parsing failed"): self.addon.update_cache() def test_error_loading_cache(self, repo, make_git_repo): parent_repo = make_git_repo(repo.location, commit=True) # create a pkg and commit it - repo.create_ebuild('cat/pkg-0') - parent_repo.add_all('cat/pkg-0') + repo.create_ebuild("cat/pkg-0") + parent_repo.add_all("cat/pkg-0") child_repo = make_git_repo(self.repo.location, commit=False) - child_repo.run(['git', 'remote', 'add', 'origin', parent_repo.path]) - child_repo.run(['git', 'pull', 'origin', 'main']) - child_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + child_repo.run(["git", "remote", "add", "origin", parent_repo.path]) + child_repo.run(["git", "pull", "origin", "main"]) + child_repo.run(["git", "remote", "set-head", "origin", "main"]) self.addon.update_cache() - assert atom_cls('=cat/pkg-0') in self.addon.cached_repo(git.GitAddedRepo) + assert atom_cls("=cat/pkg-0") in self.addon.cached_repo(git.GitAddedRepo) - with patch('pkgcheck.addons.caches.pickle.load') as pickle_load: + with patch("pkgcheck.addons.caches.pickle.load") as pickle_load: # catastrophic errors are raised - pickle_load.side_effect = MemoryError('unpickling failed') - with pytest.raises(MemoryError, match='unpickling failed'): + pickle_load.side_effect = MemoryError("unpickling failed") + with pytest.raises(MemoryError, match="unpickling failed"): self.addon.update_cache() # but various load failure exceptions cause cache regen - pickle_load.side_effect = Exception('unpickling failed') - with patch('pkgcheck.addons.caches.CachedAddon.save_cache') as save_cache: + pickle_load.side_effect = Exception("unpickling failed") + with patch("pkgcheck.addons.caches.CachedAddon.save_cache") as save_cache: self.addon.update_cache() save_cache.assert_called_once() def test_error_dumping_cache(self, repo, make_git_repo): parent_repo = make_git_repo(repo.location, commit=True) # create a pkg and commit it - repo.create_ebuild('cat/pkg-0') - parent_repo.add_all('cat/pkg-0') + repo.create_ebuild("cat/pkg-0") + parent_repo.add_all("cat/pkg-0") child_repo = make_git_repo(self.repo.location, commit=False) - child_repo.run(['git', 'remote', 'add', 'origin', parent_repo.path]) - child_repo.run(['git', 'pull', 'origin', 'main']) - child_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + child_repo.run(["git", "remote", "add", "origin", parent_repo.path]) + child_repo.run(["git", "pull", "origin", "main"]) + child_repo.run(["git", "remote", "set-head", "origin", "main"]) # verify IO related dump failures are raised - with patch('pkgcheck.addons.caches.pickle.dump') as pickle_dump: - pickle_dump.side_effect = IOError('unpickling failed') - with pytest.raises(PkgcheckUserException, match='failed dumping git cache'): + with patch("pkgcheck.addons.caches.pickle.dump") as pickle_dump: + pickle_dump.side_effect = IOError("unpickling failed") + with pytest.raises(PkgcheckUserException, match="failed dumping git cache"): self.addon.update_cache() def test_commits_repo(self, repo, make_repo, make_git_repo): parent_repo = repo parent_git_repo = make_git_repo(repo.location, commit=True) # create a pkg and commit it - parent_repo.create_ebuild('cat/pkg-0') - parent_git_repo.add_all('cat/pkg-0') + parent_repo.create_ebuild("cat/pkg-0") + parent_git_repo.add_all("cat/pkg-0") child_git_repo = make_git_repo(self.repo.location, commit=False) - child_git_repo.run(['git', 'remote', 'add', 'origin', parent_git_repo.path]) - child_git_repo.run(['git', 'pull', 'origin', 'main']) - child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + child_git_repo.run(["git", "remote", "add", "origin", parent_git_repo.path]) + child_git_repo.run(["git", "pull", "origin", "main"]) + child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.addon.update_cache() # no new pkg commits exist locally in the child repo @@ -654,37 +651,37 @@ class TestGitAddon: # create a pkg in the child repo and commit it child_repo = make_repo(child_git_repo.path) - child_repo.create_ebuild('cat/pkg-1') - child_git_repo.add_all('cat/pkg-1') + child_repo.create_ebuild("cat/pkg-1") + child_git_repo.add_all("cat/pkg-1") # pkg commits now exist locally in the child repo commits_repo = self.addon.commits_repo(git.GitChangedRepo) assert len(commits_repo) == 1 - assert atom_cls('=cat/pkg-1') in commits_repo + assert atom_cls("=cat/pkg-1") in commits_repo # failing to parse git log returns error with git cache enabled - with patch('pkgcheck.addons.git.GitLog') as git_log: - git_log.side_effect = git.GitError('git parsing failed') - with pytest.raises(PkgcheckUserException, match='git parsing failed'): + with patch("pkgcheck.addons.git.GitLog") as git_log: + git_log.side_effect = git.GitError("git parsing failed") + with pytest.raises(PkgcheckUserException, match="git parsing failed"): self.addon.commits_repo(git.GitChangedRepo) # failing to parse git log yields an empty repo with git cache disabled - with patch('pkgcheck.addons.git.GitLog') as git_log: - git_log.side_effect = git.GitError('git parsing failed') - with pytest.raises(PkgcheckUserException, match='git parsing failed'): + with patch("pkgcheck.addons.git.GitLog") as git_log: + git_log.side_effect = git.GitError("git parsing failed") + with pytest.raises(PkgcheckUserException, match="git parsing failed"): self.addon.commits_repo(git.GitChangedRepo) def test_commits(self, repo, make_repo, make_git_repo): parent_repo = repo parent_git_repo = make_git_repo(repo.location, commit=True) # create a pkg and commit it - parent_repo.create_ebuild('cat/pkg-0') - parent_git_repo.add_all('cat/pkg-0') + parent_repo.create_ebuild("cat/pkg-0") + parent_git_repo.add_all("cat/pkg-0") child_git_repo = make_git_repo(self.repo.location, commit=False) - child_git_repo.run(['git', 'remote', 'add', 'origin', parent_git_repo.path]) - child_git_repo.run(['git', 'pull', 'origin', 'main']) - child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + child_git_repo.run(["git", "remote", "add", "origin", parent_git_repo.path]) + child_git_repo.run(["git", "pull", "origin", "main"]) + child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.addon.update_cache() # no new commits exist locally in the child repo @@ -692,22 +689,22 @@ class TestGitAddon: # create a pkg in the child repo and commit it child_repo = make_repo(child_git_repo.path) - child_repo.create_ebuild('cat/pkg-1') - child_git_repo.add_all('cat/pkg-1') + child_repo.create_ebuild("cat/pkg-1") + child_git_repo.add_all("cat/pkg-1") # commits now exist locally in the child repo commits = list(self.addon.commits()) assert len(commits) == 1 - assert commits[0].message == ['cat/pkg-1'] + assert commits[0].message == ["cat/pkg-1"] # failing to parse git log returns error with git cache enabled - with patch('pkgcheck.addons.git.GitLog') as git_log: - git_log.side_effect = git.GitError('git parsing failed') - with pytest.raises(PkgcheckUserException, match='git parsing failed'): + with patch("pkgcheck.addons.git.GitLog") as git_log: + git_log.side_effect = git.GitError("git parsing failed") + with pytest.raises(PkgcheckUserException, match="git parsing failed"): list(self.addon.commits()) # failing to parse git log raises exception - with patch('pkgcheck.addons.git.GitLog') as git_log: - git_log.side_effect = git.GitError('git parsing failed') - with pytest.raises(PkgcheckUserException, match='git parsing failed'): + with patch("pkgcheck.addons.git.GitLog") as git_log: + git_log.side_effect = git.GitError("git parsing failed") + with pytest.raises(PkgcheckUserException, match="git parsing failed"): self.addon.commits() diff --git a/tests/checks/test_acct.py b/tests/checks/test_acct.py index 57273705..4c8202dc 100644 --- a/tests/checks/test_acct.py +++ b/tests/checks/test_acct.py @@ -12,81 +12,86 @@ class TestAcctUser(misc.ReportTestCase): check_kls = acct.AcctCheck - kind = 'user' + kind = "user" @pytest.fixture(autouse=True) def _setup(self, tmp_path): - (metadata := tmp_path / 'metadata').mkdir() - (metadata / 'qa-policy.conf').write_text(textwrap.dedent("""\ - [user-group-ids] - uid-range = 0-749,65534 - gid-range = 0-749,65533,65534 - """)) + (metadata := tmp_path / "metadata").mkdir() + (metadata / "qa-policy.conf").write_text( + textwrap.dedent( + """\ + [user-group-ids] + uid-range = 0-749,65534 + gid-range = 0-749,65533,65534 + """ + ) + ) self.location = str(tmp_path) def mk_check(self, pkgs): - repo = FakeRepo(pkgs=pkgs, repo_id='test', location=self.location) + repo = FakeRepo(pkgs=pkgs, repo_id="test", location=self.location) check = self.check_kls(arghparse.Namespace(target_repo=repo, gentoo_repo=True)) return check def mk_pkg(self, name, identifier, version=1, ebuild=None): if ebuild is None: - ebuild = textwrap.dedent(f'''\ - inherit acct-{self.kind} - ACCT_{self.kind.upper()}_ID="{identifier}" - ''') - return misc.FakePkg(f'acct-{self.kind}/{name}-{version}', ebuild=ebuild) + ebuild = textwrap.dedent( + f"""\ + inherit acct-{self.kind} + ACCT_{self.kind.upper()}_ID="{identifier}" + """ + ) + return misc.FakePkg(f"acct-{self.kind}/{name}-{version}", ebuild=ebuild) def test_unmatching_pkgs(self): - pkgs = (misc.FakePkg('dev-util/foo-0'), - misc.FakePkg('dev-util/bar-1')) + pkgs = (misc.FakePkg("dev-util/foo-0"), misc.FakePkg("dev-util/bar-1")) check = self.mk_check(pkgs) self.assertNoReport(check, pkgs) def test_correct_ids(self): - pkgs = (self.mk_pkg('foo', 100), - self.mk_pkg('bar', 200), - self.mk_pkg('test', 749), - self.mk_pkg('nobody', 65534)) + pkgs = ( + self.mk_pkg("foo", 100), + self.mk_pkg("bar", 200), + self.mk_pkg("test", 749), + self.mk_pkg("nobody", 65534), + ) check = self.mk_check(pkgs) self.assertNoReport(check, pkgs) def test_missing_ids(self): - pkg = self.mk_pkg('foo', None, ebuild='inherit acct-user\n') + pkg = self.mk_pkg("foo", None, ebuild="inherit acct-user\n") check = self.mk_check((pkg,)) r = self.assertReport(check, pkg) assert isinstance(r, acct.MissingAccountIdentifier) - assert r.var == f'ACCT_{self.kind.upper()}_ID' + assert r.var == f"ACCT_{self.kind.upper()}_ID" assert r.var in str(r) def test_conflicting_ids(self): - pkgs = (self.mk_pkg('foo', 100), - self.mk_pkg('bar', 100)) + pkgs = (self.mk_pkg("foo", 100), self.mk_pkg("bar", 100)) check = self.mk_check(pkgs) r = self.assertReport(check, pkgs) assert isinstance(r, acct.ConflictingAccountIdentifiers) assert r.kind == self.kind assert r.identifier == 100 - assert r.pkgs == (f'acct-{self.kind}/bar-1', f'acct-{self.kind}/foo-1') - assert f'conflicting {self.kind} id 100 usage: ' in str(r) + assert r.pkgs == (f"acct-{self.kind}/bar-1", f"acct-{self.kind}/foo-1") + assert f"conflicting {self.kind} id 100 usage: " in str(r) def test_self_nonconflicting_ids(self): - pkgs = (self.mk_pkg('foo', 100), - self.mk_pkg('foo', 100, version=2)) + pkgs = (self.mk_pkg("foo", 100), self.mk_pkg("foo", 100, version=2)) check = self.mk_check(pkgs) self.assertNoReport(check, pkgs) def test_dynamic_assignment_range(self): - pkg = self.mk_pkg('foo', 750) + pkg = self.mk_pkg("foo", 750) check = self.mk_check((pkg,)) r = self.assertReport(check, pkg) assert isinstance(r, acct.OutsideRangeAccountIdentifier) assert r.kind == self.kind assert r.identifier == 750 - assert f'{self.kind} id 750 outside permitted' in str(r) + assert f"{self.kind} id 750 outside permitted" in str(r) def test_sysadmin_assignment_range(self): - pkg = self.mk_pkg('foo', 1000) + pkg = self.mk_pkg("foo", 1000) check = self.mk_check((pkg,)) r = self.assertReport(check, pkg) assert isinstance(r, acct.OutsideRangeAccountIdentifier) @@ -94,7 +99,7 @@ class TestAcctUser(misc.ReportTestCase): assert r.identifier == 1000 def test_high_reserved(self): - pkg = self.mk_pkg('foo', 65535) + pkg = self.mk_pkg("foo", 65535) check = self.mk_check((pkg,)) r = self.assertReport(check, pkg) assert isinstance(r, acct.OutsideRangeAccountIdentifier) @@ -103,7 +108,7 @@ class TestAcctUser(misc.ReportTestCase): def test_nogroup(self): """Test that 65533 is not accepted for UID.""" - pkg = self.mk_pkg('nogroup', 65533) + pkg = self.mk_pkg("nogroup", 65533) check = self.mk_check((pkg,)) r = self.assertReport(check, pkg) assert isinstance(r, acct.OutsideRangeAccountIdentifier) @@ -111,28 +116,27 @@ class TestAcctUser(misc.ReportTestCase): assert r.identifier == 65533 def test_nobody(self): - pkg = self.mk_pkg('nobody', 65534) + pkg = self.mk_pkg("nobody", 65534) check = self.mk_check((pkg,)) self.assertNoReport(check, pkg) class TestAcctGroup(TestAcctUser): - kind = 'group' + kind = "group" def test_nogroup(self): """Test that 65533 is accepted for GID.""" - pkg = self.mk_pkg('nogroup', 65533) + pkg = self.mk_pkg("nogroup", 65533) check = self.mk_check((pkg,)) self.assertNoReport(check, pkg) class TestQaPolicyValidation(misc.ReportTestCase): - def mk_check(self, tmp_path, content): if content: - (metadata := tmp_path / 'metadata').mkdir() - (metadata / 'qa-policy.conf').write_text(textwrap.dedent(content)) - repo = FakeRepo(repo_id='test', location=str(tmp_path)) + (metadata := tmp_path / "metadata").mkdir() + (metadata / "qa-policy.conf").write_text(textwrap.dedent(content)) + repo = FakeRepo(repo_id="test", location=str(tmp_path)) return acct.AcctCheck(arghparse.Namespace(target_repo=repo, gentoo_repo=True)) def test_missing_qa_policy(self, tmp_path): @@ -141,27 +145,39 @@ class TestQaPolicyValidation(misc.ReportTestCase): def test_missing_section(self, tmp_path): with pytest.raises(SkipCheck, match="missing section user-group-ids"): - self.mk_check(tmp_path, '''\ + self.mk_check( + tmp_path, + """\ [random] x = 5 - ''') + """, + ) def test_missing_config(self, tmp_path): with pytest.raises(SkipCheck, match="missing value for gid-range"): - self.mk_check(tmp_path, '''\ + self.mk_check( + tmp_path, + """\ [user-group-ids] uid-range = 0-749 - ''') - - @pytest.mark.parametrize('value', ( - 'start-end', - '0-749-1500', - ',150', - )) + """, + ) + + @pytest.mark.parametrize( + "value", + ( + "start-end", + "0-749-1500", + ",150", + ), + ) def test_invalid_value(self, tmp_path, value): with pytest.raises(SkipCheck, match="invalid value for uid-range"): - self.mk_check(tmp_path, f'''\ + self.mk_check( + tmp_path, + f"""\ [user-group-ids] uid-range = {value} gid-range = 0-749 - ''') + """, + ) diff --git a/tests/checks/test_all.py b/tests/checks/test_all.py index 2ca8a114..a153a802 100644 --- a/tests/checks/test_all.py +++ b/tests/checks/test_all.py @@ -22,96 +22,91 @@ class TestMetadataError: def test_reregister_error(self): with pytest.raises(ValueError, match="metadata attribute 'eapi' already registered"): + class InvalidEapi2(results.MetadataError, results.VersionResult): - attr = 'eapi' + attr = "eapi" def test_register_missing_attr(self): with pytest.raises(ValueError, match="class missing metadata attributes"): + class InvalidAttr(results.MetadataError, results.VersionResult): pass class TestGentooRepoCheck: - def test_non_gentoo_repo(self, tool, make_repo): self.repo = make_repo() - args = ['scan', '--repo', self.repo.location] + args = ["scan", "--repo", self.repo.location] options, _ = tool.parse_args(args) - with pytest.raises(checks_mod.SkipCheck, match='not running against gentoo repo'): + with pytest.raises(checks_mod.SkipCheck, match="not running against gentoo repo"): init_check(checks_mod.GentooRepoCheck, options) def test_gentoo_repo(self, tool, make_repo): - self.repo = make_repo(repo_id='gentoo') - args = ['scan', '--repo', self.repo.location] + self.repo = make_repo(repo_id="gentoo") + args = ["scan", "--repo", self.repo.location] options, _ = tool.parse_args(args) assert init_check(checks_mod.GentooRepoCheck, options) class TestOverlayCheck: - def test_non_overlay_repo(self, tool, testconfig): tool.parser.set_defaults(config_path=testconfig) - options, _ = tool.parse_args(['scan', '--repo', 'gentoo']) - with pytest.raises(checks_mod.SkipCheck, match='not running against overlay'): + options, _ = tool.parse_args(["scan", "--repo", "gentoo"]) + with pytest.raises(checks_mod.SkipCheck, match="not running against overlay"): init_check(checks_mod.OverlayRepoCheck, options) def test_overlay_repo(self, tool, testconfig): tool.parser.set_defaults(config_path=testconfig) - options, _ = tool.parse_args(['scan', '--repo', 'overlay']) + options, _ = tool.parse_args(["scan", "--repo", "overlay"]) assert init_check(checks_mod.OverlayRepoCheck, options) class TestGitCommitsCheck: - @pytest.fixture(autouse=True) def _setup(self, tool, make_repo, make_git_repo): # initialize parent repo self.parent_git_repo = make_git_repo() - self.parent_repo = make_repo( - self.parent_git_repo.path, repo_id='gentoo', arches=['amd64']) - self.parent_git_repo.add_all('initial commit') + self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo", arches=["amd64"]) + self.parent_git_repo.add_all("initial commit") # initialize child repo self.child_git_repo = make_git_repo() - self.child_git_repo.run(['git', 'remote', 'add', 'origin', self.parent_git_repo.path]) - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + self.child_git_repo.run(["git", "remote", "add", "origin", self.parent_git_repo.path]) + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.child_repo = make_repo(self.child_git_repo.path) def test_no_commits_option(self, tool, make_git_repo): - options, _ = tool.parse_args( - ['scan', '--repo', self.child_repo.location]) - with pytest.raises(checks_mod.SkipCheck, match='not scanning against git commits'): + options, _ = tool.parse_args(["scan", "--repo", self.child_repo.location]) + with pytest.raises(checks_mod.SkipCheck, match="not scanning against git commits"): init_check(checks_mod.GitCommitsCheck, options) def test_commits_option(self, tool, make_repo): - self.child_repo.create_ebuild('cat/pkg-1') - self.child_git_repo.add_all('cat/pkg-1') - options, _ = tool.parse_args( - ['scan', '--repo', self.child_repo.location, '--commits']) + self.child_repo.create_ebuild("cat/pkg-1") + self.child_git_repo.add_all("cat/pkg-1") + options, _ = tool.parse_args(["scan", "--repo", self.child_repo.location, "--commits"]) assert init_check(checks_mod.GitCommitsCheck, options) def test_no_local_commits(self, tool): with pytest.raises(SystemExit) as excinfo: - tool.parse_args(['scan', '--repo', self.child_repo.location, '--commits']) + tool.parse_args(["scan", "--repo", self.child_repo.location, "--commits"]) assert excinfo.value.code == 0 # parent repo has new commits - self.parent_repo.create_ebuild('cat/pkg-1') - self.parent_git_repo.add_all('cat/pkg-1') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1") + self.parent_git_repo.add_all("cat/pkg-1") + self.child_git_repo.run(["git", "pull", "origin", "main"]) with pytest.raises(SystemExit) as excinfo: - tool.parse_args(['scan', '--repo', self.child_repo.location, '--commits']) + tool.parse_args(["scan", "--repo", self.child_repo.location, "--commits"]) assert excinfo.value.code == 0 class TestNetworkCheck: - def test_network_disabled(self, tool): - options, _ = tool.parse_args(['scan']) - with pytest.raises(checks_mod.SkipCheck, match='network checks not enabled'): + options, _ = tool.parse_args(["scan"]) + with pytest.raises(checks_mod.SkipCheck, match="network checks not enabled"): init_check(checks_mod.NetworkCheck, options) def test_network_enabled(self, tool): - options, _ = tool.parse_args(['scan', '--net']) + options, _ = tool.parse_args(["scan", "--net"]) assert init_check(checks_mod.NetworkCheck, options) diff --git a/tests/checks/test_cleanup.py b/tests/checks/test_cleanup.py index 4e1aa2b3..7ca2f3b6 100644 --- a/tests/checks/test_cleanup.py +++ b/tests/checks/test_cleanup.py @@ -3,10 +3,12 @@ from snakeoil.cli import arghparse from .. import misc + def mk_pkg(ver, keywords=("x86", "amd64"), slot="0", **kwds): return misc.FakePkg( - f"dev-util/diffball-{ver}", - data={**kwds, "KEYWORDS": ' '.join(keywords), "SLOT": slot}) + f"dev-util/diffball-{ver}", data={**kwds, "KEYWORDS": " ".join(keywords), "SLOT": slot} + ) + class TestRedundantVersion(misc.ReportTestCase): @@ -17,50 +19,43 @@ class TestRedundantVersion(misc.ReportTestCase): self.assertNoReport(self.check, [mk_pkg("0.7.1")]) def test_live_version(self): - self.assertNoReport( - self.check, [mk_pkg('0.7'), mk_pkg('0.9', PROPERTIES='live')]) - self.assertNoReport( - self.check, [mk_pkg('0.7'), mk_pkg('9999', PROPERTIES='live')]) + self.assertNoReport(self.check, [mk_pkg("0.7"), mk_pkg("0.9", PROPERTIES="live")]) + self.assertNoReport(self.check, [mk_pkg("0.7"), mk_pkg("9999", PROPERTIES="live")]) def test_no_keywords(self): - self.assertNoReport( - self.check, [mk_pkg('0.7'), mk_pkg('0.9', keywords=())]) + self.assertNoReport(self.check, [mk_pkg("0.7"), mk_pkg("0.9", keywords=())]) def test_disabled_keywords(self): - self.assertNoReport( - self.check, [mk_pkg('0.7'), mk_pkg('0.9', keywords=('-x86', '-amd64'))]) + self.assertNoReport(self.check, [mk_pkg("0.7"), mk_pkg("0.9", keywords=("-x86", "-amd64"))]) def test_single_redundant(self): - r = self.assertReport( - self.check, [mk_pkg(x) for x in ("0.7", "0.8")]) + r = self.assertReport(self.check, [mk_pkg(x) for x in ("0.7", "0.8")]) assert isinstance(r, cleanup.RedundantVersion) assert r.later_versions == ("0.8",) - assert 'slot(0) keywords are overshadowed by version: 0.8' in str(r) + assert "slot(0) keywords are overshadowed by version: 0.8" in str(r) def test_multiple_redundants(self): - reports = self.assertReports( - self.check, [mk_pkg(x) for x in ("0.7", "0.8", "0.9")]) - assert ( - [list(x.later_versions) for x in reports] == - [["0.8", "0.9"], ["0.9"]]) + reports = self.assertReports(self.check, [mk_pkg(x) for x in ("0.7", "0.8", "0.9")]) + assert [list(x.later_versions) for x in reports] == [["0.8", "0.9"], ["0.9"]] for x in reports: assert isinstance(x, cleanup.RedundantVersion) def test_multiple_slots(self): - l = [mk_pkg("0.7", slot="1"), mk_pkg("0.8"), - mk_pkg("0.9", slot="1")] + l = [mk_pkg("0.7", slot="1"), mk_pkg("0.8"), mk_pkg("0.9", slot="1")] r = self.assertReport(self.check, l) assert r.later_versions == ("0.9",) assert isinstance(r, cleanup.RedundantVersion) - assert 'slot(1) keywords are overshadowed by version: 0.9' in str(r) + assert "slot(1) keywords are overshadowed by version: 0.9" in str(r) l.append(mk_pkg("0.10", keywords=("x86", "amd64", "~sparc"))) reports = self.assertReports(self.check, l) - assert ([list(x.later_versions) for x in reports] == [["0.9"], ["0.10"]]) + assert [list(x.later_versions) for x in reports] == [["0.9"], ["0.10"]] def test_multiple_keywords(self): - l = [mk_pkg("0.1", keywords=("~x86", "~amd64")), - mk_pkg("0.2", keywords=("x86", "~amd64", "~sparc"))] + l = [ + mk_pkg("0.1", keywords=("~x86", "~amd64")), + mk_pkg("0.2", keywords=("x86", "~amd64", "~sparc")), + ] r = self.assertReport(self.check, l) assert r.later_versions == ("0.2",) @@ -71,32 +66,33 @@ class TestRedundantVersionByStable(misc.ReportTestCase): check = cleanup.RedundantVersionCheck(arghparse.Namespace(stable_only=True), profile_addon={}) def test_only_unstable(self): - l = [mk_pkg("0.1", keywords=("~x86", "~amd64")), - mk_pkg("0.2", keywords=("~x86", "~amd64"))] + l = [mk_pkg("0.1", keywords=("~x86", "~amd64")), mk_pkg("0.2", keywords=("~x86", "~amd64"))] self.assertNoReport(self.check, l) def test_only_stable(self): - l = [mk_pkg("0.1", keywords=("x86", "amd64")), - mk_pkg("0.2", keywords=("x86", "amd64"))] + l = [mk_pkg("0.1", keywords=("x86", "amd64")), mk_pkg("0.2", keywords=("x86", "amd64"))] r = self.assertReport(self.check, l) assert r.later_versions == ("0.2",) def test_mixed_stable(self): - l = [mk_pkg("0.1", keywords=("x86", "amd64", "~sparc")), - mk_pkg("0.2", keywords=("x86", "amd64", "~sparc"))] + l = [ + mk_pkg("0.1", keywords=("x86", "amd64", "~sparc")), + mk_pkg("0.2", keywords=("x86", "amd64", "~sparc")), + ] r = self.assertReport(self.check, l) assert r.later_versions == ("0.2",) def test_mixed_history(self): - l = [mk_pkg("0.1", keywords=("amd64")), - mk_pkg("0.2", keywords=("~x86", "~amd64")), - mk_pkg("0.3", keywords=("x86", "amd64")), - mk_pkg("0.4", keywords=("~x86", "~amd64")), - mk_pkg("0.5", keywords=("~x86", "~amd64"))] + l = [ + mk_pkg("0.1", keywords=("amd64")), + mk_pkg("0.2", keywords=("~x86", "~amd64")), + mk_pkg("0.3", keywords=("x86", "amd64")), + mk_pkg("0.4", keywords=("~x86", "~amd64")), + mk_pkg("0.5", keywords=("~x86", "~amd64")), + ] r = self.assertReport(self.check, l) assert r.later_versions == ("0.3", "0.4", "0.5") def test_no_redundant(self): - l = [mk_pkg("0.1", keywords=("x86", "amd64")), - mk_pkg("0.2", keywords=("x86", "~amd64"))] + l = [mk_pkg("0.1", keywords=("x86", "amd64")), mk_pkg("0.2", keywords=("x86", "~amd64"))] self.assertNoReport(self.check, l) diff --git a/tests/checks/test_codingstyle.py b/tests/checks/test_codingstyle.py index 1c6a0075..528faa8b 100644 --- a/tests/checks/test_codingstyle.py +++ b/tests/checks/test_codingstyle.py @@ -30,8 +30,12 @@ class TestInsintoCheck(misc.ReportTestCase): fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) bad = ( - "/etc/env.d", "/etc/conf.d", "/etc/init.d", "/etc/pam.d", - "/usr/share/applications", "/usr/share/applications", + "/etc/env.d", + "/etc/conf.d", + "/etc/init.d", + "/etc/pam.d", + "/usr/share/applications", + "/usr/share/applications", "//usr/share//applications", ) check = self.check_kls(None) @@ -42,11 +46,12 @@ class TestInsintoCheck(misc.ReportTestCase): def test_docinto(self): check = self.check_kls(None) - for path in ('${PF}', '${P}', '${PF}/examples'): + for path in ("${PF}", "${P}", "${PF}/examples"): for eapi_str, eapi in EAPI.known_eapis.items(): - fake_src = [f'\tinsinto /usr/share/doc/{path}\n'] + fake_src = [f"\tinsinto /usr/share/doc/{path}\n"] fake_pkg = misc.FakePkg( - "dev-util/diff-0.5", data={'EAPI': eapi_str}, lines=fake_src) + "dev-util/diff-0.5", data={"EAPI": eapi_str}, lines=fake_src + ) if eapi.options.dodoc_allow_recursive: r = self.assertReport(check, fake_pkg) assert path in str(r) @@ -68,10 +73,10 @@ class TestAbsoluteSymlink(misc.ReportTestCase): absolute_prefixed = [] for path_var in codingstyle.PATH_VARIABLES: - src, dest = ('/bin/blah', '/bin/bash') + src, dest = ("/bin/blah", "/bin/bash") absolute_prefixed.append((f'"${{{path_var}}}"{src}', dest)) absolute_prefixed.append((f'"${{{path_var}%/}}"{src}', dest)) - src, dest = ('/bin/blah baz', '/bin/blahbaz') + src, dest = ("/bin/blah baz", "/bin/blahbaz") absolute_prefixed.append((f'"${{{path_var}}}{src}"', dest)) absolute_prefixed.append((f'"${{{path_var}%/}}{src}"', dest)) @@ -99,7 +104,7 @@ class TestAbsoluteSymlink(misc.ReportTestCase): assert len(reports) == len(absolute) + len(absolute_prefixed) for r, (src, dest) in zip(reports, absolute + absolute_prefixed): - assert f'dosym {src}' in str(r) + assert f"dosym {src}" in str(r) class TestPathVariablesCheck(misc.ReportTestCase): @@ -107,7 +112,7 @@ class TestPathVariablesCheck(misc.ReportTestCase): check_kls = codingstyle.PathVariablesCheck check = check_kls(None) - def _found(self, cls, suffix=''): + def _found(self, cls, suffix=""): # check single and multiple matches across all specified variables for lines in (1, 2): for path_var in codingstyle.PATH_VARIABLES: @@ -117,17 +122,18 @@ class TestPathVariablesCheck(misc.ReportTestCase): fake_src.extend(["}\n", "\n"]) for eapi_str, eapi in EAPI.known_eapis.items(): fake_pkg = misc.FakePkg( - "dev-util/diff-0.5", data={'EAPI': eapi_str}, lines=fake_src) + "dev-util/diff-0.5", data={"EAPI": eapi_str}, lines=fake_src + ) if eapi.options.trailing_slash: self.assertNoReport(self.check, fake_pkg) else: r = self.assertReport(self.check, fake_pkg) assert isinstance(r, cls) - assert r.match == f'${{{path_var}{suffix}}}' + assert r.match == f"${{{path_var}{suffix}}}" assert r.lines == tuple(x + 2 for x in range(lines)) assert path_var in str(r) - def _unfound(self, cls, suffix=''): + def _unfound(self, cls, suffix=""): for path_var in codingstyle.PATH_VARIABLES: fake_src = [ "src_install() {\n", @@ -138,7 +144,8 @@ class TestPathVariablesCheck(misc.ReportTestCase): ] for eapi_str, eapi in EAPI.known_eapis.items(): fake_pkg = misc.FakePkg( - "dev-util/diffball-0.5", data={'EAPI': eapi_str}, lines=fake_src) + "dev-util/diffball-0.5", data={"EAPI": eapi_str}, lines=fake_src + ) self.assertNoReport(self.check, fake_pkg) def test_missing_found(self): @@ -148,14 +155,14 @@ class TestPathVariablesCheck(misc.ReportTestCase): self._unfound(codingstyle.MissingSlash) def test_unnecessary_found(self): - self._found(codingstyle.UnnecessarySlashStrip, suffix='%/') + self._found(codingstyle.UnnecessarySlashStrip, suffix="%/") def test_unnecessary_unfound(self): - self._unfound(codingstyle.UnnecessarySlashStrip, suffix='%/') + self._unfound(codingstyle.UnnecessarySlashStrip, suffix="%/") def test_double_prefix_found(self): fake_src = [ - 'src_install() {\n', + "src_install() {\n", ' cp foo.py "${ED}$(python_get_sitedir)"\n', # test non-match ' cp foo.py "${D%/}$(python_get_sitedir)"\n', @@ -174,17 +181,17 @@ class TestPathVariablesCheck(misc.ReportTestCase): ' dodir /foo/bar "${EPREFIX}"/bar/baz\n', # commented lines aren't flagged for double prefix usage '# exeinto "${EPREFIX}/foo/bar"\n', - '}\n' + "}\n", ] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) r = self.assertReports(self.check, fake_pkg) cls = codingstyle.DoublePrefixInPath expected_results = ( - ('${ED}$(python_get_sitedir)', 2), - ('${ED%/}$(python_get_sitedir)', 4), - ('${ED}/$(python_get_sitedir)', 5), - ('${ED}${PYTHON_SITEDIR}', 6), - ('${ED}${EPREFIX}', 7), + ("${ED}$(python_get_sitedir)", 2), + ("${ED%/}$(python_get_sitedir)", 4), + ("${ED}/$(python_get_sitedir)", 5), + ("${ED}${PYTHON_SITEDIR}", 6), + ("${ED}${EPREFIX}", 7), ('insinto "$(python_get_sitedir)', 8), ('exeinto "${EPREFIX}', 9), ('fowners foo:bar "$(python_get_sitedir)', 10), @@ -199,16 +206,16 @@ class TestPathVariablesCheck(misc.ReportTestCase): def test_double_prefix_unfound(self): fake_src = [ - 'src_install() {\n', + "src_install() {\n", ' cp foo.py "${D}$(python_get_sitedir)"\n', ' cp foo "${D}${EPREFIX}/foo/bar"\n', - ' insinto /foo/bar\n', + " insinto /foo/bar\n", # potential false positives: stripping prefix ' insinto "${MYVAR#${EPREFIX}}"\n', ' insinto "${MYVAR#"${EPREFIX}"}"\n', # combined commands ' dodir /etc/env.d && echo "FOO=${EPREFIX}"\n', - '}\n' + "}\n", ] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) self.assertNoReport(self.check, fake_pkg) @@ -219,99 +226,76 @@ class TestObsoleteUri(misc.ReportTestCase): check_kls = codingstyle.ObsoleteUriCheck def test_github_archive_uri(self): - uri = 'https://github.com/foo/bar/archive/${PV}.tar.gz' - fake_src = [ - f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n' - ] + uri = "https://github.com/foo/bar/archive/${PV}.tar.gz" + fake_src = [f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) self.assertNoReport(self.check_kls(None), fake_pkg) def test_commented_github_tarball_uri(self): - uri = 'https://github.com/foo/bar/tarball/${PV}' - fake_src = [ - '# github tarball\n', - '\n', - f'# {uri}\n' - ] + uri = "https://github.com/foo/bar/tarball/${PV}" + fake_src = ["# github tarball\n", "\n", f"# {uri}\n"] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) self.assertNoReport(self.check_kls(None), fake_pkg) def test_github_tarball_uri(self): - uri = 'https://github.com/foo/bar/tarball/${PV}' - fake_src = [ - f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n' - ] + uri = "https://github.com/foo/bar/tarball/${PV}" + fake_src = [f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) r = self.assertReport(self.check_kls(None), fake_pkg) assert r.line == 1 assert r.uri == uri - assert (r.replacement == - 'https://github.com/foo/bar/archive/${PV}.tar.gz') + assert r.replacement == "https://github.com/foo/bar/archive/${PV}.tar.gz" assert uri in str(r) def test_github_zipball_uri(self): - uri = 'https://github.com/foo/bar/zipball/${PV}' - fake_src = [ - f'SRC_URI="{uri} -> ${{P}}.zip"\n' - ] + uri = "https://github.com/foo/bar/zipball/${PV}" + fake_src = [f'SRC_URI="{uri} -> ${{P}}.zip"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) r = self.assertReport(self.check_kls(None), fake_pkg) assert r.line == 1 assert r.uri == uri - assert (r.replacement == - 'https://github.com/foo/bar/archive/${PV}.tar.gz') + assert r.replacement == "https://github.com/foo/bar/archive/${PV}.tar.gz" assert uri in str(r) def test_gitlab_archive_uri(self): - uri = 'https://gitlab.com/foo/bar/-/archive/${PV}/${P}.tar.gz' - fake_src = [ - f'SRC_URI="{uri}"\n' - ] + uri = "https://gitlab.com/foo/bar/-/archive/${PV}/${P}.tar.gz" + fake_src = [f'SRC_URI="{uri}"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) self.assertNoReport(self.check_kls(None), fake_pkg) def test_gitlab_tar_gz_uri(self): - uri = 'https://gitlab.com/foo/bar/repository/archive.tar.gz?ref=${PV}' - fake_src = [ - f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n' - ] + uri = "https://gitlab.com/foo/bar/repository/archive.tar.gz?ref=${PV}" + fake_src = [f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) r = self.assertReport(self.check_kls(None), fake_pkg) assert r.line == 1 assert r.uri == uri - assert (r.replacement == - 'https://gitlab.com/foo/bar/-/archive/${PV}/bar-${PV}.tar.gz') + assert r.replacement == "https://gitlab.com/foo/bar/-/archive/${PV}/bar-${PV}.tar.gz" assert uri in str(r) def test_gitlab_tar_bz2_uri(self): - uri = 'https://gitlab.com/foo/bar/repository/archive.tar.bz2?ref=${PV}' - fake_src = [ - f'SRC_URI="{uri} -> ${{P}}.tar.bz2"\n' - ] + uri = "https://gitlab.com/foo/bar/repository/archive.tar.bz2?ref=${PV}" + fake_src = [f'SRC_URI="{uri} -> ${{P}}.tar.bz2"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) r = self.assertReport(self.check_kls(None), fake_pkg) assert r.line == 1 assert r.uri == uri - assert (r.replacement == - 'https://gitlab.com/foo/bar/-/archive/${PV}/bar-${PV}.tar.bz2') + assert r.replacement == "https://gitlab.com/foo/bar/-/archive/${PV}/bar-${PV}.tar.bz2" assert uri in str(r) def test_gitlab_zip_uri(self): - uri = 'https://gitlab.com/foo/bar/repository/archive.zip?ref=${PV}' - fake_src = [ - f'SRC_URI="{uri} -> ${{P}}.zip"\n' - ] + uri = "https://gitlab.com/foo/bar/repository/archive.zip?ref=${PV}" + fake_src = [f'SRC_URI="{uri} -> ${{P}}.zip"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) r = self.assertReport(self.check_kls(None), fake_pkg) assert r.line == 1 assert r.uri == uri - assert (r.replacement == - 'https://gitlab.com/foo/bar/-/archive/${PV}/bar-${PV}.zip') + assert r.replacement == "https://gitlab.com/foo/bar/-/archive/${PV}/bar-${PV}.zip" assert uri in str(r) @@ -320,15 +304,13 @@ class TestBetterCompression(misc.ReportTestCase): check_kls = codingstyle.BetterCompressionCheck def test_github_archive_uri(self): - uri = 'https://github.com/foo/bar/archive/${PV}.tar.gz' - fake_src = [ - f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n' - ] + uri = "https://github.com/foo/bar/archive/${PV}.tar.gz" + fake_src = [f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) self.assertNoReport(self.check_kls(None), fake_pkg) def test_comment_uri(self): - uri = 'https://gitlab.com/GNOME/${PN}/-/archive/${PV}/${P}.tar' + uri = "https://gitlab.com/GNOME/${PN}/-/archive/${PV}/${P}.tar" fake_src = [ f'#SRC_URI="{uri} -> ${{P}}.tar.gz"\n', " ", @@ -339,21 +321,22 @@ class TestBetterCompression(misc.ReportTestCase): r = self.assertReport(self.check_kls(None), fake_pkg) assert r.lineno == 4 - @pytest.mark.parametrize('uri', ( - 'https://gitlab.com/GNOME/${PN}/-/archive/${PV}/${P}.tar', - 'https://gitlab.gnome.org/GNOME/${PN}/-/archive/${PV}/${P}.tar.gz', - 'https://gitlab.gnome.org/GNOME/${PN}/-/archive/${PV}/${P}.zip', - 'https://gitlab.freedesktop.org/glvnd/${PN}/-/archive/v${PV}/${PN}-v${PV}.tar.gz', - )) + @pytest.mark.parametrize( + "uri", + ( + "https://gitlab.com/GNOME/${PN}/-/archive/${PV}/${P}.tar", + "https://gitlab.gnome.org/GNOME/${PN}/-/archive/${PV}/${P}.tar.gz", + "https://gitlab.gnome.org/GNOME/${PN}/-/archive/${PV}/${P}.zip", + "https://gitlab.freedesktop.org/glvnd/${PN}/-/archive/v${PV}/${PN}-v${PV}.tar.gz", + ), + ) def test_gitlab_archive_uri(self, uri): - fake_src = [ - f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n' - ] + fake_src = [f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n'] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) r = self.assertReport(self.check_kls(None), fake_pkg) assert r.lineno == 1 assert r.line == uri - assert r.replacement == '.tar.bz2' + assert r.replacement == ".tar.bz2" assert uri in str(r) @@ -363,76 +346,85 @@ class TestStaticSrcUri(misc.ReportTestCase): check = check_kls(None) @staticmethod - def _prepare_pkg(uri_value: str, rename: str = '', pkgver: str = 'diffball-0.1.2.3'): + def _prepare_pkg(uri_value: str, rename: str = "", pkgver: str = "diffball-0.1.2.3"): if rename: - rename = f' -> {rename}' - uri = f'https://github.com/pkgcore/pkgcheck/archive/{uri_value}.tar.gz' - fake_src = [ - f'SRC_URI="{uri}{rename}"\n' - ] + rename = f" -> {rename}" + uri = f"https://github.com/pkgcore/pkgcheck/archive/{uri_value}.tar.gz" + fake_src = [f'SRC_URI="{uri}{rename}"\n'] - fake_pkg = misc.FakePkg(f"dev-util/{pkgver}", ebuild=''.join(fake_src), lines=fake_src) - data = ''.join(fake_src).encode() + fake_pkg = misc.FakePkg(f"dev-util/{pkgver}", ebuild="".join(fake_src), lines=fake_src) + data = "".join(fake_src).encode() return _ParsedPkg(data, pkg=fake_pkg) - - @pytest.mark.parametrize('value', ( - '${P}', - '${PV}', - 'v${PV}', - 'random-0.1.2.3', # not a valid prefix - '1.2.3', # currently we support only ver_cut with start=1 - '0', # for ver_cut only if more then 1 part - )) + @pytest.mark.parametrize( + "value", + ( + "${P}", + "${PV}", + "v${PV}", + "random-0.1.2.3", # not a valid prefix + "1.2.3", # currently we support only ver_cut with start=1 + "0", # for ver_cut only if more then 1 part + ), + ) def test_no_report(self, value): self.assertNoReport(self.check, self._prepare_pkg(value)) - @pytest.mark.parametrize(('value', 'static_str', 'replacement'), ( - ('diffball-0.1.2.3', 'diffball-0.1.2.3', '${P}'), - ('Diffball-0.1.2.3', 'Diffball-0.1.2.3', '${P^}'), - ('DIFFBALL-0.1.2.3', 'DIFFBALL-0.1.2.3', '${P^^}'), - ('diffball-0123', 'diffball-0123', '${P//.}'), - ('Diffball-0123', 'Diffball-0123', '${P^//.}'), - ('0.1.2.3', '0.1.2.3', '${PV}'), - ('v0.1.2.3', '0.1.2.3', '${PV}'), - ('0.1.2', '0.1.2', '$(ver_cut 1-3)'), - ('0.1', '0.1', '$(ver_cut 1-2)'), - ('diffball-0.1.2', '0.1.2', '$(ver_cut 1-3)'), - ('v0123', '0123', "${PV//.}"), - ('012.3', '012.3', "$(ver_rs 1-2 '')"), - ('012.3', '012.3', "$(ver_rs 1-2 '')"), - ('0_1_2_3', '0_1_2_3', "${PV//./_}"), - ('0_1_2.3', '0_1_2.3', "$(ver_rs 1-2 '_')"), - ('0-1.2.3', '0-1.2.3', "$(ver_rs 1 '-')"), - )) + @pytest.mark.parametrize( + ("value", "static_str", "replacement"), + ( + ("diffball-0.1.2.3", "diffball-0.1.2.3", "${P}"), + ("Diffball-0.1.2.3", "Diffball-0.1.2.3", "${P^}"), + ("DIFFBALL-0.1.2.3", "DIFFBALL-0.1.2.3", "${P^^}"), + ("diffball-0123", "diffball-0123", "${P//.}"), + ("Diffball-0123", "Diffball-0123", "${P^//.}"), + ("0.1.2.3", "0.1.2.3", "${PV}"), + ("v0.1.2.3", "0.1.2.3", "${PV}"), + ("0.1.2", "0.1.2", "$(ver_cut 1-3)"), + ("0.1", "0.1", "$(ver_cut 1-2)"), + ("diffball-0.1.2", "0.1.2", "$(ver_cut 1-3)"), + ("v0123", "0123", "${PV//.}"), + ("012.3", "012.3", "$(ver_rs 1-2 '')"), + ("012.3", "012.3", "$(ver_rs 1-2 '')"), + ("0_1_2_3", "0_1_2_3", "${PV//./_}"), + ("0_1_2.3", "0_1_2.3", "$(ver_rs 1-2 '_')"), + ("0-1.2.3", "0-1.2.3", "$(ver_rs 1 '-')"), + ), + ) def test_with_report(self, value, static_str, replacement): r = self.assertReport(self.check, self._prepare_pkg(value)) assert r.static_str == static_str assert r.replacement == replacement def test_rename(self): - self.assertNoReport(self.check, self._prepare_pkg('${P}', '${P}.tar.gz')) + self.assertNoReport(self.check, self._prepare_pkg("${P}", "${P}.tar.gz")) - r = self.assertReport(self.check, self._prepare_pkg('${P}', 'diffball-0.1.2.3.tar.gz')) - assert r.static_str == 'diffball-0.1.2.3' - assert r.replacement == '${P}' + r = self.assertReport(self.check, self._prepare_pkg("${P}", "diffball-0.1.2.3.tar.gz")) + assert r.static_str == "diffball-0.1.2.3" + assert r.replacement == "${P}" - r = self.assertReport(self.check, self._prepare_pkg('0.1.2.3', '${P}.tar.gz')) - assert r.static_str == '0.1.2.3' - assert r.replacement == '${PV}' + r = self.assertReport(self.check, self._prepare_pkg("0.1.2.3", "${P}.tar.gz")) + assert r.static_str == "0.1.2.3" + assert r.replacement == "${PV}" - r = self.assertReport(self.check, self._prepare_pkg('diffball-0.1.2.3', 'diffball-0.1.2.3.tar.gz')) - assert r.static_str == 'diffball-0.1.2.3' - assert r.replacement == '${P}' + r = self.assertReport( + self.check, self._prepare_pkg("diffball-0.1.2.3", "diffball-0.1.2.3.tar.gz") + ) + assert r.static_str == "diffball-0.1.2.3" + assert r.replacement == "${P}" def test_capitalize(self): - r = self.assertReport(self.check, self._prepare_pkg('DIFFBALL-0.1.2.3', pkgver='DIFFBALL-0.1.2.3')) - assert r.static_str == 'DIFFBALL-0.1.2.3' - assert r.replacement == '${P}' + r = self.assertReport( + self.check, self._prepare_pkg("DIFFBALL-0.1.2.3", pkgver="DIFFBALL-0.1.2.3") + ) + assert r.static_str == "DIFFBALL-0.1.2.3" + assert r.replacement == "${P}" - r = self.assertReport(self.check, self._prepare_pkg('Diffball-0.1.2.3', pkgver='Diffball-0.1.2.3')) - assert r.static_str == 'Diffball-0.1.2.3' - assert r.replacement == '${P}' + r = self.assertReport( + self.check, self._prepare_pkg("Diffball-0.1.2.3", pkgver="Diffball-0.1.2.3") + ) + assert r.static_str == "Diffball-0.1.2.3" + assert r.replacement == "${P}" class TestExcessiveLineLength(misc.ReportTestCase): @@ -441,54 +433,68 @@ class TestExcessiveLineLength(misc.ReportTestCase): check = check_kls(None) word_length = codingstyle.ExcessiveLineLength.word_length - @staticmethod def _prepare_pkg(*lines: str): - fake_pkg = misc.FakePkg("dev-util/diffball-0", ebuild=''.join(lines), lines=lines) - data = ''.join(lines).encode() + fake_pkg = misc.FakePkg("dev-util/diffball-0", ebuild="".join(lines), lines=lines) + data = "".join(lines).encode() return _ParsedPkg(data, pkg=fake_pkg) def test_normal_length(self): self.assertNoReport(self.check, self._prepare_pkg('echo "short line"')) def test_long_line(self): - r = self.assertReport(self.check, self._prepare_pkg(f'echo {"a " * codingstyle.ExcessiveLineLength.line_length}')) - assert r.lines == (1, ) + r = self.assertReport( + self.check, + self._prepare_pkg(f'echo {"a " * codingstyle.ExcessiveLineLength.line_length}'), + ) + assert r.lines == (1,) def test_multiple_lines(self): - r = self.assertReport(self.check, self._prepare_pkg( - f'echo {"a " * codingstyle.ExcessiveLineLength.line_length}', - 'echo "short line"', - f'echo {"Hello " * codingstyle.ExcessiveLineLength.line_length}', - )) + r = self.assertReport( + self.check, + self._prepare_pkg( + f'echo {"a " * codingstyle.ExcessiveLineLength.line_length}', + 'echo "short line"', + f'echo {"Hello " * codingstyle.ExcessiveLineLength.line_length}', + ), + ) assert r.lines == (1, 3) - @pytest.mark.parametrize('variable', ('DESCRIPTION', 'KEYWORDS', 'IUSE')) + @pytest.mark.parametrize("variable", ("DESCRIPTION", "KEYWORDS", "IUSE")) def test_special_variables(self, variable): - self.assertNoReport(self.check, self._prepare_pkg( - f'{variable}="{"a " * codingstyle.ExcessiveLineLength.line_length}"', - f' {variable}="{"a " * codingstyle.ExcessiveLineLength.line_length}"', - f'\t\t{variable}="{"a " * codingstyle.ExcessiveLineLength.line_length}"', - )) + self.assertNoReport( + self.check, + self._prepare_pkg( + f'{variable}="{"a " * codingstyle.ExcessiveLineLength.line_length}"', + f' {variable}="{"a " * codingstyle.ExcessiveLineLength.line_length}"', + f'\t\t{variable}="{"a " * codingstyle.ExcessiveLineLength.line_length}"', + ), + ) def test_long_words(self): - long_word = 'a' * self.word_length + 'b' - medium_word = 'a' * (self.word_length // 2) - r = self.assertReport(self.check, self._prepare_pkg( - f'echo {"a" * codingstyle.ExcessiveLineLength.line_length}', - f'echo {medium_word} {long_word}', - f'echo {medium_word} {long_word[:-5]}', - )) - assert r.lines == (3, ) + long_word = "a" * self.word_length + "b" + medium_word = "a" * (self.word_length // 2) + r = self.assertReport( + self.check, + self._prepare_pkg( + f'echo {"a" * codingstyle.ExcessiveLineLength.line_length}', + f"echo {medium_word} {long_word}", + f"echo {medium_word} {long_word[:-5]}", + ), + ) + assert r.lines == (3,) def test_long_quotes(self): # The exception is for any quoted string with length >= word_length. # Each quoted string is computed by itself. - long_word = 'a ' * (self.word_length // 2) + 'b' # long quoted string, skipped - medium_word = 'a ' * (self.word_length // 4) # not long enough string, not skipped - r = self.assertReport(self.check, self._prepare_pkg( - f'echo "{"a" * codingstyle.ExcessiveLineLength.line_length}"', - f'echo "{medium_word}" "{long_word}"', - 'echo' + f' "{medium_word}"' * 3, - )) - assert r.lines == (3, ) + long_word = "a " * (self.word_length // 2) + "b" # long quoted string, skipped + medium_word = "a " * (self.word_length // 4) # not long enough string, not skipped + r = self.assertReport( + self.check, + self._prepare_pkg( + f'echo "{"a" * codingstyle.ExcessiveLineLength.line_length}"', + f'echo "{medium_word}" "{long_word}"', + "echo" + f' "{medium_word}"' * 3, + ), + ) + assert r.lines == (3,) diff --git a/tests/checks/test_dropped_keywords.py b/tests/checks/test_dropped_keywords.py index 6b070919..fbfee5fc 100644 --- a/tests/checks/test_dropped_keywords.py +++ b/tests/checks/test_dropped_keywords.py @@ -8,65 +8,62 @@ class TestDroppedKeywords(misc.ReportTestCase): check_kls = dropped_keywords.DroppedKeywordsCheck - def mk_pkg(self, ver, keywords='', eclasses=(), **kwargs): + def mk_pkg(self, ver, keywords="", eclasses=(), **kwargs): return misc.FakePkg( f"dev-util/diffball-{ver}", data={ **kwargs, "KEYWORDS": keywords, "_eclasses_": eclasses, - }) + }, + ) - def mk_check(self, arches=('x86', 'amd64'), verbosity=0): + def mk_check(self, arches=("x86", "amd64"), verbosity=0): options = arghparse.Namespace(arches=arches, verbosity=verbosity) return self.check_kls(options, arches_addon=None) def test_it(self): # single version, shouldn't yield. check = self.mk_check() - self.assertNoReport(check, [self.mk_pkg('1')]) + self.assertNoReport(check, [self.mk_pkg("1")]) # ebuilds without keywords are skipped - self.assertNoReport( - check, [self.mk_pkg("1", "x86 amd64"), self.mk_pkg("2")]) + self.assertNoReport(check, [self.mk_pkg("1", "x86 amd64"), self.mk_pkg("2")]) # ensure it limits itself to just the arches we care about # check unstable at the same time; # finally, check '-' handling; if x86 -> -x86, that's valid. self.assertNoReport( check, - [self.mk_pkg("1", "x86 ~amd64 ppc"), - self.mk_pkg("2", "~amd64 x86"), - self.mk_pkg("3", "-amd64 x86")]) + [ + self.mk_pkg("1", "x86 ~amd64 ppc"), + self.mk_pkg("2", "~amd64 x86"), + self.mk_pkg("3", "-amd64 x86"), + ], + ) # check added keyword handling self.assertNoReport( check, - [self.mk_pkg("1", "amd64"), - self.mk_pkg("2", "x86"), - self.mk_pkg("3", "~x86 ~amd64")]) + [self.mk_pkg("1", "amd64"), self.mk_pkg("2", "x86"), self.mk_pkg("3", "~x86 ~amd64")], + ) # check special keyword handling - for key in ('-*', '*', '~*'): - self.assertNoReport( - check, - [self.mk_pkg("1", "x86 ~amd64"), - self.mk_pkg("2", key)]) + for key in ("-*", "*", "~*"): + self.assertNoReport(check, [self.mk_pkg("1", "x86 ~amd64"), self.mk_pkg("2", key)]) # ensure it doesn't flag live ebuilds self.assertNoReport( - check, - [self.mk_pkg("1", "x86 amd64"), - self.mk_pkg("9999", "", PROPERTIES='live')]) + check, [self.mk_pkg("1", "x86 amd64"), self.mk_pkg("9999", "", PROPERTIES="live")] + ) def test_verbose_mode(self): # verbose mode outputs a report per version with dropped keywords check = self.mk_check(verbosity=1) reports = self.assertReports( check, - [self.mk_pkg("1", "amd64 x86"), - self.mk_pkg("2", "amd64"), - self.mk_pkg("3", "amd64")]) + [self.mk_pkg("1", "amd64 x86"), self.mk_pkg("2", "amd64"), self.mk_pkg("3", "amd64")], + ) assert len(reports) == 2 assert {x.version for x in reports} == {"2", "3"} assert set().union(*(x.arches for x in reports)) == {"x86"} @@ -76,9 +73,8 @@ class TestDroppedKeywords(misc.ReportTestCase): check = self.mk_check() reports = self.assertReports( check, - [self.mk_pkg("1", "x86 amd64"), - self.mk_pkg("2", "amd64"), - self.mk_pkg("3", "amd64")]) + [self.mk_pkg("1", "x86 amd64"), self.mk_pkg("2", "amd64"), self.mk_pkg("3", "amd64")], + ) assert len(reports) == 1 - assert reports[0].version == '3' + assert reports[0].version == "3" assert set().union(*(x.arches for x in reports)) == {"x86"} diff --git a/tests/checks/test_git.py b/tests/checks/test_git.py index 150d8b8b..1cefd549 100644 --- a/tests/checks/test_git.py +++ b/tests/checks/test_git.py @@ -21,11 +21,11 @@ class FakeCommit(GitCommit): def __init__(self, **kwargs): commit_data = { - 'hash': '7f9abd7ec2d079b1d0c36fc2f5d626ae0691757e', - 'commit_time': 1613438722, - 'author': 'author@domain.com', - 'committer': 'author@domain.com', - 'message': (), + "hash": "7f9abd7ec2d079b1d0c36fc2f5d626ae0691757e", + "commit_time": 1613438722, + "author": "author@domain.com", + "committer": "author@domain.com", + "message": (), } commit_data.update(kwargs) super().__init__(**commit_data) @@ -33,199 +33,217 @@ class FakeCommit(GitCommit): class TestGitCommitMessageCheck(ReportTestCase): check_kls = git_mod.GitCommitMessageCheck - options = arghparse.Namespace( - target_repo=FakeRepo(), commits='origin', gentoo_repo=True) + options = arghparse.Namespace(target_repo=FakeRepo(), commits="origin", gentoo_repo=True) check = git_mod.GitCommitMessageCheck(options) def test_sign_offs(self): # assert that it checks for both author and comitter r = self.assertReport( - self.check, - FakeCommit(author='user1', committer='user2', message=['blah']) + self.check, FakeCommit(author="user1", committer="user2", message=["blah"]) ) assert isinstance(r, git_mod.MissingSignOff) - assert r.missing_sign_offs == ('user1', 'user2') + assert r.missing_sign_offs == ("user1", "user2") # assert that it handles author/committer being the same self.assertNoReport( self.check, FakeCommit( - author='user@user.com', committer='user@user.com', - message=['summary', '', 'Signed-off-by: user@user.com'])) + author="user@user.com", + committer="user@user.com", + message=["summary", "", "Signed-off-by: user@user.com"], + ), + ) # assert it can handle multiple sign offs. self.assertNoReport( self.check, FakeCommit( - author='user1', committer='user2', - message=['summary', '', 'Signed-off-by: user2', 'Signed-off-by: user1'])) + author="user1", + committer="user2", + message=["summary", "", "Signed-off-by: user2", "Signed-off-by: user1"], + ), + ) - def SO_commit(self, summary='summary', body='', tags=(), **kwargs): + def SO_commit(self, summary="summary", body="", tags=(), **kwargs): """Create a commit object from summary, body, and tags components.""" - author = kwargs.pop('author', 'author@domain.com') - committer = kwargs.pop('committer', 'author@domain.com') + author = kwargs.pop("author", "author@domain.com") + committer = kwargs.pop("committer", "author@domain.com") message = summary if message: if body: - message += '\n\n' + body - sign_offs = tuple(f'Signed-off-by: {user}' for user in {author, committer}) - message += '\n\n' + '\n'.join(tuple(tags) + sign_offs) + message += "\n\n" + body + sign_offs = tuple(f"Signed-off-by: {user}" for user in {author, committer}) + message += "\n\n" + "\n".join(tuple(tags) + sign_offs) return FakeCommit(author=author, committer=committer, message=message.splitlines()) def test_invalid_commit_tag(self): # assert it doesn't puke if there are no tags self.assertNoReport(self.check, self.SO_commit()) - self.assertNoReport(self.check, self.SO_commit(tags=['Bug: https://gentoo.org/blah'])) - self.assertNoReport(self.check, self.SO_commit(tags=['Close: https://gentoo.org/blah'])) + self.assertNoReport(self.check, self.SO_commit(tags=["Bug: https://gentoo.org/blah"])) + self.assertNoReport(self.check, self.SO_commit(tags=["Close: https://gentoo.org/blah"])) - r = self.assertReport(self.check, self.SO_commit(tags=['Bug: 123455'])) + r = self.assertReport(self.check, self.SO_commit(tags=["Bug: 123455"])) assert isinstance(r, git_mod.InvalidCommitTag) - assert (r.tag, r.value, r.error) == ('Bug', '123455', "value isn't a URL") + assert (r.tag, r.value, r.error) == ("Bug", "123455", "value isn't a URL") # Do a protocol check; this is more of an assertion against the parsing model # used in the implementation. - r = self.assertReport(self.check, self.SO_commit(tags=['Closes: ftp://blah.com/asdf'])) + r = self.assertReport(self.check, self.SO_commit(tags=["Closes: ftp://blah.com/asdf"])) assert isinstance(r, git_mod.InvalidCommitTag) - assert r.tag == 'Closes' - assert 'protocol' in r.error + assert r.tag == "Closes" + assert "protocol" in r.error def test_gentoo_bug_tag(self): - commit = self.SO_commit(tags=['Gentoo-Bug: https://bugs.gentoo.org/1']) - assert 'Gentoo-Bug tag is no longer valid' in self.assertReport(self.check, commit).error + commit = self.SO_commit(tags=["Gentoo-Bug: https://bugs.gentoo.org/1"]) + assert "Gentoo-Bug tag is no longer valid" in self.assertReport(self.check, commit).error def test_commit_tags(self): - ref = 'd8337304f09' + ref = "d8337304f09" - for tag in ('Fixes', 'Reverts'): + for tag in ("Fixes", "Reverts"): # no results on `git cat-file` failure - with patch('pkgcheck.checks.git.subprocess.Popen') as git_cat: + with patch("pkgcheck.checks.git.subprocess.Popen") as git_cat: # force using a new `git cat-file` process for each iteration self.check._git_cat_file = None git_cat.return_value.poll.return_value = -1 - commit = self.SO_commit(tags=[f'{tag}: {ref}']) + commit = self.SO_commit(tags=[f"{tag}: {ref}"]) self.assertNoReport(self.check, commit) # missing and ambiguous object refs - for status in ('missing', 'ambiguous'): + for status in ("missing", "ambiguous"): self.check._git_cat_file = None - with patch('pkgcheck.checks.git.subprocess.Popen') as git_cat: + with patch("pkgcheck.checks.git.subprocess.Popen") as git_cat: git_cat.return_value.poll.return_value = None - git_cat.return_value.stdout.readline.return_value = f'{ref} {status}' - commit = self.SO_commit(tags=[f'{tag}: {ref}']) + git_cat.return_value.stdout.readline.return_value = f"{ref} {status}" + commit = self.SO_commit(tags=[f"{tag}: {ref}"]) r = self.assertReport(self.check, commit) assert isinstance(r, git_mod.InvalidCommitTag) - assert f'{status} commit' in r.error + assert f"{status} commit" in r.error # valid tag reference - with patch('pkgcheck.checks.git.subprocess.Popen') as git_cat: + with patch("pkgcheck.checks.git.subprocess.Popen") as git_cat: self.check._git_cat_file = None git_cat.return_value.poll.return_value = None - git_cat.return_value.stdout.readline.return_value = f'{ref} commit 1234' - commit = self.SO_commit(tags=[f'{tag}: {ref}']) + git_cat.return_value.stdout.readline.return_value = f"{ref} commit 1234" + commit = self.SO_commit(tags=[f"{tag}: {ref}"]) self.assertNoReport(self.check, commit) def test_summary_length(self): - self.assertNoReport(self.check, self.SO_commit('single summary headline')) - self.assertNoReport(self.check, self.SO_commit('a' * 69)) - assert 'no commit message' in \ - self.assertReport(self.check, self.SO_commit('')).error - assert 'summary is too long' in \ - self.assertReport(self.check, self.SO_commit('a' * 70)).error + self.assertNoReport(self.check, self.SO_commit("single summary headline")) + self.assertNoReport(self.check, self.SO_commit("a" * 69)) + assert "no commit message" in self.assertReport(self.check, self.SO_commit("")).error + assert ( + "summary is too long" in self.assertReport(self.check, self.SO_commit("a" * 70)).error + ) def test_message_body_length(self): # message body lines longer than 80 chars are flagged - long_line = 'a' + ' b' * 40 - assert 'line 2 greater than 80 chars' in \ - self.assertReport( - self.check, - self.SO_commit(body=long_line)).error + long_line = "a" + " b" * 40 + assert ( + "line 2 greater than 80 chars" + in self.assertReport(self.check, self.SO_commit(body=long_line)).error + ) # but not non-word lines - long_line = 'a' * 81 + long_line = "a" * 81 self.assertNoReport(self.check, self.SO_commit(body=long_line)) def test_message_empty_lines(self): - message = textwrap.dedent("""\ - foo + message = textwrap.dedent( + """\ + foo - bar + bar - Signed-off-by: author@domain.com - """).splitlines() + Signed-off-by: author@domain.com + """ + ).splitlines() commit = FakeCommit(message=message) self.assertNoReport(self.check, commit) # missing empty line between summary and body - message = textwrap.dedent("""\ - foo - bar + message = textwrap.dedent( + """\ + foo + bar - Signed-off-by: author@domain.com - """).splitlines() + Signed-off-by: author@domain.com + """ + ).splitlines() commit = FakeCommit(message=message) r = self.assertReport(self.check, commit) - assert 'missing empty line before body' in str(r) + assert "missing empty line before body" in str(r) # missing empty line between summary and tags - message = textwrap.dedent("""\ - foo - Signed-off-by: author@domain.com - """).splitlines() + message = textwrap.dedent( + """\ + foo + Signed-off-by: author@domain.com + """ + ).splitlines() commit = FakeCommit(message=message) r = self.assertReport(self.check, commit) - assert 'missing empty line before tags' in str(r) + assert "missing empty line before tags" in str(r) # missing empty lines between summary, body, and tags - message = textwrap.dedent("""\ - foo - bar - Signed-off-by: author@domain.com - """).splitlines() + message = textwrap.dedent( + """\ + foo + bar + Signed-off-by: author@domain.com + """ + ).splitlines() commit = FakeCommit(message=message) reports = self.assertReports(self.check, commit) - assert 'missing empty line before body' in str(reports[0]) - assert 'missing empty line before tags' in str(reports[1]) + assert "missing empty line before body" in str(reports[0]) + assert "missing empty line before tags" in str(reports[1]) def test_footer_empty_lines(self): - for whitespace in ('\t', ' ', ''): + for whitespace in ("\t", " ", ""): # empty lines in footer are flagged - message = textwrap.dedent(f"""\ - foon - - blah: dar - {whitespace} - footer: yep - Signed-off-by: author@domain.com - """).splitlines() + message = textwrap.dedent( + f"""\ + foon + + blah: dar + {whitespace} + footer: yep + Signed-off-by: author@domain.com + """ + ).splitlines() commit = FakeCommit(message=message) r = self.assertReport(self.check, commit) - assert 'empty line 4 in footer' in str(r) + assert "empty line 4 in footer" in str(r) # empty lines at the end of a commit message are ignored - message = textwrap.dedent(f"""\ + message = textwrap.dedent( + f"""\ + foon + + blah: dar + footer: yep + Signed-off-by: author@domain.com + {whitespace} + """ + ).splitlines() + commit = FakeCommit(message=message) + self.assertNoReport(self.check, commit) + + def test_footer_non_tags(self): + message = textwrap.dedent( + """\ foon blah: dar footer: yep + some random line Signed-off-by: author@domain.com - {whitespace} - """).splitlines() - commit = FakeCommit(message=message) - self.assertNoReport(self.check, commit) - - def test_footer_non_tags(self): - message = textwrap.dedent("""\ - foon - - blah: dar - footer: yep - some random line - Signed-off-by: author@domain.com - """).splitlines() + """ + ).splitlines() commit = FakeCommit(message=message) r = self.assertReport(self.check, commit) - assert 'non-tag in footer, line 5' in str(r) + assert "non-tag in footer, line 5" in str(r) class TestGitCommitMessageRepoCheck(ReportTestCase): @@ -239,18 +257,17 @@ class TestGitCommitMessageRepoCheck(ReportTestCase): # initialize parent repo self.parent_git_repo = make_git_repo() - self.parent_repo = make_repo( - self.parent_git_repo.path, repo_id='gentoo', arches=['amd64']) - self.parent_git_repo.add_all('initial commit') + self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo", arches=["amd64"]) + self.parent_git_repo.add_all("initial commit") # create a stub pkg and commit it - self.parent_repo.create_ebuild('cat/pkg-0') - self.parent_git_repo.add_all('cat/pkg-0') + self.parent_repo.create_ebuild("cat/pkg-0") + self.parent_git_repo.add_all("cat/pkg-0") # initialize child repo self.child_git_repo = make_git_repo() - self.child_git_repo.run(['git', 'remote', 'add', 'origin', self.parent_git_repo.path]) - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + self.child_git_repo.run(["git", "remote", "add", "origin", self.parent_git_repo.path]) + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.child_repo = make_repo(self.child_git_repo.path) def init_check(self, options=None, future=0): @@ -263,96 +280,106 @@ class TestGitCommitMessageRepoCheck(ReportTestCase): def _options(self, **kwargs): args = [ - 'scan', '-q', '--cache-dir', self.cache_dir, - '--repo', self.child_repo.location, '--commits', + "scan", + "-q", + "--cache-dir", + self.cache_dir, + "--repo", + self.child_repo.location, + "--commits", ] options, _ = self._tool.parse_args(args) return options def test_bad_commit_summary_pkg(self): # properly prefixed commit summary - self.child_repo.create_ebuild('cat/pkg-1') - self.child_git_repo.add_all('cat/pkg: version bump to 1', signoff=True) + self.child_repo.create_ebuild("cat/pkg-1") + self.child_git_repo.add_all("cat/pkg: version bump to 1", signoff=True) self.init_check() self.assertNoReport(self.check, self.source) # properly prefixed multiple ebuild commit summary - self.child_repo.create_ebuild('cat/pkg-2') - self.child_repo.create_ebuild('cat/pkg-3') - self.child_git_repo.add_all('cat/pkg: more version bumps', signoff=True) + self.child_repo.create_ebuild("cat/pkg-2") + self.child_repo.create_ebuild("cat/pkg-3") + self.child_git_repo.add_all("cat/pkg: more version bumps", signoff=True) self.init_check() self.assertNoReport(self.check, self.source) # special categories that allow not having version in new package summary - self.child_repo.create_ebuild('acct-user/pkgcheck-1') - self.child_git_repo.add_all('acct-user/pkgcheck: add user for pkgcheck', signoff=True) + self.child_repo.create_ebuild("acct-user/pkgcheck-1") + self.child_git_repo.add_all("acct-user/pkgcheck: add user for pkgcheck", signoff=True) self.init_check() self.assertNoReport(self.check, self.source) # special categories that allow not having version in bump version summary - self.child_repo.create_ebuild('acct-user/pkgcheck-2') - self.child_git_repo.add_all('acct-user/pkgcheck: bump user for pkgcheck', signoff=True) + self.child_repo.create_ebuild("acct-user/pkgcheck-2") + self.child_git_repo.add_all("acct-user/pkgcheck: bump user for pkgcheck", signoff=True) self.init_check() self.assertNoReport(self.check, self.source) # poorly prefixed commit summary - self.child_repo.create_ebuild('cat/pkg-4') - self.child_git_repo.add_all('version bump to 4', signoff=True) + self.child_repo.create_ebuild("cat/pkg-4") + self.child_git_repo.add_all("version bump to 4", signoff=True) commit1 = self.child_git_repo.HEAD # commit summary missing package version - self.child_repo.create_ebuild('cat/pkg-5') - self.child_git_repo.add_all('cat/pkg: version bump', signoff=True) + self.child_repo.create_ebuild("cat/pkg-5") + self.child_git_repo.add_all("cat/pkg: version bump", signoff=True) commit2 = self.child_git_repo.HEAD # commit summary missing renamed package version self.child_git_repo.move( - 'cat/pkg/pkg-3.ebuild', 'cat/pkg/pkg-6.ebuild', - msg='cat/pkg: version bump and remove old', signoff=True) + "cat/pkg/pkg-3.ebuild", + "cat/pkg/pkg-6.ebuild", + msg="cat/pkg: version bump and remove old", + signoff=True, + ) commit3 = self.child_git_repo.HEAD # revision bumps aren't flagged - self.child_repo.create_ebuild('cat/pkg-6-r1') - self.child_git_repo.add_all('cat/pkg: revision bump', signoff=True) + self.child_repo.create_ebuild("cat/pkg-6-r1") + self.child_git_repo.add_all("cat/pkg: revision bump", signoff=True) self.init_check() # allow vVERSION - self.child_repo.create_ebuild('cat/pkg-7') - self.child_git_repo.add_all('cat/pkg: bump to v7', signoff=True) + self.child_repo.create_ebuild("cat/pkg-7") + self.child_git_repo.add_all("cat/pkg: bump to v7", signoff=True) self.init_check() results = self.assertReports(self.check, self.source) r1 = git_mod.BadCommitSummary( - "summary missing 'cat/pkg' package prefix", - 'version bump to 4', commit=commit1) + "summary missing 'cat/pkg' package prefix", "version bump to 4", commit=commit1 + ) r2 = git_mod.BadCommitSummary( - "summary missing package version '5'", - 'cat/pkg: version bump', commit=commit2) + "summary missing package version '5'", "cat/pkg: version bump", commit=commit2 + ) r3 = git_mod.BadCommitSummary( "summary missing package version '6'", - 'cat/pkg: version bump and remove old', commit=commit3) + "cat/pkg: version bump and remove old", + commit=commit3, + ) assert set(results) == {r1, r2, r3} def test_bad_commit_summary_category(self): # properly prefixed commit summary - self.child_repo.create_ebuild('cat/pkg1-1') - self.child_repo.create_ebuild('cat/pkg2-1') - self.child_git_repo.add_all('cat: various pkg updates', signoff=True) + self.child_repo.create_ebuild("cat/pkg1-1") + self.child_repo.create_ebuild("cat/pkg2-1") + self.child_git_repo.add_all("cat: various pkg updates", signoff=True) self.init_check() self.assertNoReport(self.check, self.source) # multiple category commits are ignored - self.child_repo.create_ebuild('newcat1/newcat1-1') - self.child_repo.create_ebuild('newcat2/newpkg2-1') - self.child_git_repo.add_all('various changes', signoff=True) + self.child_repo.create_ebuild("newcat1/newcat1-1") + self.child_repo.create_ebuild("newcat2/newpkg2-1") + self.child_git_repo.add_all("various changes", signoff=True) self.init_check() self.assertNoReport(self.check, self.source) # poorly prefixed commit summary for single category changes - self.child_repo.create_ebuild('cat/pkg3-1') - self.child_repo.create_ebuild('cat/pkg4-1') - self.child_git_repo.add_all('cat updates', signoff=True) + self.child_repo.create_ebuild("cat/pkg3-1") + self.child_repo.create_ebuild("cat/pkg4-1") + self.child_git_repo.add_all("cat updates", signoff=True) commit = self.child_git_repo.HEAD self.init_check() r = self.assertReport(self.check, self.source) expected = git_mod.BadCommitSummary( - "summary missing 'cat' category prefix", - 'cat updates', commit=commit) + "summary missing 'cat' category prefix", "cat updates", commit=commit + ) assert r == expected @@ -367,18 +394,17 @@ class TestGitPkgCommitsCheck(ReportTestCase): # initialize parent repo self.parent_git_repo = make_git_repo() - self.parent_repo = make_repo( - self.parent_git_repo.path, repo_id='gentoo', arches=['amd64']) - self.parent_git_repo.add_all('initial commit') + self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo", arches=["amd64"]) + self.parent_git_repo.add_all("initial commit") # create a stub pkg and commit it - self.parent_repo.create_ebuild('cat/pkg-0') - self.parent_git_repo.add_all('cat/pkg-0') + self.parent_repo.create_ebuild("cat/pkg-0") + self.parent_git_repo.add_all("cat/pkg-0") # initialize child repo self.child_git_repo = make_git_repo() - self.child_git_repo.run(['git', 'remote', 'add', 'origin', self.parent_git_repo.path]) - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + self.child_git_repo.run(["git", "remote", "add", "origin", self.parent_git_repo.path]) + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.child_repo = make_repo(self.child_git_repo.path) def init_check(self, options=None, future=0): @@ -391,193 +417,206 @@ class TestGitPkgCommitsCheck(ReportTestCase): def _options(self, **kwargs): args = [ - 'scan', '-q', '--cache-dir', self.cache_dir, - '--repo', self.child_repo.location, '--commits', + "scan", + "-q", + "--cache-dir", + self.cache_dir, + "--repo", + self.child_repo.location, + "--commits", ] options, _ = self._tool.parse_args(args) return options def test_broken_ebuilds_ignored(self): - self.child_repo.create_ebuild('newcat/pkg-1', eapi='-1') - self.child_git_repo.add_all('newcat/pkg: initial import') + self.child_repo.create_ebuild("newcat/pkg-1", eapi="-1") + self.child_git_repo.add_all("newcat/pkg: initial import") self.init_check() self.assertNoReport(self.check, self.source) def test_direct_stable(self): - self.child_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.child_git_repo.add_all('cat/pkg: version bump to 1') + self.child_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.child_git_repo.add_all("cat/pkg: version bump to 1") self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.DirectStableKeywords(['amd64'], pkg=CPV('cat/pkg-1')) + expected = git_mod.DirectStableKeywords(["amd64"], pkg=CPV("cat/pkg-1")) assert r == expected def test_direct_no_maintainer(self): - self.child_repo.create_ebuild('newcat/pkg-1') - self.child_git_repo.add_all('newcat/pkg: initial import') + self.child_repo.create_ebuild("newcat/pkg-1") + self.child_git_repo.add_all("newcat/pkg: initial import") self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.DirectNoMaintainer(pkg=CPV('newcat/pkg-1')) + expected = git_mod.DirectNoMaintainer(pkg=CPV("newcat/pkg-1")) assert r == expected def test_ebuild_incorrect_copyright(self): - self.child_repo.create_ebuild('cat/pkg-1') - line = '# Copyright 1999-2019 Gentoo Authors' - with open(pjoin(self.child_git_repo.path, 'cat/pkg/pkg-1.ebuild'), 'r+') as f: + self.child_repo.create_ebuild("cat/pkg-1") + line = "# Copyright 1999-2019 Gentoo Authors" + with open(pjoin(self.child_git_repo.path, "cat/pkg/pkg-1.ebuild"), "r+") as f: lines = f.read().splitlines() lines[0] = line f.seek(0) f.truncate() - f.write('\n'.join(lines)) - self.child_git_repo.add_all('cat/pkg: version bump to 1') + f.write("\n".join(lines)) + self.child_git_repo.add_all("cat/pkg: version bump to 1") self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.EbuildIncorrectCopyright('2019', line=line, pkg=CPV('cat/pkg-1')) + expected = git_mod.EbuildIncorrectCopyright("2019", line=line, pkg=CPV("cat/pkg-1")) assert r == expected def test_missing_copyright(self): """Ebuilds missing copyrights entirely are handled by EbuildHeaderCheck.""" - self.child_repo.create_ebuild('cat/pkg-1') - with open(pjoin(self.child_git_repo.path, 'cat/pkg/pkg-1.ebuild'), 'r+') as f: + self.child_repo.create_ebuild("cat/pkg-1") + with open(pjoin(self.child_git_repo.path, "cat/pkg/pkg-1.ebuild"), "r+") as f: lines = f.read().splitlines() f.seek(0) f.truncate() - f.write('\n'.join(lines[1:])) - self.child_git_repo.add_all('cat/pkg: update ebuild') + f.write("\n".join(lines[1:])) + self.child_git_repo.add_all("cat/pkg: update ebuild") self.init_check() self.assertNoReport(self.check, self.source) def test_dropped_stable_keywords(self): # add stable ebuild to parent repo - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.parent_git_repo.add_all('cat/pkg: version bump to 1') + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.parent_git_repo.add_all("cat/pkg: version bump to 1") # pull changes and remove it from the child repo - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.remove('cat/pkg/pkg-1.ebuild', msg='cat/pkg: remove 1') + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.remove("cat/pkg/pkg-1.ebuild", msg="cat/pkg: remove 1") commit = self.child_git_repo.HEAD self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.DroppedStableKeywords(['amd64'], commit, pkg=CPV('cat/pkg-1')) + expected = git_mod.DroppedStableKeywords(["amd64"], commit, pkg=CPV("cat/pkg-1")) assert r == expected # git archive failures error out - with patch('pkgcheck.checks.git.subprocess.Popen') as git_archive: + with patch("pkgcheck.checks.git.subprocess.Popen") as git_archive: git_archive.return_value.poll.return_value = -1 - with pytest.raises(PkgcheckUserException, match='failed populating archive repo'): + with pytest.raises(PkgcheckUserException, match="failed populating archive repo"): self.assertNoReport(self.check, self.source) def test_dropped_unstable_keywords(self): # add stable ebuild to parent repo - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg: version bump to 1') + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg: version bump to 1") # pull changes and remove it from the child repo - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.remove('cat/pkg/pkg-1.ebuild', msg='cat/pkg: remove 1') + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.remove("cat/pkg/pkg-1.ebuild", msg="cat/pkg: remove 1") commit = self.child_git_repo.HEAD self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.DroppedUnstableKeywords(['~amd64'], commit, pkg=CPV('cat/pkg-1')) + expected = git_mod.DroppedUnstableKeywords(["~amd64"], commit, pkg=CPV("cat/pkg-1")) assert r == expected def test_dropped_keywords_inherit_eclass(self): # add stable ebuild to parent repo - with open(pjoin(self.parent_git_repo.path, 'eclass/make.eclass'), 'w') as f: - f.write(':') - self.parent_git_repo.add_all('make.eclass: initial commit') - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['~amd64'], data="inherit make") - self.parent_git_repo.add_all('cat/pkg: version bump to 1') + with open(pjoin(self.parent_git_repo.path, "eclass/make.eclass"), "w") as f: + f.write(":") + self.parent_git_repo.add_all("make.eclass: initial commit") + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["~amd64"], data="inherit make") + self.parent_git_repo.add_all("cat/pkg: version bump to 1") # pull changes and remove it from the child repo - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.remove('cat/pkg/pkg-1.ebuild', msg='cat/pkg: remove 1') + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.remove("cat/pkg/pkg-1.ebuild", msg="cat/pkg: remove 1") commit = self.child_git_repo.HEAD self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.DroppedUnstableKeywords(['~amd64'], commit, pkg=CPV('cat/pkg-1')) + expected = git_mod.DroppedUnstableKeywords(["~amd64"], commit, pkg=CPV("cat/pkg-1")) assert r == expected def test_rdepend_change(self): # add pkgs to parent repo - self.parent_repo.create_ebuild('cat/dep1-0') - self.parent_git_repo.add_all('cat/dep1: initial import') - self.parent_repo.create_ebuild('cat/dep2-0') - self.parent_git_repo.add_all('cat/dep2: initial import') - self.parent_repo.create_ebuild('newcat/newpkg-1') - self.parent_git_repo.add_all('newcat/newpkg: initial import') - self.parent_repo.create_ebuild('newcat/newpkg-2', rdepend="cat/dep1 cat/dep2") - self.parent_git_repo.add_all('newcat/newpkg: version bump') + self.parent_repo.create_ebuild("cat/dep1-0") + self.parent_git_repo.add_all("cat/dep1: initial import") + self.parent_repo.create_ebuild("cat/dep2-0") + self.parent_git_repo.add_all("cat/dep2: initial import") + self.parent_repo.create_ebuild("newcat/newpkg-1") + self.parent_git_repo.add_all("newcat/newpkg: initial import") + self.parent_repo.create_ebuild("newcat/newpkg-2", rdepend="cat/dep1 cat/dep2") + self.parent_git_repo.add_all("newcat/newpkg: version bump") # pull changes to child repo - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.child_git_repo.run(["git", "pull", "origin", "main"]) # change pkg RDEPEND and commit - with open(pjoin(self.child_git_repo.path, 'cat/pkg/pkg-0.ebuild'), 'a') as f: + with open(pjoin(self.child_git_repo.path, "cat/pkg/pkg-0.ebuild"), "a") as f: f.write('RDEPEND="cat/dep1"\n') - self.child_git_repo.add_all('cat/pkg: update deps') + self.child_git_repo.add_all("cat/pkg: update deps") # change live pkg RDEPEND and commit - with open(pjoin(self.child_git_repo.path, 'newcat/newpkg/newpkg-1.ebuild'), 'a') as f: + with open(pjoin(self.child_git_repo.path, "newcat/newpkg/newpkg-1.ebuild"), "a") as f: f.write('RDEPEND="cat/dep1"\n') f.write('PROPERTIES="live"\n') - self.child_git_repo.add_all('newcat/newpkg: update deps') + self.child_git_repo.add_all("newcat/newpkg: update deps") # reorder pkg RDEPEND and commit - with open(pjoin(self.child_git_repo.path, 'newcat/newpkg/newpkg-2.ebuild'), 'a') as f: + with open(pjoin(self.child_git_repo.path, "newcat/newpkg/newpkg-2.ebuild"), "a") as f: f.write('RDEPEND="cat/dep2 cat/dep1"\n') - self.child_git_repo.add_all('newcat/newpkg: reorder deps') + self.child_git_repo.add_all("newcat/newpkg: reorder deps") self.init_check() r = self.assertReport(self.check, self.source) # only one result is expected since live ebuilds are ignored - expected = git_mod.RdependChange(pkg=CPV('cat/pkg-0')) + expected = git_mod.RdependChange(pkg=CPV("cat/pkg-0")) assert r == expected def test_missing_slotmove(self): # add new ebuild to parent repo - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg: version bump to 1') + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg: version bump to 1") # pull changes and modify its slot in the child repo - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_repo.create_ebuild('cat/pkg-1', keywords=['~amd64'], slot='1') - self.child_git_repo.add_all('cat/pkg: update SLOT to 1') + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_repo.create_ebuild("cat/pkg-1", keywords=["~amd64"], slot="1") + self.child_git_repo.add_all("cat/pkg: update SLOT to 1") self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.MissingSlotmove('0', '1', pkg=CPV('cat/pkg-1')) + expected = git_mod.MissingSlotmove("0", "1", pkg=CPV("cat/pkg-1")) assert r == expected # create slot move update and the result goes away - updates_dir = pjoin(self.child_git_repo.path, 'profiles', 'updates') + updates_dir = pjoin(self.child_git_repo.path, "profiles", "updates") os.makedirs(updates_dir, exist_ok=True) - with open(pjoin(updates_dir, '4Q-2020'), 'w') as f: - f.write(textwrap.dedent("""\ - slotmove ~cat/foo-0 0 1 - slotmove ~cat/pkg-1 0 1 - """)) + with open(pjoin(updates_dir, "4Q-2020"), "w") as f: + f.write( + textwrap.dedent( + """\ + slotmove ~cat/foo-0 0 1 + slotmove ~cat/pkg-1 0 1 + """ + ) + ) # force repo_config pkg updates jitted attr to be reset self.init_check() self.assertNoReport(self.check, self.source) # git archive failures error out - with patch('pkgcheck.checks.git.subprocess.Popen') as git_archive: + with patch("pkgcheck.checks.git.subprocess.Popen") as git_archive: git_archive.return_value.poll.return_value = -1 - with pytest.raises(PkgcheckUserException, match='failed populating archive repo'): + with pytest.raises(PkgcheckUserException, match="failed populating archive repo"): self.assertNoReport(self.check, self.source) def test_missing_move(self): # verify ebuild renames at the git level don't trigger - self.child_repo.create_ebuild('cat/pkg-1') - self.child_git_repo.run(['git', 'rm', 'cat/pkg/pkg-0.ebuild']) - self.child_git_repo.add_all('cat/pkg: version bump and remove old') + self.child_repo.create_ebuild("cat/pkg-1") + self.child_git_repo.run(["git", "rm", "cat/pkg/pkg-0.ebuild"]) + self.child_git_repo.add_all("cat/pkg: version bump and remove old") self.init_check() self.assertNoReport(self.check, self.source) - self.child_git_repo.move('cat', 'newcat', msg='newcat/pkg: moved pkg') + self.child_git_repo.move("cat", "newcat", msg="newcat/pkg: moved pkg") self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.MissingMove('cat/pkg', 'newcat/pkg', pkg=CPV('newcat/pkg-0')) + expected = git_mod.MissingMove("cat/pkg", "newcat/pkg", pkg=CPV("newcat/pkg-0")) assert r == expected # create package move update and the result goes away - updates_dir = pjoin(self.child_git_repo.path, 'profiles', 'updates') + updates_dir = pjoin(self.child_git_repo.path, "profiles", "updates") os.makedirs(updates_dir, exist_ok=True) - with open(pjoin(updates_dir, '4Q-2020'), 'w') as f: - f.write(textwrap.dedent("""\ - move cat/foo newcat/foo - move cat/pkg newcat/pkg - """)) + with open(pjoin(updates_dir, "4Q-2020"), "w") as f: + f.write( + textwrap.dedent( + """\ + move cat/foo newcat/foo + move cat/pkg newcat/pkg + """ + ) + ) # force repo_config pkg updates jitted attr to be reset self.init_check() self.assertNoReport(self.check, self.source) @@ -594,18 +633,17 @@ class TestGitEclassCommitsCheck(ReportTestCase): # initialize parent repo self.parent_git_repo = make_git_repo() - self.parent_repo = make_repo( - self.parent_git_repo.path, repo_id='gentoo', arches=['amd64']) - self.parent_git_repo.add_all('initial commit') + self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo", arches=["amd64"]) + self.parent_git_repo.add_all("initial commit") # create a stub eclass and commit it - touch(pjoin(self.parent_git_repo.path, 'eclass', 'foo.eclass')) - self.parent_git_repo.add_all('eclass: add foo eclass') + touch(pjoin(self.parent_git_repo.path, "eclass", "foo.eclass")) + self.parent_git_repo.add_all("eclass: add foo eclass") # initialize child repo self.child_git_repo = make_git_repo() - self.child_git_repo.run(['git', 'remote', 'add', 'origin', self.parent_git_repo.path]) - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + self.child_git_repo.run(["git", "remote", "add", "origin", self.parent_git_repo.path]) + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.child_repo = make_repo(self.child_git_repo.path) def init_check(self, options=None, future=0): @@ -618,35 +656,40 @@ class TestGitEclassCommitsCheck(ReportTestCase): def _options(self, **kwargs): args = [ - 'scan', '-q', '--cache-dir', self.cache_dir, - '--repo', self.child_repo.location, '--commits', + "scan", + "-q", + "--cache-dir", + self.cache_dir, + "--repo", + self.child_repo.location, + "--commits", ] options, _ = self._tool.parse_args(args) return options def test_eclass_incorrect_copyright(self): - line = '# Copyright 1999-2019 Gentoo Authors' - with open(pjoin(self.child_git_repo.path, 'eclass/foo.eclass'), 'w') as f: - f.write(f'{line}\n') - self.child_git_repo.add_all('eclass: update foo') + line = "# Copyright 1999-2019 Gentoo Authors" + with open(pjoin(self.child_git_repo.path, "eclass/foo.eclass"), "w") as f: + f.write(f"{line}\n") + self.child_git_repo.add_all("eclass: update foo") self.init_check() r = self.assertReport(self.check, self.source) - expected = git_mod.EclassIncorrectCopyright('2019', line, eclass='foo') + expected = git_mod.EclassIncorrectCopyright("2019", line, eclass="foo") assert r == expected # correcting the year results in no report year = datetime.today().year - line = f'# Copyright 1999-{year} Gentoo Authors' - with open(pjoin(self.child_git_repo.path, 'eclass/foo.eclass'), 'w') as f: - f.write(f'{line}\n') - self.child_git_repo.add_all('eclass: fix copyright year') + line = f"# Copyright 1999-{year} Gentoo Authors" + with open(pjoin(self.child_git_repo.path, "eclass/foo.eclass"), "w") as f: + f.write(f"{line}\n") + self.child_git_repo.add_all("eclass: fix copyright year") self.init_check() self.assertNoReport(self.check, self.source) def test_eclass_missing_copyright(self): """Eclasses missing copyrights entirely are handled by EclassHeaderCheck.""" - with open(pjoin(self.child_git_repo.path, 'eclass/foo.eclass'), 'w') as f: - f.write('# comment\n') - self.child_git_repo.add_all('eclass: update foo') + with open(pjoin(self.child_git_repo.path, "eclass/foo.eclass"), "w") as f: + f.write("# comment\n") + self.child_git_repo.add_all("eclass: update foo") self.init_check() self.assertNoReport(self.check, self.source) diff --git a/tests/checks/test_glsa.py b/tests/checks/test_glsa.py index c3182be1..bec35857 100644 --- a/tests/checks/test_glsa.py +++ b/tests/checks/test_glsa.py @@ -31,34 +31,34 @@ class TestVulnerabilitiesCheck(misc.ReportTestCase): def test_no_glsa_dir(self, tmp_path): # TODO: switch to using a repo fixture when available repo_dir = str(tmp_path) - os.makedirs(pjoin(repo_dir, 'profiles')) - os.makedirs(pjoin(repo_dir, 'metadata')) - with open(pjoin(repo_dir, 'profiles', 'repo_name'), 'w') as f: - f.write('fake\n') - with open(pjoin(repo_dir, 'metadata', 'layout.conf'), 'w') as f: - f.write('masters =\n') + os.makedirs(pjoin(repo_dir, "profiles")) + os.makedirs(pjoin(repo_dir, "metadata")) + with open(pjoin(repo_dir, "profiles", "repo_name"), "w") as f: + f.write("fake\n") + with open(pjoin(repo_dir, "metadata", "layout.conf"), "w") as f: + f.write("masters =\n") repo_config = repo_objs.RepoConfig(location=repo_dir) repo = repository.UnconfiguredTree(repo_config.location, repo_config=repo_config) options = arghparse.Namespace(glsa_dir=None, target_repo=repo, gentoo_repo=True) - with pytest.raises(SkipCheck, match='no available glsa source'): + with pytest.raises(SkipCheck, match="no available glsa source"): glsa.GlsaCheck(options) def test_repo_glsa_dir(self, tmp_path): # TODO: switch to using a repo fixture when available repo_dir = str(tmp_path) - os.makedirs(pjoin(repo_dir, 'profiles')) - os.makedirs(pjoin(repo_dir, 'metadata', 'glsa')) - with open(pjoin(repo_dir, 'profiles', 'repo_name'), 'w') as f: - f.write('fake\n') - with open(pjoin(repo_dir, 'metadata', 'layout.conf'), 'w') as f: - f.write('masters =\n') - with open(pjoin(repo_dir, 'metadata', 'glsa', 'glsa-202010-01.xml'), 'w') as f: + os.makedirs(pjoin(repo_dir, "profiles")) + os.makedirs(pjoin(repo_dir, "metadata", "glsa")) + with open(pjoin(repo_dir, "profiles", "repo_name"), "w") as f: + f.write("fake\n") + with open(pjoin(repo_dir, "metadata", "layout.conf"), "w") as f: + f.write("masters =\n") + with open(pjoin(repo_dir, "metadata", "glsa", "glsa-202010-01.xml"), "w") as f: f.write(mk_glsa(("dev-util/diffball", ([], ["~>=0.5-r3"])))) repo_config = repo_objs.RepoConfig(location=repo_dir) repo = repository.UnconfiguredTree(repo_config.location, repo_config=repo_config) options = arghparse.Namespace(glsa_dir=None, target_repo=repo, gentoo_repo=True) check = glsa.GlsaCheck(options) - assert 'dev-util/diffball' in check.vulns + assert "dev-util/diffball" in check.vulns def test_non_matching(self, check): self.assertNoReport(check, mk_pkg("0.5.1")) @@ -67,10 +67,8 @@ class TestVulnerabilitiesCheck(misc.ReportTestCase): def test_matching(self, check): r = self.assertReport(check, mk_pkg("0.5-r5")) assert isinstance(r, glsa.VulnerablePackage) - assert ( - (r.category, r.package, r.version) == - ("dev-util", "diffball", "0.5-r5")) - assert 'vulnerable via glsa(200611-02)' in str(r) + assert (r.category, r.package, r.version) == ("dev-util", "diffball", "0.5-r5") + assert "vulnerable via glsa(200611-02)" in str(r) # multiple glsa matches self.assertReports(check, mk_pkg("1.0")) diff --git a/tests/checks/test_header.py b/tests/checks/test_header.py index 492c3d8c..e79fdeb1 100644 --- a/tests/checks/test_header.py +++ b/tests/checks/test_header.py @@ -21,9 +21,9 @@ class TestEbuildHeaderCheck(misc.ReportTestCase): def test_good_copyright(self): good_copyrights = [ - '# Copyright 1999-2019 Gentoo Authors\n', - '# Copyright 2019 Gentoo Authors\n', - '# Copyright 2010-2017 Gentoo Authors\n', + "# Copyright 1999-2019 Gentoo Authors\n", + "# Copyright 2019 Gentoo Authors\n", + "# Copyright 2010-2017 Gentoo Authors\n", ] for line in good_copyrights: fake_src = [line, self.check_kls.license_header] @@ -32,11 +32,11 @@ class TestEbuildHeaderCheck(misc.ReportTestCase): def test_invalid_copyright(self): bad_copyrights = [ - '# Copyright (c) 1999-2019 Gentoo Authors\n', - '# Copyright Gentoo Authors\n', - '# Gentoo Authors\n', - '# Here is entirely random text\n', - '\n', + "# Copyright (c) 1999-2019 Gentoo Authors\n", + "# Copyright Gentoo Authors\n", + "# Gentoo Authors\n", + "# Here is entirely random text\n", + "\n", ] for line in bad_copyrights: fake_src = [line, self.check_kls.license_header] @@ -48,10 +48,10 @@ class TestEbuildHeaderCheck(misc.ReportTestCase): def test_new_foundation_copyright(self): """Foundation copyright on new ebuilds triggers the report.""" bad_copyrights = [ - '# Copyright 1999-2019 Gentoo Foundation\n', - '# Copyright 2019 Gentoo Foundation\n', - '# Copyright 3125 Gentoo Foundation\n', - '# Copyright 2010-2021 Gentoo Foundation\n', + "# Copyright 1999-2019 Gentoo Foundation\n", + "# Copyright 2019 Gentoo Foundation\n", + "# Copyright 3125 Gentoo Foundation\n", + "# Copyright 2010-2021 Gentoo Foundation\n", ] for line in bad_copyrights: fake_src = [line, self.check_kls.license_header] @@ -63,9 +63,9 @@ class TestEbuildHeaderCheck(misc.ReportTestCase): def test_old_foundation_copyright(self): """Foundation copyright on old ebuilds does not trigger false positives.""" good_copyrights = [ - '# Copyright 1999-2018 Gentoo Foundation\n', - '# Copyright 2016 Gentoo Foundation\n', - '# Copyright 2010-2017 Gentoo Foundation\n', + "# Copyright 1999-2018 Gentoo Foundation\n", + "# Copyright 2016 Gentoo Foundation\n", + "# Copyright 2010-2017 Gentoo Foundation\n", ] for line in good_copyrights: fake_src = [line, self.check_kls.license_header] @@ -75,8 +75,8 @@ class TestEbuildHeaderCheck(misc.ReportTestCase): def test_non_gentoo_authors_copyright_in_gentoo(self): """Ebuilds in the gentoo repo must use 'Gentoo Authors'.""" bad_copyrights = [ - '# Copyright 1999-2019 D. E. Veloper\n', - '# Copyright 2019 辣鸡汤\n', + "# Copyright 1999-2019 D. E. Veloper\n", + "# Copyright 2019 辣鸡汤\n", ] for line in bad_copyrights: fake_src = [line, self.check_kls.license_header] @@ -86,23 +86,23 @@ class TestEbuildHeaderCheck(misc.ReportTestCase): assert line.strip() in str(r) def test_license_headers(self): - copyright = '# Copyright 1999-2019 Gentoo Authors\n' + copyright = "# Copyright 1999-2019 Gentoo Authors\n" fake_src = [copyright, self.check_kls.license_header] fake_pkg = self.mk_pkg(lines=fake_src) self.assertNoReport(self.mk_check(), fake_pkg) bad_license_headers = [ [], - [''], - ['\n'], - [f'{self.check_kls.license_header} '], - [f' {self.check_kls.license_header}'], - ['# Distributed under the terms of the GNU General Public License v3'], + [""], + ["\n"], + [f"{self.check_kls.license_header} "], + [f" {self.check_kls.license_header}"], + ["# Distributed under the terms of the GNU General Public License v3"], ] for content in bad_license_headers: fake_src = [copyright] + content fake_pkg = self.mk_pkg(lines=fake_src) r = self.assertReport(self.mk_check(), fake_pkg) assert isinstance(r, header.EbuildInvalidLicenseHeader) - expected = content[0].strip() if content else 'missing license header' + expected = content[0].strip() if content else "missing license header" assert expected in str(r) diff --git a/tests/checks/test_imlate.py b/tests/checks/test_imlate.py index 3c0f44f8..624dc90a 100644 --- a/tests/checks/test_imlate.py +++ b/tests/checks/test_imlate.py @@ -4,21 +4,25 @@ from snakeoil.cli import arghparse from .. import misc -def mk_check(selected_arches=("x86", "ppc", "amd64"), arches=None, - stable_arches=None, source_arches=None): +def mk_check( + selected_arches=("x86", "ppc", "amd64"), arches=None, stable_arches=None, source_arches=None +): if arches is None: arches = selected_arches if stable_arches is None: stable_arches = selected_arches return imlate.ImlateCheck( arghparse.Namespace( - selected_arches=selected_arches, arches=arches, - stable_arches=stable_arches, source_arches=source_arches)) + selected_arches=selected_arches, + arches=arches, + stable_arches=stable_arches, + source_arches=source_arches, + ) + ) def mk_pkg(ver, keywords="", slot="0"): - return misc.FakePkg( - f"dev-util/diffball-{ver}", data={"SLOT": slot, "KEYWORDS": keywords}) + return misc.FakePkg(f"dev-util/diffball-{ver}", data={"SLOT": slot, "KEYWORDS": keywords}) class TestImlateCheck(misc.ReportTestCase): @@ -26,96 +30,82 @@ class TestImlateCheck(misc.ReportTestCase): check_kls = imlate.ImlateCheck def test_all_unstable(self): - self.assertNoReport( - mk_check(), - [mk_pkg(str(x), "~x86 ~amd64") for x in range(10)]) + self.assertNoReport(mk_check(), [mk_pkg(str(x), "~x86 ~amd64") for x in range(10)]) def test_all_stable(self): - self.assertNoReport( - mk_check(), - [mk_pkg("0.9", "amd64 x86")]) + self.assertNoReport(mk_check(), [mk_pkg("0.9", "amd64 x86")]) def test_unselected_arch(self): - self.assertNoReport( - mk_check(), - [mk_pkg("0.9", "~mips amd64")]) + self.assertNoReport(mk_check(), [mk_pkg("0.9", "~mips amd64")]) def test_specified_stable_arches(self): # pkg doesn't have any unstable arches we care about - self.assertNoReport( - mk_check(source_arches=('arm', 'arm64')), - [mk_pkg("0.9", "~x86 amd64")]) + self.assertNoReport(mk_check(source_arches=("arm", "arm64")), [mk_pkg("0.9", "~x86 amd64")]) # pkg doesn't have any stable arches we care about - self.assertNoReport( - mk_check(source_arches=('arm64',)), - [mk_pkg("0.9", "~x86 amd64")]) + self.assertNoReport(mk_check(source_arches=("arm64",)), [mk_pkg("0.9", "~x86 amd64")]) # only flag arches we care about r = self.assertReport( - mk_check(source_arches=('amd64',), selected_arches=('arm64',)), - [mk_pkg("0.9", "~arm64 ~x86 amd64")]) + mk_check(source_arches=("amd64",), selected_arches=("arm64",)), + [mk_pkg("0.9", "~arm64 ~x86 amd64")], + ) assert isinstance(r, imlate.PotentialStable) assert r.stable == ("amd64",) assert r.keywords == ("~arm64",) assert r.version == "0.9" def test_lagging_keyword(self): - r = self.assertReport( - mk_check(), - [mk_pkg("0.8", "x86 amd64"), - mk_pkg("0.9", "x86 ~amd64")]) + r = self.assertReport(mk_check(), [mk_pkg("0.8", "x86 amd64"), mk_pkg("0.9", "x86 ~amd64")]) assert isinstance(r, imlate.LaggingStable) assert r.stable == ("x86",) assert r.keywords == ("~amd64",) assert r.version == "0.9" - assert 'x86' in str(r) and '~amd64' in str(r) + assert "x86" in str(r) and "~amd64" in str(r) def test_potential_keyword(self): - r = self.assertReport( - mk_check(), - [mk_pkg("0.9", "~x86 amd64")]) + r = self.assertReport(mk_check(), [mk_pkg("0.9", "~x86 amd64")]) assert isinstance(r, imlate.PotentialStable) assert r.stable == ("amd64",) assert r.keywords == ("~x86",) assert r.version == "0.9" - assert 'amd64' in str(r) and '~x86' in str(r) + assert "amd64" in str(r) and "~x86" in str(r) def test_multiple_unstable_pkgs(self): r = self.assertReport( - mk_check(), - [mk_pkg("0.7", "~x86"), - mk_pkg("0.8", "~x86"), - mk_pkg("0.9", "~x86 amd64")]) + mk_check(), [mk_pkg("0.7", "~x86"), mk_pkg("0.8", "~x86"), mk_pkg("0.9", "~x86 amd64")] + ) assert r.stable == ("amd64",) assert r.keywords == ("~x86",) assert r.version == "0.9" def test_multiple_stable_arches(self): r = self.assertReport( - mk_check(), - [mk_pkg("0.7", "~x86 ~ppc"), - mk_pkg("0.9", "~x86 ppc amd64")]) + mk_check(), [mk_pkg("0.7", "~x86 ~ppc"), mk_pkg("0.9", "~x86 ppc amd64")] + ) assert r.stable == ("amd64", "ppc") assert r.keywords == ("~x86",) assert r.version == "0.9" def test_multiple_potential_arches(self): - r = self.assertReport( - mk_check(), - [mk_pkg("0.7", "~x86"), - mk_pkg("0.9", "~x86 ~ppc amd64")]) + r = self.assertReport(mk_check(), [mk_pkg("0.7", "~x86"), mk_pkg("0.9", "~x86 ~ppc amd64")]) assert r.stable == ("amd64",) - assert r.keywords == ("~ppc", "~x86",) + assert r.keywords == ( + "~ppc", + "~x86", + ) assert r.version == "0.9" def test_multiple_lagging_slots(self): r = self.assertReports( mk_check(), - [mk_pkg("0.7", slot="0", keywords="x86 ppc"), - mk_pkg("0.9", slot="0", keywords="~x86 ppc"), - mk_pkg("1.0", slot="1", keywords="x86 ppc"), - mk_pkg("1.2", slot="1", keywords="x86 ~ppc")]) + [ + mk_pkg("0.7", slot="0", keywords="x86 ppc"), + mk_pkg("0.9", slot="0", keywords="~x86 ppc"), + mk_pkg("1.0", slot="1", keywords="x86 ppc"), + mk_pkg("1.2", slot="1", keywords="x86 ~ppc"), + ], + ) assert len(r) == 2 assert isinstance(r[0], imlate.LaggingStable) assert r[0].slot == "0" @@ -131,8 +121,11 @@ class TestImlateCheck(misc.ReportTestCase): def test_multiple_potential_slots(self): r = self.assertReports( mk_check(), - [mk_pkg("0.9", slot="0", keywords="x86 ~ppc"), - mk_pkg("1.2", slot="1", keywords="x86 ~ppc")]) + [ + mk_pkg("0.9", slot="0", keywords="x86 ~ppc"), + mk_pkg("1.2", slot="1", keywords="x86 ~ppc"), + ], + ) assert len(r) == 2 assert isinstance(r[0], imlate.PotentialStable) assert r[0].slot == "0" @@ -146,15 +139,17 @@ class TestImlateCheck(misc.ReportTestCase): assert r[1].version == "1.2" def test_drop_newer_slot_stables(self): - selected_arches=("x86", "amd64") - all_arches=("x86", "amd64", "arm64") + selected_arches = ("x86", "amd64") + all_arches = ("x86", "amd64", "arm64") r = self.assertReport( mk_check(selected_arches=selected_arches, arches=all_arches), - [mk_pkg("0.7", "amd64 x86 ~arm64"), - mk_pkg("0.8", "amd64 ~x86 ~arm64"), - mk_pkg("0.9", "~amd64 ~x86 arm64")] + [ + mk_pkg("0.7", "amd64 x86 ~arm64"), + mk_pkg("0.8", "amd64 ~x86 ~arm64"), + mk_pkg("0.9", "~amd64 ~x86 arm64"), + ], ) assert isinstance(r, imlate.LaggingStable) - assert r.stable == ('amd64',) - assert r.keywords == ('~x86',) - assert r.version == '0.8' + assert r.stable == ("amd64",) + assert r.keywords == ("~x86",) + assert r.version == "0.8" diff --git a/tests/checks/test_metadata.py b/tests/checks/test_metadata.py index cc074d93..ee0ac08e 100644 --- a/tests/checks/test_metadata.py +++ b/tests/checks/test_metadata.py @@ -30,27 +30,24 @@ class TestDescriptionCheck(misc.ReportTestCase): self.assertNoReport(self.check, self.mk_pkg("a perfectly written package description")) def test_bad_descs(self): - for desc in ('based on eclass', - 'diffball', - 'dev-util/diffball', - 'foon'): + for desc in ("based on eclass", "diffball", "dev-util/diffball", "foon"): r = self.assertReport(self.check, self.mk_pkg(desc)) assert isinstance(r, metadata.BadDescription) def test_desc_length(self): r = self.assertReport(self.check, self.mk_pkg()) assert isinstance(r, metadata.BadDescription) - assert 'empty/unset' in str(r) + assert "empty/unset" in str(r) - self.assertNoReport(self.check, self.mk_pkg('s' * 80)) - r = self.assertReport(self.check, self.mk_pkg('s' * 81)) + self.assertNoReport(self.check, self.mk_pkg("s" * 80)) + r = self.assertReport(self.check, self.mk_pkg("s" * 81)) assert isinstance(r, metadata.BadDescription) - assert 'over 80 chars in length' in str(r) + assert "over 80 chars in length" in str(r) - self.assertNoReport(self.check, self.mk_pkg('s' * 10)) - r = self.assertReport(self.check, self.mk_pkg('s' * 9)) + self.assertNoReport(self.check, self.mk_pkg("s" * 10)) + r = self.assertReport(self.check, self.mk_pkg("s" * 9)) assert isinstance(r, metadata.BadDescription) - assert 'under 10 chars in length' in str(r) + assert "under 10 chars in length" in str(r) class TestHomepageCheck(misc.ReportTestCase): @@ -58,7 +55,7 @@ class TestHomepageCheck(misc.ReportTestCase): check_kls = metadata.HomepageCheck check = metadata.HomepageCheck(None) - def mk_pkg(self, homepage='', cpvstr='dev-util/diffball-0.7.1'): + def mk_pkg(self, homepage="", cpvstr="dev-util/diffball-0.7.1"): return misc.FakePkg(cpvstr, data={"HOMEPAGE": homepage}) def test_regular(self): @@ -72,26 +69,26 @@ class TestHomepageCheck(misc.ReportTestCase): def test_unset(self): r = self.assertReport(self.check, self.mk_pkg()) isinstance(r, metadata.BadHomepage) - assert 'empty/unset' in str(r) + assert "empty/unset" in str(r) # categories of pkgs allowed to skip HOMEPAGE for cat in self.check_kls.missing_categories: - self.assertNoReport(self.check, self.mk_pkg(cpvstr=f'{cat}/foo-0')) + self.assertNoReport(self.check, self.mk_pkg(cpvstr=f"{cat}/foo-0")) def test_no_protocol(self): - r = self.assertReport(self.check, self.mk_pkg('foobar.com')) + r = self.assertReport(self.check, self.mk_pkg("foobar.com")) isinstance(r, metadata.BadHomepage) - assert 'lacks protocol' in str(r) + assert "lacks protocol" in str(r) def test_unsupported_protocol(self): - r = self.assertReport(self.check, self.mk_pkg('htp://foobar.com')) + r = self.assertReport(self.check, self.mk_pkg("htp://foobar.com")) isinstance(r, metadata.BadHomepage) assert "uses unsupported protocol 'htp'" in str(r) def test_unspecific_site(self): - for suffix in ('', '/'): - for site in ('https://www.gentoo.org', 'https://gentoo.org'): - r = self.assertReport(self.check, self.mk_pkg(f'{site}{suffix}')) + for suffix in ("", "/"): + for site in ("https://www.gentoo.org", "https://gentoo.org"): + r = self.assertReport(self.check, self.mk_pkg(f"{site}{suffix}")) isinstance(r, metadata.BadHomepage) assert "unspecific HOMEPAGE" in str(r) @@ -104,27 +101,30 @@ class TestHomepageCheck(misc.ReportTestCase): class IUSE_Options(misc.Tmpdir): - def get_options(self, properties=(), restrict=(), **kwargs): repo_base = tempfile.mkdtemp(dir=self.dir) - base = pjoin(repo_base, 'profiles') + base = pjoin(repo_base, "profiles") os.mkdir(base) - with open(pjoin(base, "arch.list"), 'w') as file: + with open(pjoin(base, "arch.list"), "w") as file: file.write("\n".join(kwargs.pop("arches", ("x86", "ppc", "amd64", "amd64-fbsd")))) with open(pjoin(base, "use.desc"), "w") as file: file.write("\n".join(f"{x} - {x}" for x in kwargs.pop("use_desc", ("foo", "bar")))) - with open(pjoin(base, 'repo_name'), 'w') as file: - file.write(kwargs.pop('repo_name', 'monkeys')) - os.mkdir(pjoin(repo_base, 'metadata')) - with open(pjoin(repo_base, 'metadata', 'layout.conf'), 'w') as f: - f.write(textwrap.dedent(f"""\ - masters = - properties-allowed = {' '.join(properties)} - restrict-allowed = {' '.join(restrict)} - """)) - kwargs['target_repo'] = repository.UnconfiguredTree(repo_base) - kwargs.setdefault('verbosity', 0) - kwargs.setdefault('cache', {'git': False}) + with open(pjoin(base, "repo_name"), "w") as file: + file.write(kwargs.pop("repo_name", "monkeys")) + os.mkdir(pjoin(repo_base, "metadata")) + with open(pjoin(repo_base, "metadata", "layout.conf"), "w") as f: + f.write( + textwrap.dedent( + f"""\ + masters = + properties-allowed = {' '.join(properties)} + restrict-allowed = {' '.join(restrict)} + """ + ) + ) + kwargs["target_repo"] = repository.UnconfiguredTree(repo_base) + kwargs.setdefault("verbosity", 0) + kwargs.setdefault("cache", {"git": False}) return arghparse.Namespace(**kwargs) @@ -135,21 +135,21 @@ class TestKeywordsCheck(IUSE_Options, misc.ReportTestCase): @pytest.fixture def check(self): pkgs = ( - FakePkg('dev-libs/foo-0', keywords=('amd64', '~x86')), - FakePkg('dev-libs/foo-1', keywords=('-*', 'ppc')), - FakePkg('dev-libs/bar-2', keywords=()), + FakePkg("dev-libs/foo-0", keywords=("amd64", "~x86")), + FakePkg("dev-libs/foo-1", keywords=("-*", "ppc")), + FakePkg("dev-libs/bar-2", keywords=()), ) search_repo = FakeRepo(pkgs=pkgs) options = self.get_options(search_repo=search_repo, gentoo_repo=False) kwargs = { - 'use_addon': addons.UseAddon(options), - 'keywords_addon': addons.KeywordsAddon(options), + "use_addon": addons.UseAddon(options), + "keywords_addon": addons.KeywordsAddon(options), } return metadata.KeywordsCheck(options, **kwargs) - def mk_pkg(self, keywords='', cpv='dev-util/diffball-0.7.1', rdepend=''): - return misc.FakePkg(cpv, data={'KEYWORDS': keywords, 'RDEPEND': rdepend}) + def mk_pkg(self, keywords="", cpv="dev-util/diffball-0.7.1", rdepend=""): + return misc.FakePkg(cpv, data={"KEYWORDS": keywords, "RDEPEND": rdepend}) def test_no_keywords(self, check): self.assertNoReport(check, self.mk_pkg()) @@ -173,23 +173,23 @@ class TestKeywordsCheck(IUSE_Options, misc.ReportTestCase): # unknown keyword r = self.assertReport(check, self.mk_pkg("foo")) assert isinstance(r, metadata.UnknownKeywords) - assert r.keywords == ('foo',) + assert r.keywords == ("foo",) assert "unknown KEYWORDS: 'foo'" in str(r) # check that * and ~* are flagged in gentoo repo - options = self.get_options(repo_name='gentoo', gentoo_repo=True) + options = self.get_options(repo_name="gentoo", gentoo_repo=True) kwargs = { - 'use_addon': addons.UseAddon(options), - 'keywords_addon': addons.KeywordsAddon(options), + "use_addon": addons.UseAddon(options), + "keywords_addon": addons.KeywordsAddon(options), } check = metadata.KeywordsCheck(options, **kwargs) r = self.assertReport(check, self.mk_pkg("*")) assert isinstance(r, metadata.UnknownKeywords) - assert r.keywords == ('*',) + assert r.keywords == ("*",) assert "unknown KEYWORDS: '*'" in str(r) r = self.assertReport(check, self.mk_pkg("~*")) assert isinstance(r, metadata.UnknownKeywords) - assert r.keywords == ('~*',) + assert r.keywords == ("~*",) assert "unknown KEYWORDS: '~*'" in str(r) def test_overlapping_keywords(self, check): @@ -214,78 +214,78 @@ class TestKeywordsCheck(IUSE_Options, misc.ReportTestCase): # single duplicate r = self.assertReport(check, self.mk_pkg("amd64 amd64")) assert isinstance(r, metadata.DuplicateKeywords) - assert r.keywords == ('amd64',) - assert 'duplicate KEYWORDS: amd64' in str(r) + assert r.keywords == ("amd64",) + assert "duplicate KEYWORDS: amd64" in str(r) # multiple duplicates r = self.assertReport(check, self.mk_pkg("-* -* amd64 amd64 ~x86 ~x86")) assert isinstance(r, metadata.DuplicateKeywords) - assert r.keywords == ('-*', 'amd64', '~x86') + assert r.keywords == ("-*", "amd64", "~x86") def test_unsorted_keywords(self, check): # regular keywords - self.assertNoReport(check, self.mk_pkg('-* ~amd64')) + self.assertNoReport(check, self.mk_pkg("-* ~amd64")) # prefix keywords come after regular keywords - self.assertNoReport(check, self.mk_pkg('~amd64 ppc ~x86 ~amd64-fbsd')) + self.assertNoReport(check, self.mk_pkg("~amd64 ppc ~x86 ~amd64-fbsd")) # non-verbose mode doesn't show sorted keywords - r = self.assertReport(check, self.mk_pkg('~amd64 -*')) + r = self.assertReport(check, self.mk_pkg("~amd64 -*")) assert isinstance(r, metadata.UnsortedKeywords) - assert r.keywords == ('~amd64', '-*') + assert r.keywords == ("~amd64", "-*") assert r.sorted_keywords == () - assert 'unsorted KEYWORDS: ~amd64, -*' in str(r) + assert "unsorted KEYWORDS: ~amd64, -*" in str(r) # create a check instance with verbose mode enabled options = self.get_options(gentoo_repo=False, verbosity=1) kwargs = { - 'use_addon': addons.UseAddon(options), - 'keywords_addon': addons.KeywordsAddon(options), + "use_addon": addons.UseAddon(options), + "keywords_addon": addons.KeywordsAddon(options), } check = metadata.KeywordsCheck(options, **kwargs) # masks should come before regular keywords - r = self.assertReport(check, self.mk_pkg('~amd64 -*')) + r = self.assertReport(check, self.mk_pkg("~amd64 -*")) assert isinstance(r, metadata.UnsortedKeywords) - assert r.keywords == ('~amd64', '-*') - assert r.sorted_keywords == ('-*', '~amd64') - assert '\n\tunsorted KEYWORDS: ~amd64, -*\n\tsorted KEYWORDS: -*, ~amd64' in str(r) + assert r.keywords == ("~amd64", "-*") + assert r.sorted_keywords == ("-*", "~amd64") + assert "\n\tunsorted KEYWORDS: ~amd64, -*\n\tsorted KEYWORDS: -*, ~amd64" in str(r) # keywords should be sorted alphabetically by arch - r = self.assertReport(check, self.mk_pkg('ppc ~amd64')) + r = self.assertReport(check, self.mk_pkg("ppc ~amd64")) assert isinstance(r, metadata.UnsortedKeywords) - assert r.keywords == ('ppc', '~amd64') - assert r.sorted_keywords == ('~amd64', 'ppc') - assert '\n\tunsorted KEYWORDS: ppc, ~amd64\n\tsorted KEYWORDS: ~amd64, ppc' in str(r) + assert r.keywords == ("ppc", "~amd64") + assert r.sorted_keywords == ("~amd64", "ppc") + assert "\n\tunsorted KEYWORDS: ppc, ~amd64\n\tsorted KEYWORDS: ~amd64, ppc" in str(r) # prefix keywords should come after regular keywords - r = self.assertReport(check, self.mk_pkg('~amd64 ~amd64-fbsd ppc ~x86')) + r = self.assertReport(check, self.mk_pkg("~amd64 ~amd64-fbsd ppc ~x86")) assert isinstance(r, metadata.UnsortedKeywords) - assert r.keywords == ('~amd64', '~amd64-fbsd', 'ppc', '~x86') - assert r.sorted_keywords == ('~amd64', 'ppc', '~x86', '~amd64-fbsd') + assert r.keywords == ("~amd64", "~amd64-fbsd", "ppc", "~x86") + assert r.sorted_keywords == ("~amd64", "ppc", "~x86", "~amd64-fbsd") def test_missing_virtual_keywords(self, check): # non-virtuals don't trigger - pkg = self.mk_pkg(cpv='dev-util/foo-0', rdepend='=dev-libs/foo-0') + pkg = self.mk_pkg(cpv="dev-util/foo-0", rdepend="=dev-libs/foo-0") self.assertNoReport(check, pkg) # matching pkg with no keywords - pkg = self.mk_pkg(cpv='virtual/foo-0', rdepend='dev-libs/bar') + pkg = self.mk_pkg(cpv="virtual/foo-0", rdepend="dev-libs/bar") self.assertNoReport(check, pkg) # single pkg match - pkg = self.mk_pkg(cpv='virtual/foo-0', rdepend='=dev-libs/foo-0') + pkg = self.mk_pkg(cpv="virtual/foo-0", rdepend="=dev-libs/foo-0") r = self.assertReport(check, pkg) assert isinstance(r, metadata.VirtualKeywordsUpdate) - assert r.keywords == ('amd64', '~x86') - assert 'KEYWORDS updates available: amd64, ~x86' in str(r) + assert r.keywords == ("amd64", "~x86") + assert "KEYWORDS updates available: amd64, ~x86" in str(r) # multiple pkg match - pkg = self.mk_pkg(cpv='virtual/foo-0', rdepend='dev-libs/foo') + pkg = self.mk_pkg(cpv="virtual/foo-0", rdepend="dev-libs/foo") r = self.assertReport(check, pkg) assert isinstance(r, metadata.VirtualKeywordsUpdate) - assert r.keywords == ('amd64', 'ppc', '~x86') - assert 'KEYWORDS updates available: amd64, ppc, ~x86' in str(r) + assert r.keywords == ("amd64", "ppc", "~x86") + assert "KEYWORDS updates available: amd64, ppc, ~x86" in str(r) class TestIuseCheck(IUSE_Options, misc.ReportTestCase): @@ -298,28 +298,28 @@ class TestIuseCheck(IUSE_Options, misc.ReportTestCase): use_addon = addons.UseAddon(options) return self.check_kls(options, use_addon=use_addon) - def mk_pkg(self, iuse=''): - return misc.FakePkg('dev-util/diffball-0.7.1', data={'IUSE': iuse, 'EAPI': '1'}) + def mk_pkg(self, iuse=""): + return misc.FakePkg("dev-util/diffball-0.7.1", data={"IUSE": iuse, "EAPI": "1"}) def test_known_iuse(self, check): - self.assertNoReport(check, self.mk_pkg('foo bar')) + self.assertNoReport(check, self.mk_pkg("foo bar")) def test_unknown_iuse(self, check): - r = self.assertReport(check, self.mk_pkg('foo dar')) + r = self.assertReport(check, self.mk_pkg("foo dar")) assert isinstance(r, metadata.UnknownUseFlags) - assert r.flags == ('dar',) - assert 'dar' in str(r) + assert r.flags == ("dar",) + assert "dar" in str(r) def test_arch_iuse(self, check): # arch flags must _not_ be in IUSE - r = self.assertReport(check, self.mk_pkg('x86')) + r = self.assertReport(check, self.mk_pkg("x86")) assert isinstance(r, metadata.UnknownUseFlags) - assert r.flags == ('x86',) - assert 'x86' in str(r) + assert r.flags == ("x86",) + assert "x86" in str(r) def test_invalid_iuse(self, check): - for flag in ('+', '-', '@', '_'): - r = self.assertReport(check, self.mk_pkg(f'foo {flag}')) + for flag in ("+", "-", "@", "_"): + r = self.assertReport(check, self.mk_pkg(f"foo {flag}")) assert isinstance(r, metadata.InvalidUseFlags) assert r.flags == (flag,) assert flag in str(r) @@ -331,12 +331,12 @@ class TestEapiCheck(misc.ReportTestCase, misc.Tmpdir): def mk_check(self, deprecated=(), banned=()): # TODO: switch to using a repo fixture when available - os.makedirs(pjoin(self.dir, 'profiles')) - os.makedirs(pjoin(self.dir, 'metadata')) - with open(pjoin(self.dir, 'profiles', 'repo_name'), 'w') as f: - f.write('fake\n') - with open(pjoin(self.dir, 'metadata', 'layout.conf'), 'w') as f: - f.write('masters =\n') + os.makedirs(pjoin(self.dir, "profiles")) + os.makedirs(pjoin(self.dir, "metadata")) + with open(pjoin(self.dir, "profiles", "repo_name"), "w") as f: + f.write("fake\n") + with open(pjoin(self.dir, "metadata", "layout.conf"), "w") as f: + f.write("masters =\n") f.write(f"eapis-deprecated = {' '.join(deprecated)}\n") f.write(f"eapis-banned = {' '.join(banned)}\n") repo_config = repo_objs.RepoConfig(location=self.dir) @@ -345,7 +345,7 @@ class TestEapiCheck(misc.ReportTestCase, misc.Tmpdir): return self.check_kls(options, eclass_addon=addons.eclass.EclassAddon(options)) def mk_pkg(self, eapi): - return misc.FakePkg('dev-util/diffball-2.7.1', data={'EAPI': eapi}) + return misc.FakePkg("dev-util/diffball-2.7.1", data={"EAPI": eapi}) def test_repo_with_no_settings(self): check = self.mk_check() @@ -353,29 +353,35 @@ class TestEapiCheck(misc.ReportTestCase, misc.Tmpdir): self.assertNoReport(check, self.mk_pkg(eapi=eapi_str)) def test_latest_eapi(self): - check = self.mk_check(deprecated=('0', '2', '4', '5'), banned=('1', '3',)) + check = self.mk_check( + deprecated=("0", "2", "4", "5"), + banned=( + "1", + "3", + ), + ) latest_eapi = list(eapi.EAPI.known_eapis)[-1] self.assertNoReport(check, self.mk_pkg(eapi=latest_eapi)) def test_deprecated_eapi(self): - deprecated = ('0', '2', '4', '5') - banned = ('1', '3') + deprecated = ("0", "2", "4", "5") + banned = ("1", "3") check = self.mk_check(deprecated=deprecated, banned=banned) for eapi_str in deprecated: r = self.assertReport(check, self.mk_pkg(eapi=eapi_str)) assert isinstance(r, metadata.DeprecatedEapi) assert r.eapi == eapi_str - assert f'uses deprecated EAPI {eapi_str}' in str(r) + assert f"uses deprecated EAPI {eapi_str}" in str(r) def test_banned_eapi(self): - deprecated = ('0', '2', '4', '5') - banned = ('1', '3') + deprecated = ("0", "2", "4", "5") + banned = ("1", "3") check = self.mk_check(deprecated=deprecated, banned=banned) for eapi_str in banned: r = self.assertReport(check, self.mk_pkg(eapi=eapi_str)) assert isinstance(r, metadata.BannedEapi) assert r.eapi == eapi_str - assert f'uses banned EAPI {eapi_str}' in str(r) + assert f"uses banned EAPI {eapi_str}" in str(r) class TestSourcingCheck(misc.ReportTestCase, misc.Tmpdir): @@ -387,19 +393,19 @@ class TestSourcingCheck(misc.ReportTestCase, misc.Tmpdir): # TODO: switch to using a repo fixture when available repo_dir = pjoin(self.dir, str(self._repo_id)) self._repo_id += 1 - os.makedirs(pjoin(repo_dir, 'profiles')) - os.makedirs(pjoin(repo_dir, 'metadata')) - with open(pjoin(repo_dir, 'profiles', 'repo_name'), 'w') as f: - f.write('fake\n') - with open(pjoin(repo_dir, 'metadata', 'layout.conf'), 'w') as f: - f.write('masters =\n') + os.makedirs(pjoin(repo_dir, "profiles")) + os.makedirs(pjoin(repo_dir, "metadata")) + with open(pjoin(repo_dir, "profiles", "repo_name"), "w") as f: + f.write("fake\n") + with open(pjoin(repo_dir, "metadata", "layout.conf"), "w") as f: + f.write("masters =\n") repo_config = repo_objs.RepoConfig(location=repo_dir) self.repo = repository.UnconfiguredTree(repo_config.location, repo_config=repo_config) options = arghparse.Namespace(target_repo=self.repo, verbosity=False) return self.check_kls(options) def mk_pkg(self, eapi): - return misc.FakePkg('dev-util/diffball-2.7.1', data={'EAPI': eapi}) + return misc.FakePkg("dev-util/diffball-2.7.1", data={"EAPI": eapi}) def test_repo_with_no_settings(self): check = self.mk_check() @@ -407,51 +413,43 @@ class TestSourcingCheck(misc.ReportTestCase, misc.Tmpdir): self.assertNoReport(check, self.mk_pkg(eapi=eapi_str)) def test_unknown_eapis(self): - for eapi in ('blah', '9999'): + for eapi in ("blah", "9999"): check = self.mk_check() - pkg_path = pjoin(self.repo.location, 'dev-util', 'foo') + pkg_path = pjoin(self.repo.location, "dev-util", "foo") os.makedirs(pkg_path) - with open(pjoin(pkg_path, 'foo-0.ebuild'), 'w') as f: - f.write(textwrap.dedent(f"""\ - EAPI={eapi} - """)) + with open(pjoin(pkg_path, "foo-0.ebuild"), "w") as f: + f.write(f"EAPI={eapi}\n") r = self.assertReport(check, self.repo) assert isinstance(r, metadata.InvalidEapi) assert f"EAPI '{eapi}' is not supported" in str(r) def test_invalid_eapis(self): - for eapi in ('invalid!', '${EAPI}'): + for eapi in ("invalid!", "${EAPI}"): check = self.mk_check() - pkg_path = pjoin(self.repo.location, 'dev-util', 'foo') + pkg_path = pjoin(self.repo.location, "dev-util", "foo") os.makedirs(pkg_path) - with open(pjoin(pkg_path, 'foo-0.ebuild'), 'w') as f: - f.write(textwrap.dedent(f"""\ - EAPI="{eapi}" - """)) + with open(pjoin(pkg_path, "foo-0.ebuild"), "w") as f: + f.write(f"EAPI={eapi}\n") r = self.assertReport(check, self.repo) assert isinstance(r, metadata.InvalidEapi) assert f"invalid EAPI '{eapi}'" in str(r) def test_sourcing_error(self): check = self.mk_check() - pkg_path = pjoin(self.repo.location, 'dev-util', 'foo') + pkg_path = pjoin(self.repo.location, "dev-util", "foo") os.makedirs(pkg_path) - with open(pjoin(pkg_path, 'foo-0.ebuild'), 'w') as f: - f.write(textwrap.dedent("""\ - foo - """)) + with open(pjoin(pkg_path, "foo-0.ebuild"), "w") as f: + f.write("foo\n") r = self.assertReport(check, self.repo) assert isinstance(r, metadata.SourcingError) def test_invalid_slots(self): - for slot in ('?', '0/1'): + for slot in ("?", "0/1"): check = self.mk_check() - pkg_path = pjoin(self.repo.location, 'dev-util', 'foo') + pkg_path = pjoin(self.repo.location, "dev-util", "foo") os.makedirs(pkg_path) - with open(pjoin(pkg_path, 'foo-0.ebuild'), 'w') as f: - f.write(textwrap.dedent(f"""\ - SLOT="{slot}" - """)) + with open(pjoin(pkg_path, "foo-0.ebuild"), "w") as f: + f.write(f"""SLOT="{slot}"\n""") r = self.assertReport(check, self.repo) assert isinstance(r, metadata.InvalidSlot) assert f"invalid SLOT: '{slot}'" in str(r) @@ -467,19 +465,26 @@ class TestRequiredUseCheck(IUSE_Options, misc.ReportTestCase): def mk_check(self, masks=(), verbosity=1, profiles=None): if profiles is None: - profiles = {'x86': [misc.FakeProfile(name='default/linux/x86', masks=masks)]} + profiles = {"x86": [misc.FakeProfile(name="default/linux/x86", masks=masks)]} options = self.get_options(verbosity=verbosity) use_addon = addons.UseAddon(options) check = self.check_kls(options, use_addon=use_addon, profile_addon=profiles) return check - def mk_pkg(self, cpvstr="dev-util/diffball-0.7.1", eapi="4", iuse="", - required_use="", keywords="~amd64 x86"): + def mk_pkg( + self, + cpvstr="dev-util/diffball-0.7.1", + eapi="4", + iuse="", + required_use="", + keywords="~amd64 x86", + ): return FakePkg( cpvstr, eapi=eapi, iuse=iuse.split(), - data={"REQUIRED_USE": required_use, "KEYWORDS": keywords}) + data={"REQUIRED_USE": required_use, "KEYWORDS": keywords}, + ) def test_unsupported_eapis(self, check): for eapi_str, eapi_obj in eapi.EAPI.known_eapis.items(): @@ -489,9 +494,10 @@ class TestRequiredUseCheck(IUSE_Options, misc.ReportTestCase): def test_multireport_verbosity(self): profiles = { - 'x86': [ - misc.FakeProfile(name='default/linux/x86', masks=()), - misc.FakeProfile(name='default/linux/x86/foo', masks=())] + "x86": [ + misc.FakeProfile(name="default/linux/x86", masks=()), + misc.FakeProfile(name="default/linux/x86/foo", masks=()), + ] } # non-verbose mode should only one failure per node check = self.mk_check(verbosity=0, profiles=profiles) @@ -516,7 +522,9 @@ class TestRequiredUseCheck(IUSE_Options, misc.ReportTestCase): # only supported in >= EAPI 5 self.assertReport(check, self.mk_pkg(iuse="foo bar", required_use="?? ( foo bar )")) - self.assertNoReport(check, self.mk_pkg(eapi="5", iuse="foo bar", required_use="?? ( foo bar )")) + self.assertNoReport( + check, self.mk_pkg(eapi="5", iuse="foo bar", required_use="?? ( foo bar )") + ) def test_unstated_iuse(self, check): r = self.assertReport(check, self.mk_pkg(required_use="foo? ( blah )")) @@ -534,25 +542,34 @@ class TestRequiredUseCheck(IUSE_Options, misc.ReportTestCase): # pkgs masked by the related profile aren't checked self.assertNoReport( - self.mk_check(masks=('>=dev-util/diffball-8.0',)), - self.mk_pkg(cpvstr="dev-util/diffball-8.0", iuse="foo bar", required_use="bar")) + self.mk_check(masks=(">=dev-util/diffball-8.0",)), + self.mk_pkg(cpvstr="dev-util/diffball-8.0", iuse="foo bar", required_use="bar"), + ) # unsatisfied REQUIRED_USE r = self.assertReport(check, self.mk_pkg(iuse="foo bar", required_use="bar")) assert isinstance(r, metadata.RequiredUseDefaults) - assert r.keyword == 'x86' - assert r.profile == 'default/linux/x86' + assert r.keyword == "x86" + assert r.profile == "default/linux/x86" assert r.use == () - assert str(r.required_use) == 'bar' + assert str(r.required_use) == "bar" # at-most-one-of - self.assertNoReport(check, self.mk_pkg(eapi="5", iuse="foo bar", required_use="?? ( foo bar )")) - self.assertNoReport(check, self.mk_pkg(eapi="5", iuse="+foo bar", required_use="?? ( foo bar )")) - self.assertNoReport(check, self.mk_pkg(eapi="5", iuse="foo +bar", required_use="?? ( foo bar )")) - r = self.assertReport(check, self.mk_pkg(eapi="5", iuse="+foo +bar", required_use="?? ( foo bar )")) + self.assertNoReport( + check, self.mk_pkg(eapi="5", iuse="foo bar", required_use="?? ( foo bar )") + ) + self.assertNoReport( + check, self.mk_pkg(eapi="5", iuse="+foo bar", required_use="?? ( foo bar )") + ) + self.assertNoReport( + check, self.mk_pkg(eapi="5", iuse="foo +bar", required_use="?? ( foo bar )") + ) + r = self.assertReport( + check, self.mk_pkg(eapi="5", iuse="+foo +bar", required_use="?? ( foo bar )") + ) assert isinstance(r, metadata.RequiredUseDefaults) - assert r.use == ('bar', 'foo') - assert str(r.required_use) == 'at-most-one-of ( foo bar )' + assert r.use == ("bar", "foo") + assert str(r.required_use) == "at-most-one-of ( foo bar )" # exactly-one-of self.assertNoReport(check, self.mk_pkg(iuse="+foo bar", required_use="^^ ( foo bar )")) @@ -560,35 +577,48 @@ class TestRequiredUseCheck(IUSE_Options, misc.ReportTestCase): self.assertReport(check, self.mk_pkg(iuse="foo bar", required_use="^^ ( foo bar )")) r = self.assertReport(check, self.mk_pkg(iuse="+foo +bar", required_use="^^ ( foo bar )")) assert isinstance(r, metadata.RequiredUseDefaults) - assert r.use == ('bar', 'foo') - assert str(r.required_use) == 'exactly-one-of ( foo bar )' + assert r.use == ("bar", "foo") + assert str(r.required_use) == "exactly-one-of ( foo bar )" # all-of self.assertNoReport(check, self.mk_pkg(iuse="foo bar baz", required_use="foo? ( bar baz )")) - self.assertNoReport(check, self.mk_pkg(iuse="+foo +bar +baz", required_use="foo? ( bar baz )")) + self.assertNoReport( + check, self.mk_pkg(iuse="+foo +bar +baz", required_use="foo? ( bar baz )") + ) self.assertReports(check, self.mk_pkg(iuse="+foo bar baz", required_use="foo? ( bar baz )")) self.assertReport(check, self.mk_pkg(iuse="+foo +bar baz", required_use="foo? ( bar baz )")) - r = self.assertReport(check, self.mk_pkg(iuse="+foo bar +baz", required_use="foo? ( bar baz )")) + r = self.assertReport( + check, self.mk_pkg(iuse="+foo bar +baz", required_use="foo? ( bar baz )") + ) assert isinstance(r, metadata.RequiredUseDefaults) - assert r.use == ('baz', 'foo') + assert r.use == ("baz", "foo") # TODO: fix this output to show both required USE flags - assert str(r.required_use) == 'bar' + assert str(r.required_use) == "bar" # any-of - self.assertNoReport(check, self.mk_pkg(iuse="foo bar baz", required_use="foo? ( || ( bar baz ) )")) - self.assertNoReport(check, self.mk_pkg(iuse="+foo +bar baz", required_use="foo? ( || ( bar baz ) )")) - self.assertNoReport(check, self.mk_pkg(iuse="+foo bar +baz", required_use="foo? ( || ( bar baz ) )")) - self.assertNoReport(check, self.mk_pkg(iuse="+foo +bar +baz", required_use="foo? ( || ( bar baz ) )")) - r = self.assertReport(check, self.mk_pkg(iuse="+foo bar baz", required_use="foo? ( || ( bar baz ) )")) + self.assertNoReport( + check, self.mk_pkg(iuse="foo bar baz", required_use="foo? ( || ( bar baz ) )") + ) + self.assertNoReport( + check, self.mk_pkg(iuse="+foo +bar baz", required_use="foo? ( || ( bar baz ) )") + ) + self.assertNoReport( + check, self.mk_pkg(iuse="+foo bar +baz", required_use="foo? ( || ( bar baz ) )") + ) + self.assertNoReport( + check, self.mk_pkg(iuse="+foo +bar +baz", required_use="foo? ( || ( bar baz ) )") + ) + r = self.assertReport( + check, self.mk_pkg(iuse="+foo bar baz", required_use="foo? ( || ( bar baz ) )") + ) assert isinstance(r, metadata.RequiredUseDefaults) - assert r.use == ('foo',) - assert str(r.required_use) == '( bar || baz )' + assert r.use == ("foo",) + assert str(r.required_use) == "( bar || baz )" def use_based(): # hidden to keep the test runner from finding it class UseBased(IUSE_Options): - def test_required_addons(self): assert addons.UseAddon in self.check_kls.required_addons @@ -604,30 +634,32 @@ def use_based(): class _TestRestrictPropertiesCheck(use_based(), misc.ReportTestCase): - - def mk_pkg(self, restrict='', properties='', iuse=''): + def mk_pkg(self, restrict="", properties="", iuse=""): return misc.FakePkg( - 'dev-util/diffball-2.7.1', - data={'IUSE': iuse, 'RESTRICT': restrict, 'PROPERTIES': properties}) + "dev-util/diffball-2.7.1", + data={"IUSE": iuse, "RESTRICT": restrict, "PROPERTIES": properties}, + ) def test_no_allowed(self): # repo or its masters don't define any allowed values so anything goes check = self.mk_check() - self.assertNoReport(check, self.mk_pkg(**{self.check_kls._attr: 'foo'})) - self.assertNoReport(check, self.mk_pkg(**{self.check_kls._attr: 'foo? ( bar )', 'iuse': 'foo'})) + self.assertNoReport(check, self.mk_pkg(**{self.check_kls._attr: "foo"})) + self.assertNoReport( + check, self.mk_pkg(**{self.check_kls._attr: "foo? ( bar )", "iuse": "foo"}) + ) def test_allowed(self): - check = self.mk_check(options={self.check_kls._attr: ('foo',)}) + check = self.mk_check(options={self.check_kls._attr: ("foo",)}) # allowed - self.assertNoReport(check, self.mk_pkg(**{self.check_kls._attr: 'foo'})) + self.assertNoReport(check, self.mk_pkg(**{self.check_kls._attr: "foo"})) # unknown - r = self.assertReport(check, self.mk_pkg(**{self.check_kls._attr: 'bar'})) + r = self.assertReport(check, self.mk_pkg(**{self.check_kls._attr: "bar"})) assert isinstance(r, self.check_kls._unknown_result_cls) assert f'unknown {self.check_kls._attr.upper()}="bar"' in str(r) # unknown multiple, conditional - pkg = self.mk_pkg(**{self.check_kls._attr: 'baz? ( foo bar boo )', 'iuse': 'baz'}) + pkg = self.mk_pkg(**{self.check_kls._attr: "baz? ( foo bar boo )", "iuse": "baz"}) r = self.assertReport(check, pkg) assert isinstance(r, self.check_kls._unknown_result_cls) assert f'unknown {self.check_kls._attr.upper()}="bar boo"' in str(r) @@ -635,17 +667,21 @@ class _TestRestrictPropertiesCheck(use_based(), misc.ReportTestCase): def test_unstated_iuse(self): check = self.mk_check() # no IUSE - self.assertNoReport(check, self.mk_pkg(**{self.check_kls._attr: 'foo'})) + self.assertNoReport(check, self.mk_pkg(**{self.check_kls._attr: "foo"})) # conditional with IUSE defined - self.assertNoReport(check, self.mk_pkg(**{self.check_kls._attr: 'foo? ( bar )', 'iuse': 'foo'})) + self.assertNoReport( + check, self.mk_pkg(**{self.check_kls._attr: "foo? ( bar )", "iuse": "foo"}) + ) # conditional missing IUSE - r = self.assertReport(check, self.mk_pkg(**{self.check_kls._attr: 'foo? ( bar )'})) + r = self.assertReport(check, self.mk_pkg(**{self.check_kls._attr: "foo? ( bar )"})) assert isinstance(r, addons.UnstatedIuse) - assert 'unstated flag: [ foo ]' in str(r) + assert "unstated flag: [ foo ]" in str(r) # multiple missing IUSE - r = self.assertReport(check, self.mk_pkg(**{self.check_kls._attr: 'foo? ( bar ) boo? ( blah )'})) + r = self.assertReport( + check, self.mk_pkg(**{self.check_kls._attr: "foo? ( bar ) boo? ( blah )"}) + ) assert isinstance(r, addons.UnstatedIuse) - assert 'unstated flags: [ boo, foo ]' in str(r) + assert "unstated flags: [ boo, foo ]" in str(r) class TestRestrictCheck(_TestRestrictPropertiesCheck): @@ -670,30 +706,33 @@ class TestRestrictTestCheck(misc.ReportTestCase): check_kls = metadata.RestrictTestCheck check = metadata.RestrictTestCheck(None) - def mk_pkg(self, iuse='', restrict=''): - return misc.FakePkg( - 'dev-util/diffball-2.7.1', data={'IUSE': iuse, 'RESTRICT': restrict}) + def mk_pkg(self, iuse="", restrict=""): + return misc.FakePkg("dev-util/diffball-2.7.1", data={"IUSE": iuse, "RESTRICT": restrict}) def test_empty_restrict(self): self.assertNoReport(self.check, self.mk_pkg()) def test_specified_restrict(self): - self.assertNoReport(self.check, self.mk_pkg( - iuse='test', restrict='!test? ( test )')) + self.assertNoReport(self.check, self.mk_pkg(iuse="test", restrict="!test? ( test )")) # unconditional restriction is fine too - self.assertNoReport(self.check, self.mk_pkg(iuse='test', restrict='test')) - self.assertNoReport(self.check, self.mk_pkg(restrict='test')) + self.assertNoReport(self.check, self.mk_pkg(iuse="test", restrict="test")) + self.assertNoReport(self.check, self.mk_pkg(restrict="test")) # more RESTRICTs - self.assertNoReport(self.check, self.mk_pkg(iuse='foo test', - restrict='foo? ( strip ) !test? ( test ) bindist')) + self.assertNoReport( + self.check, + self.mk_pkg(iuse="foo test", restrict="foo? ( strip ) !test? ( test ) bindist"), + ) def test_missing_restrict(self): data = ( - ('test', ''), # missing entirely - ('foo test', '!foo? ( test )'), # 'test' present in other condition - ('foo test', '!foo? ( !test? ( test ) )'), # correct restriction inside another condition - ('test', 'test? ( test )'), # USE condition gotten the other way around + ("test", ""), # missing entirely + ("foo test", "!foo? ( test )"), # 'test' present in other condition + ( + "foo test", + "!foo? ( !test? ( test ) )", + ), # correct restriction inside another condition + ("test", "test? ( test )"), # USE condition gotten the other way around ) for iuse, restrict in data: r = self.assertReport(self.check, self.mk_pkg(iuse=iuse, restrict=restrict)) @@ -706,67 +745,65 @@ class TestLicenseCheck(use_based(), misc.ReportTestCase): check_kls = metadata.LicenseCheck def mk_check(self, licenses=(), **kwargs): - self.repo = FakeRepo(repo_id='test', licenses=licenses) + self.repo = FakeRepo(repo_id="test", licenses=licenses) options = self.get_options(**kwargs) use_addon = addons.UseAddon(options) check = self.check_kls(options, use_addon=use_addon) return check - def mk_pkg(self, license='', iuse=''): + def mk_pkg(self, license="", iuse=""): return FakePkg( - 'dev-util/diffball-2.7.1', - data={'LICENSE': license, 'IUSE': iuse}, - repo=self.repo) + "dev-util/diffball-2.7.1", data={"LICENSE": license, "IUSE": iuse}, repo=self.repo + ) def test_malformed(self): r = self.assertReport(self.mk_check(), self.mk_pkg("|| (")) assert isinstance(r, metadata.InvalidLicense) - assert r.attr == 'license' + assert r.attr == "license" def test_empty(self): r = self.assertReport(self.mk_check(), self.mk_pkg()) assert isinstance(r, metadata.MissingLicense) def test_unstated_iuse(self): - chk = self.mk_check(licenses=('BSD',)) + chk = self.mk_check(licenses=("BSD",)) # no IUSE - self.assertNoReport(chk, self.mk_pkg('BSD')) + self.assertNoReport(chk, self.mk_pkg("BSD")) # conditional URI with related IUSE - pkg = self.mk_pkg(license='foo? ( BSD )', iuse='foo') + pkg = self.mk_pkg(license="foo? ( BSD )", iuse="foo") self.assertNoReport(chk, pkg) # conditional URI with missing IUSE - pkg = self.mk_pkg(license='foo? ( BSD )') + pkg = self.mk_pkg(license="foo? ( BSD )") r = self.assertReport(chk, pkg) assert isinstance(r, addons.UnstatedIuse) - assert 'unstated flag: [ foo ]' in str(r) + assert "unstated flag: [ foo ]" in str(r) def test_single_missing(self): r = self.assertReport(self.mk_check(), self.mk_pkg("foo")) assert isinstance(r, metadata.UnknownLicense) - assert r.licenses == ('foo',) + assert r.licenses == ("foo",) def test_multiple_existing(self): - chk = self.mk_check(['foo', 'foo2']) - self.assertNoReport(chk, self.mk_pkg('foo')) - self.assertNoReport(chk, self.mk_pkg('foo', 'foo2')) + chk = self.mk_check(["foo", "foo2"]) + self.assertNoReport(chk, self.mk_pkg("foo")) + self.assertNoReport(chk, self.mk_pkg("foo", "foo2")) def test_multiple_missing(self): - chk = self.mk_check(['foo', 'foo2']) - r = self.assertReport(chk, self.mk_pkg('|| ( foo foo3 foo4 )')) + chk = self.mk_check(["foo", "foo2"]) + r = self.assertReport(chk, self.mk_pkg("|| ( foo foo3 foo4 )")) assert isinstance(r, metadata.UnknownLicense) - assert r.licenses == ('foo3', 'foo4') + assert r.licenses == ("foo3", "foo4") def test_unlicensed_categories(self): - check = self.mk_check(['foo']) + check = self.mk_check(["foo"]) for category in self.check_kls.unlicensed_categories: - for license in ('foo', ''): + for license in ("foo", ""): pkg = FakePkg( - f'{category}/diffball-2.7.1', - data={'LICENSE': license}, - repo=self.repo) + f"{category}/diffball-2.7.1", data={"LICENSE": license}, repo=self.repo + ) if license: r = self.assertReport(check, pkg) assert isinstance(r, metadata.UnnecessaryLicense) @@ -782,87 +819,94 @@ class TestMissingSlotDepCheck(use_based(), misc.ReportTestCase): def mk_check(self, pkgs=None, **kwargs): if pkgs is None: pkgs = ( - FakePkg('dev-libs/foo-0', slot='0'), - FakePkg('dev-libs/foo-1', slot='1'), - FakePkg('dev-libs/bar-2', slot='2'), + FakePkg("dev-libs/foo-0", slot="0"), + FakePkg("dev-libs/foo-1", slot="1"), + FakePkg("dev-libs/bar-2", slot="2"), ) - self.repo = FakeRepo(pkgs=pkgs, repo_id='test') + self.repo = FakeRepo(pkgs=pkgs, repo_id="test") options = self.get_options(**kwargs) use_addon = addons.UseAddon(options) check = self.check_kls(options, use_addon=use_addon) return check - def mk_pkg(self, eapi='5', rdepend='', depend=''): + def mk_pkg(self, eapi="5", rdepend="", depend=""): return FakePkg( - 'dev-util/diffball-2.7.1', eapi=eapi, - data={'RDEPEND': rdepend, 'DEPEND': depend}, - repo=self.repo) + "dev-util/diffball-2.7.1", + eapi=eapi, + data={"RDEPEND": rdepend, "DEPEND": depend}, + repo=self.repo, + ) def test_flagged_deps(self): - for dep_str in ('dev-libs/foo', 'dev-libs/foo[bar]'): + for dep_str in ("dev-libs/foo", "dev-libs/foo[bar]"): for eapi_str, eapi_obj in eapi.EAPI.known_eapis.items(): if eapi_obj.options.sub_slotting: r = self.assertReport( - self.mk_check(), self.mk_pkg( - eapi=eapi_str, rdepend=dep_str, depend=dep_str)) + self.mk_check(), self.mk_pkg(eapi=eapi_str, rdepend=dep_str, depend=dep_str) + ) assert isinstance(r, metadata.MissingSlotDep) - assert 'matches more than one slot: [ 0, 1 ]' in str(r) + assert "matches more than one slot: [ 0, 1 ]" in str(r) def test_skipped_deps(self): for dep_str in ( - '!dev-libs/foo', '!!dev-libs/foo', # blockers - '~dev-libs/foo-0', '~dev-libs/foo-1', # version limited to single slots - 'dev-libs/foo:0', 'dev-libs/foo:1', # slotted - 'dev-libs/foo:*', 'dev-libs/foo:=', # slot operators - ): + "!dev-libs/foo", + "!!dev-libs/foo", # blockers + "~dev-libs/foo-0", + "~dev-libs/foo-1", # version limited to single slots + "dev-libs/foo:0", + "dev-libs/foo:1", # slotted + "dev-libs/foo:*", + "dev-libs/foo:=", # slot operators + ): for eapi_str, eapi_obj in eapi.EAPI.known_eapis.items(): if eapi_obj.options.sub_slotting: self.assertNoReport( - self.mk_check(), self.mk_pkg( - eapi=eapi_str, rdepend=dep_str, depend=dep_str)) + self.mk_check(), self.mk_pkg(eapi=eapi_str, rdepend=dep_str, depend=dep_str) + ) def test_no_deps(self): self.assertNoReport(self.mk_check(), self.mk_pkg()) def test_single_slot_dep(self): self.assertNoReport( - self.mk_check(), self.mk_pkg(rdepend='dev-libs/bar', depend='dev-libs/bar')) + self.mk_check(), self.mk_pkg(rdepend="dev-libs/bar", depend="dev-libs/bar") + ) class TestDependencyCheck(use_based(), misc.ReportTestCase): check_kls = metadata.DependencyCheck - def mk_pkg(self, attr, depset='', eapi='0', iuse=''): - eapi_attr_map = {'BDEPEND': '7', 'IDEPEND': '8'} + def mk_pkg(self, attr, depset="", eapi="0", iuse=""): + eapi_attr_map = {"BDEPEND": "7", "IDEPEND": "8"} eapi = eapi_attr_map.get(attr, eapi) return misc.FakePkg( - 'dev-util/diffball-2.7.1', - data={'EAPI': eapi, 'IUSE': iuse, attr: depset}) + "dev-util/diffball-2.7.1", data={"EAPI": eapi, "IUSE": iuse, attr: depset} + ) def mk_check(self, pkgs=None, **kwargs): if pkgs is None: pkgs = ( - FakePkg('dev-libs/foo-0', slot='0', iuse=('bar',)), - FakePkg('dev-libs/foo-1', slot='1', iuse=('bar', 'baz')), - FakePkg('dev-libs/bar-2', slot='2'), + FakePkg("dev-libs/foo-0", slot="0", iuse=("bar",)), + FakePkg("dev-libs/foo-1", slot="1", iuse=("bar", "baz")), + FakePkg("dev-libs/bar-2", slot="2"), ) - kwargs['search_repo'] = FakeRepo(pkgs=pkgs, repo_id='test') + kwargs["search_repo"] = FakeRepo(pkgs=pkgs, repo_id="test") return super().mk_check(options=kwargs) # pull the set of dependency attrs from the most recent EAPI dep_attrs = sorted(list(eapi.EAPI.known_eapis.values())[-1].dep_keys) - @pytest.mark.parametrize('attr', dep_attrs) + @pytest.mark.parametrize("attr", dep_attrs) def test_depset(self, attr): chk = self.mk_check() mk_pkg = partial(self.mk_pkg, attr) # various regular depsets self.assertNoReport(chk, mk_pkg()) - self.assertNoReport(chk, mk_pkg('dev-util/foo')) + self.assertNoReport(chk, mk_pkg("dev-util/foo")) self.assertNoReport(chk, mk_pkg("|| ( dev-util/foo ) dev-foo/bugger ")) - if attr == 'RDEPEND': + if attr == "RDEPEND": self.assertNoReport(chk, mk_pkg("!dev-util/blah")) else: r = self.assertReport(chk, mk_pkg("!dev-util/blah")) @@ -870,7 +914,7 @@ class TestDependencyCheck(use_based(), misc.ReportTestCase): # invalid depset syntax r = self.assertReport(chk, mk_pkg("|| (")) - assert isinstance(r, getattr(metadata, f'Invalid{attr.lower().capitalize()}')) + assert isinstance(r, getattr(metadata, f"Invalid{attr.lower().capitalize()}")) # pkg blocking itself r = self.assertReport(chk, mk_pkg("!dev-util/diffball")) @@ -879,105 +923,113 @@ class TestDependencyCheck(use_based(), misc.ReportTestCase): assert f'{attr.upper()}="!dev-util/diffball"' in str(r) # check for := in || () blocks - pkg = mk_pkg(eapi='5', depset="|| ( dev-libs/foo:= dev-libs/bar )") + pkg = mk_pkg(eapi="5", depset="|| ( dev-libs/foo:= dev-libs/bar )") r = self.assertReport(chk, pkg) assert isinstance(r, metadata.BadDependency) assert "= slot operator used inside || block" in str(r) assert f'{attr.upper()}="dev-libs/foo:="' in str(r) # multiple := atoms in || () blocks - pkg = mk_pkg(eapi='5', depset="|| ( dev-libs/foo:= dev-libs/bar:= )") + pkg = mk_pkg(eapi="5", depset="|| ( dev-libs/foo:= dev-libs/bar:= )") reports = self.assertReports(chk, pkg) for r in reports: assert isinstance(r, metadata.BadDependency) assert "= slot operator used inside || block" in str(r) # check for := in blockers - r = self.assertReport(chk, mk_pkg(eapi='5', depset="!dev-libs/foo:=")) + r = self.assertReport(chk, mk_pkg(eapi="5", depset="!dev-libs/foo:=")) assert isinstance(r, metadata.BadDependency) assert "= slot operator used in blocker" in str(r) assert f'{attr.upper()}="!dev-libs/foo:="' in str(r) # check for missing package revisions self.assertNoReport(chk, mk_pkg("=dev-libs/foo-1-r0")) - r = self.assertReport(chk, mk_pkg(eapi='6', depset="=dev-libs/foo-1")) + r = self.assertReport(chk, mk_pkg(eapi="6", depset="=dev-libs/foo-1")) assert isinstance(r, metadata.MissingPackageRevision) assert f'{attr.upper()}="=dev-libs/foo-1"' in str(r) - @pytest.mark.parametrize('attr', dep_attrs) + @pytest.mark.parametrize("attr", dep_attrs) def test_depset_unstated_iuse(self, attr): chk = self.mk_check() mk_pkg = partial(self.mk_pkg, attr) # unstated IUSE - r = self.assertReport(chk, mk_pkg(depset='foo? ( dev-libs/foo )')) + r = self.assertReport(chk, mk_pkg(depset="foo? ( dev-libs/foo )")) assert isinstance(r, addons.UnstatedIuse) - assert 'unstated flag: [ foo ]' in str(r) + assert "unstated flag: [ foo ]" in str(r) # known IUSE - self.assertNoReport(chk, mk_pkg(depset='foo? ( dev-libs/foo )', iuse='foo')) + self.assertNoReport(chk, mk_pkg(depset="foo? ( dev-libs/foo )", iuse="foo")) # multiple unstated IUSE - r = self.assertReport(chk, mk_pkg(depset='foo? ( !bar? ( dev-libs/foo ) )')) + r = self.assertReport(chk, mk_pkg(depset="foo? ( !bar? ( dev-libs/foo ) )")) assert isinstance(r, addons.UnstatedIuse) - assert 'unstated flags: [ bar, foo ]' in str(r) + assert "unstated flags: [ bar, foo ]" in str(r) - @pytest.mark.parametrize('attr', dep_attrs) + @pytest.mark.parametrize("attr", dep_attrs) def test_depset_missing_usedep_default(self, attr): chk = self.mk_check() mk_pkg = partial(self.mk_pkg, attr) # USE flag exists on all matching pkgs - self.assertNoReport(chk, mk_pkg(eapi='4', depset='dev-libs/foo[bar?]')) + self.assertNoReport(chk, mk_pkg(eapi="4", depset="dev-libs/foo[bar?]")) use_deps = ( - 'foo(-)?', '!foo(-)?', 'foo(+)?', '!foo(+)?', 'foo(-)=', '!foo(-)=', - 'foo(+)=', '!foo(+)=', '-foo(-)', '-foo(+)', + "foo(-)?", + "!foo(-)?", + "foo(+)?", + "!foo(+)?", + "foo(-)=", + "!foo(-)=", + "foo(+)=", + "!foo(+)=", + "-foo(-)", + "-foo(+)", ) for use_dep in use_deps: # USE flag doesn't exist but has proper default - self.assertNoReport(chk, mk_pkg(eapi='4', depset=f'dev-libs/bar[{use_dep}]')) - if attr == 'RDEPEND': - self.assertNoReport(chk, mk_pkg(eapi='4', depset=f'!dev-libs/bar[{use_dep}]')) + self.assertNoReport(chk, mk_pkg(eapi="4", depset=f"dev-libs/bar[{use_dep}]")) + if attr == "RDEPEND": + self.assertNoReport(chk, mk_pkg(eapi="4", depset=f"!dev-libs/bar[{use_dep}]")) else: - r = self.assertReport(chk, mk_pkg(eapi='4', depset=f'!dev-libs/bar[{use_dep}]')) + r = self.assertReport(chk, mk_pkg(eapi="4", depset=f"!dev-libs/bar[{use_dep}]")) assert isinstance(r, metadata.MisplacedWeakBlocker) # result triggers when all matching pkgs don't have requested USE flag for dep in ( - 'dev-libs/bar[foo?]', - 'dev-libs/bar[!foo?]', - 'dev-libs/bar[foo=]', - 'dev-libs/bar[!foo=]', - 'dev-libs/bar[-foo]', - '|| ( dev-libs/foo[bar] dev-libs/bar[foo] )', - '|| ( dev-libs/foo[bar] dev-libs/bar[-foo] )', - ): - r = self.assertReport(chk, mk_pkg(eapi='4', depset=dep)) + "dev-libs/bar[foo?]", + "dev-libs/bar[!foo?]", + "dev-libs/bar[foo=]", + "dev-libs/bar[!foo=]", + "dev-libs/bar[-foo]", + "|| ( dev-libs/foo[bar] dev-libs/bar[foo] )", + "|| ( dev-libs/foo[bar] dev-libs/bar[-foo] )", + ): + r = self.assertReport(chk, mk_pkg(eapi="4", depset=dep)) assert isinstance(r, metadata.MissingUseDepDefault) - assert r.pkgs == ('dev-libs/bar-2',) - assert r.flag == 'foo' + assert r.pkgs == ("dev-libs/bar-2",) + assert r.flag == "foo" assert "USE flag 'foo' missing" in str(r) - if attr == 'RDEPEND': - r = self.assertReport(chk, mk_pkg(eapi='4', depset='!dev-libs/bar[foo?]')) + if attr == "RDEPEND": + r = self.assertReport(chk, mk_pkg(eapi="4", depset="!dev-libs/bar[foo?]")) assert isinstance(r, metadata.MissingUseDepDefault) - assert r.pkgs == ('dev-libs/bar-2',) - assert r.flag == 'foo' + assert r.pkgs == ("dev-libs/bar-2",) + assert r.flag == "foo" assert "USE flag 'foo' missing" in str(r) # USE flag missing on one of multiple matches - r = self.assertReport(chk, mk_pkg(eapi='4', depset='dev-libs/foo[baz?]')) + r = self.assertReport(chk, mk_pkg(eapi="4", depset="dev-libs/foo[baz?]")) assert isinstance(r, metadata.MissingUseDepDefault) - assert r.atom == 'dev-libs/foo[baz?]' - assert r.pkgs == ('dev-libs/foo-0',) - assert r.flag == 'baz' + assert r.atom == "dev-libs/foo[baz?]" + assert r.pkgs == ("dev-libs/foo-0",) + assert r.flag == "baz" assert "USE flag 'baz' missing" in str(r) # USE flag missing on all matches - r = self.assertReport(chk, mk_pkg(eapi='4', depset='dev-libs/foo[blah?]')) + r = self.assertReport(chk, mk_pkg(eapi="4", depset="dev-libs/foo[blah?]")) assert isinstance(r, metadata.MissingUseDepDefault) - assert r.atom == 'dev-libs/foo[blah?]' - assert r.pkgs == ('dev-libs/foo-0', 'dev-libs/foo-1') - assert r.flag == 'blah' + assert r.atom == "dev-libs/foo[blah?]" + assert r.pkgs == ("dev-libs/foo-0", "dev-libs/foo-1") + assert r.flag == "blah" assert "USE flag 'blah' missing" in str(r) @@ -993,16 +1045,16 @@ class TestOutdatedBlockersCheck(misc.ReportTestCase): # initialize parent repo self.parent_git_repo = make_git_repo() self.parent_repo = make_repo(self.parent_git_repo.path) - self.parent_git_repo.add_all('initial commit') + self.parent_git_repo.add_all("initial commit") # create a stub pkg and commit it - self.parent_repo.create_ebuild('cat/pkg-0') - self.parent_git_repo.add_all('cat/pkg-0') + self.parent_repo.create_ebuild("cat/pkg-0") + self.parent_git_repo.add_all("cat/pkg-0") # initialize child repo self.child_git_repo = make_git_repo() - self.child_git_repo.run(['git', 'remote', 'add', 'origin', self.parent_git_repo.path]) - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + self.child_git_repo.run(["git", "remote", "add", "origin", self.parent_git_repo.path]) + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.child_repo = make_repo(self.child_git_repo.path) def init_check(self, options=None, future=0): @@ -1015,36 +1067,39 @@ class TestOutdatedBlockersCheck(misc.ReportTestCase): def _options(self, **kwargs): args = [ - 'scan', '-q', '--cache-dir', self.cache_dir, - '--repo', self.child_repo.location, + "scan", + "-q", + "--cache-dir", + self.cache_dir, + "--repo", + self.child_repo.location, ] options, _ = self.tool.parse_args(args) return options def test_existent_blockers(self): - self.child_repo.create_ebuild('cat/pkg-1', depend='!~cat/pkg-0') - self.child_git_repo.add_all('cat/pkg: version bump to 1') - self.child_repo.create_ebuild('cat/pkg-2', depend='!!~cat/pkg-0') - self.child_git_repo.add_all('cat/pkg: version bump to 2') - self.child_repo.create_ebuild('cat/pkg-3', depend='!!=cat/pkg-0*') - self.child_git_repo.add_all('cat/pkg: version bump to 3') + self.child_repo.create_ebuild("cat/pkg-1", depend="!~cat/pkg-0") + self.child_git_repo.add_all("cat/pkg: version bump to 1") + self.child_repo.create_ebuild("cat/pkg-2", depend="!!~cat/pkg-0") + self.child_git_repo.add_all("cat/pkg: version bump to 2") + self.child_repo.create_ebuild("cat/pkg-3", depend="!!=cat/pkg-0*") + self.child_git_repo.add_all("cat/pkg: version bump to 3") self.init_check() self.assertNoReport(self.check, self.source) def test_nonexistent_blockers(self): - self.child_repo.create_ebuild('cat/pkg-1', depend='!nonexistent/pkg') - self.child_git_repo.add_all('cat/pkg: version bump to 1') + self.child_repo.create_ebuild("cat/pkg-1", depend="!nonexistent/pkg") + self.child_git_repo.add_all("cat/pkg: version bump to 1") self.init_check() r = self.assertReport(self.check, self.source) - expected = metadata.NonexistentBlocker( - 'DEPEND', '!nonexistent/pkg', pkg=CPV('cat/pkg-1')) + expected = metadata.NonexistentBlocker("DEPEND", "!nonexistent/pkg", pkg=CPV("cat/pkg-1")) assert r == expected def test_outdated_blockers(self): - self.parent_git_repo.remove_all('cat/pkg') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_repo.create_ebuild('cat/pkg-1', depend='!!=cat/pkg-0*') - self.child_git_repo.add_all('cat/pkg: version bump to 1') + self.parent_git_repo.remove_all("cat/pkg") + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_repo.create_ebuild("cat/pkg-1", depend="!!=cat/pkg-0*") + self.child_git_repo.add_all("cat/pkg: version bump to 1") # packages are not old enough to trigger any results for days in (0, 100, 365, 729): @@ -1056,7 +1111,8 @@ class TestOutdatedBlockersCheck(misc.ReportTestCase): self.init_check(future=days) r = self.assertReport(self.check, self.source) expected = metadata.OutdatedBlocker( - 'DEPEND', '!!=cat/pkg-0*', years, pkg=CPV('cat/pkg-1')) + "DEPEND", "!!=cat/pkg-0*", years, pkg=CPV("cat/pkg-1") + ) assert r == expected @@ -1064,16 +1120,17 @@ class TestSrcUriCheck(use_based(), misc.ReportTestCase): check_kls = metadata.SrcUriCheck - def mk_pkg(self, src_uri='', restrict='', default_chksums={"size": 100}, - iuse='', disable_chksums=False): + def mk_pkg( + self, src_uri="", restrict="", default_chksums={"size": 100}, iuse="", disable_chksums=False + ): class fake_repo: def __init__(self, default_chksums): if disable_chksums: self.chksums = {} else: self.chksums = {}.fromkeys( - {os.path.basename(x) for x in src_uri.split()}, - default_chksums) + {os.path.basename(x) for x in src_uri.split()}, default_chksums + ) def _get_digests(self, pkg, allow_missing=False): return False, self.chksums @@ -1082,47 +1139,52 @@ class TestSrcUriCheck(use_based(), misc.ReportTestCase): _parent_repo = fake_repo(default_chksums) return misc.FakePkg( - 'dev-util/diffball-2.7.1', - data={'SRC_URI': src_uri, 'IUSE': iuse, 'RESTRICT': restrict}, - parent=fake_parent()) + "dev-util/diffball-2.7.1", + data={"SRC_URI": src_uri, "IUSE": iuse, "RESTRICT": restrict}, + parent=fake_parent(), + ) def test_malformed(self): - r = self.assertReport( - self.mk_check(), self.mk_pkg("foon", disable_chksums=True)) + r = self.assertReport(self.mk_check(), self.mk_pkg("foon", disable_chksums=True)) assert isinstance(r, metadata.InvalidSrcUri) - assert r.attr == 'fetchables' + assert r.attr == "fetchables" def test_regular_src_uri(self): chk = self.mk_check() # single file - self.assertNoReport(chk, self.mk_pkg(src_uri='https://foon.com/foon-2.7.1.tar.gz')) + self.assertNoReport(chk, self.mk_pkg(src_uri="https://foon.com/foon-2.7.1.tar.gz")) # single file, multiple uris - self.assertNoReport(chk, self.mk_pkg( - src_uri='https://foo.com/a-0.tar.gz https://bar.com/a-0.tar.gz')) + self.assertNoReport( + chk, self.mk_pkg(src_uri="https://foo.com/a-0.tar.gz https://bar.com/a-0.tar.gz") + ) # multiple files, multiple uris - self.assertNoReport(chk, self.mk_pkg( - src_uri=""" + self.assertNoReport( + chk, + self.mk_pkg( + src_uri=""" https://foo.com/a-0.tar.gz https://bar.com/a-0.tar.gz https://blah.org/b-1.zip https://boo.net/boo-10.tar.xz - """)) + """ + ), + ) def test_unknown_mirror(self): chk = self.mk_check() # single mirror - r = self.assertReport(chk, self.mk_pkg('mirror://foo/a-0.gz https://foo.com/a-0.gz')) + r = self.assertReport(chk, self.mk_pkg("mirror://foo/a-0.gz https://foo.com/a-0.gz")) assert isinstance(r, metadata.UnknownMirror) - assert r.mirror == 'foo' - assert r.uri == 'mirror://foo/a-0.gz' + assert r.mirror == "foo" + assert r.uri == "mirror://foo/a-0.gz" assert "unknown mirror 'foo'" in str(r) # multiple mirrors - pkg = self.mk_pkg('mirror://foo/a-0.gz mirror://bar/a-0.gz https://foo.com/a-0.gz') + pkg = self.mk_pkg("mirror://foo/a-0.gz mirror://bar/a-0.gz https://foo.com/a-0.gz") reports = self.assertReports(chk, pkg) - for mirror, r in zip(('bar', 'foo'), sorted(reports, key=attrgetter('mirror'))): + for mirror, r in zip(("bar", "foo"), sorted(reports, key=attrgetter("mirror"))): assert isinstance(r, metadata.UnknownMirror) assert r.mirror == mirror - assert r.uri == f'mirror://{mirror}/a-0.gz' + assert r.uri == f"mirror://{mirror}/a-0.gz" assert f"unknown mirror '{mirror}'" in str(r) def test_bad_filename(self): @@ -1131,77 +1193,80 @@ class TestSrcUriCheck(use_based(), misc.ReportTestCase): # PN filename r = self.assertReport(chk, self.mk_pkg("https://foon.com/diffball.tar.gz")) assert isinstance(r, metadata.BadFilename) - assert r.filenames == ('diffball.tar.gz',) - assert 'bad filename: [ diffball.tar.gz ]' in str(r) + assert r.filenames == ("diffball.tar.gz",) + assert "bad filename: [ diffball.tar.gz ]" in str(r) # PV filename r = self.assertReport(chk, self.mk_pkg("https://foon.com/2.7.1.tar.gz")) assert isinstance(r, metadata.BadFilename) - assert r.filenames == ('2.7.1.tar.gz',) - assert 'bad filename: [ 2.7.1.tar.gz ]' in str(r) + assert r.filenames == ("2.7.1.tar.gz",) + assert "bad filename: [ 2.7.1.tar.gz ]" in str(r) # github-style PV filename r = self.assertReport(chk, self.mk_pkg("https://foon.com/v2.7.1.zip")) assert isinstance(r, metadata.BadFilename) - assert r.filenames == ('v2.7.1.zip',) - assert 'bad filename: [ v2.7.1.zip ]' in str(r) + assert r.filenames == ("v2.7.1.zip",) + assert "bad filename: [ v2.7.1.zip ]" in str(r) # github-style commit snapshot filename - r = self.assertReport(chk, self.mk_pkg("https://foon.com/cb230f01fb288a0b9f0fc437545b97d06c846bd3.tar.gz")) + r = self.assertReport( + chk, self.mk_pkg("https://foon.com/cb230f01fb288a0b9f0fc437545b97d06c846bd3.tar.gz") + ) assert isinstance(r, metadata.BadFilename) # multiple bad filenames - r = self.assertReport(chk, self.mk_pkg("https://foon.com/2.7.1.tar.gz https://foon.com/diffball.zip")) + r = self.assertReport( + chk, self.mk_pkg("https://foon.com/2.7.1.tar.gz https://foon.com/diffball.zip") + ) assert isinstance(r, metadata.BadFilename) - assert r.filenames == ('2.7.1.tar.gz', 'diffball.zip') - assert 'bad filenames: [ 2.7.1.tar.gz, diffball.zip ]' in str(r) + assert r.filenames == ("2.7.1.tar.gz", "diffball.zip") + assert "bad filenames: [ 2.7.1.tar.gz, diffball.zip ]" in str(r) def test_missing_uri(self): chk = self.mk_check() # mangled protocol - r = self.assertReport(chk, self.mk_pkg('http:/foo/foo-0.tar.gz')) + r = self.assertReport(chk, self.mk_pkg("http:/foo/foo-0.tar.gz")) assert isinstance(r, metadata.MissingUri) - assert r.filenames == ('http:/foo/foo-0.tar.gz',) + assert r.filenames == ("http:/foo/foo-0.tar.gz",) assert "unfetchable file: 'http:/foo/foo-0.tar.gz'" in str(r) # no URI and RESTRICT doesn't contain 'fetch' - r = self.assertReport(chk, self.mk_pkg('foon')) + r = self.assertReport(chk, self.mk_pkg("foon")) assert isinstance(r, metadata.MissingUri) - assert r.filenames == ('foon',) + assert r.filenames == ("foon",) assert "unfetchable file: 'foon'" in str(r) # no URI and RESTRICT contains 'fetch' - self.assertNoReport(chk, self.mk_pkg('foon', restrict='fetch')) + self.assertNoReport(chk, self.mk_pkg("foon", restrict="fetch")) # conditional URI and conditional RESTRICT containing 'fetch' - pkg = self.mk_pkg(src_uri='foo? ( bar )', iuse='foo', restrict='foo? ( fetch )') + pkg = self.mk_pkg(src_uri="foo? ( bar )", iuse="foo", restrict="foo? ( fetch )") self.assertNoReport(chk, pkg) # negated - pkg = self.mk_pkg(src_uri='!foo? ( bar )', iuse='foo', restrict='!foo? ( fetch )') + pkg = self.mk_pkg(src_uri="!foo? ( bar )", iuse="foo", restrict="!foo? ( fetch )") self.assertNoReport(chk, pkg) # multi-level conditional pkg = self.mk_pkg( - iuse='foo bar', - src_uri='foo? ( bar? ( blah ) )', - restrict='foo? ( bar? ( fetch ) )') + iuse="foo bar", src_uri="foo? ( bar? ( blah ) )", restrict="foo? ( bar? ( fetch ) )" + ) self.assertNoReport(chk, pkg) def test_unstated_iuse(self): chk = self.mk_check() # no IUSE - self.assertNoReport(chk, self.mk_pkg('https://foo.com/foo-0.tar.gz')) + self.assertNoReport(chk, self.mk_pkg("https://foo.com/foo-0.tar.gz")) # conditional URI with related IUSE - pkg = self.mk_pkg(src_uri='foo? ( https://foo.com/foo-0.tar.gz )', iuse='foo') + pkg = self.mk_pkg(src_uri="foo? ( https://foo.com/foo-0.tar.gz )", iuse="foo") self.assertNoReport(chk, pkg) # conditional URI with missing IUSE - pkg = self.mk_pkg(src_uri='foo? ( https://foo.com/foo-0.tar.gz )') + pkg = self.mk_pkg(src_uri="foo? ( https://foo.com/foo-0.tar.gz )") r = self.assertReport(chk, pkg) assert isinstance(r, addons.UnstatedIuse) - assert 'unstated flag: [ foo ]' in str(r) + assert "unstated flag: [ foo ]" in str(r) def test_bad_proto(self): chk = self.mk_check() @@ -1211,22 +1276,23 @@ class TestSrcUriCheck(use_based(), misc.ReportTestCase): for proto in self.check_kls.valid_protos: self.assertNoReport( - chk, self.mk_pkg(f"{proto}://dar.com/foon"), - msg=f"testing valid proto {proto}") + chk, self.mk_pkg(f"{proto}://dar.com/foon"), msg=f"testing valid proto {proto}" + ) - bad_proto = f'{proto}x' + bad_proto = f"{proto}x" r = self.assertReport(chk, self.mk_pkg(f"{bad_proto}://foon.com/foon")) assert isinstance(r, metadata.BadProtocol) assert bad_proto in str(r) - assert f'{bad_proto}://foon.com/foon' in str(r) + assert f"{bad_proto}://foon.com/foon" in str(r) # check collapsing pkg = self.mk_pkg(f"{bad_proto}://foon.com/foon {bad_proto}://dar.com/foon") r = self.assertReport(chk, pkg) assert isinstance(r, metadata.BadProtocol) assert list(r.uris) == sorted( - f'{bad_proto}://{x}/foon' for x in ('foon.com', 'dar.com')) + f"{bad_proto}://{x}/foon" for x in ("foon.com", "dar.com") + ) assert bad_proto in str(r) def test_tarball_available_github(self): @@ -1235,7 +1301,7 @@ class TestSrcUriCheck(use_based(), misc.ReportTestCase): r = self.assertReport(chk, self.mk_pkg(uri)) assert isinstance(r, metadata.TarballAvailable) assert r.uris == (uri,) - assert '[ https://github.com/foo/bar/archive/v1.2.3.zip ]' in str(r) + assert "[ https://github.com/foo/bar/archive/v1.2.3.zip ]" in str(r) def test_tarball_available_gitlab(self): chk = self.mk_check() @@ -1243,36 +1309,34 @@ class TestSrcUriCheck(use_based(), misc.ReportTestCase): r = self.assertReport(chk, self.mk_pkg(uri)) assert isinstance(r, metadata.TarballAvailable) assert r.uris == (uri,) - assert 'zip archive used when tarball available' in str(r) + assert "zip archive used when tarball available" in str(r) class TestMissingUnpackerDepCheck(use_based(), misc.ReportTestCase): check_kls = metadata.MissingUnpackerDepCheck - def mk_pkg(self, exts, eapi='7', **data): + def mk_pkg(self, exts, eapi="7", **data): if isinstance(exts, str): exts = [exts] class fake_repo: def _get_digests(self, pkg, allow_missing=False): - chksums = {f'diffball-2.7.1{ext}': {'size': 100} for ext in exts} + chksums = {f"diffball-2.7.1{ext}": {"size": 100} for ext in exts} return False, chksums - data['SRC_URI'] = ' '.join( - f'https://foo.com/diffball-2.7.1{ext}' for ext in exts) - return FakePkg( - 'dev-util/diffball-2.7.1', data=data, eapi=eapi, repo=fake_repo()) + data["SRC_URI"] = " ".join(f"https://foo.com/diffball-2.7.1{ext}" for ext in exts) + return FakePkg("dev-util/diffball-2.7.1", data=data, eapi=eapi, repo=fake_repo()) def test_with_system_dep(self): - self.assertNoReport(self.mk_check(), self.mk_pkg('.tar.gz')) + self.assertNoReport(self.mk_check(), self.mk_pkg(".tar.gz")) def test_keyword_output(self): # unpacker deps go in BDEPEND in EAPI >= 7 - r = self.assertReport(self.mk_check(), self.mk_pkg('.zip', eapi='7')) + r = self.assertReport(self.mk_check(), self.mk_pkg(".zip", eapi="7")) assert 'missing BDEPEND="app-arch/unzip"' in str(r) # and in DEPEND for EAPI < 7 - r = self.assertReport(self.mk_check(), self.mk_pkg('.zip', eapi='6')) + r = self.assertReport(self.mk_check(), self.mk_pkg(".zip", eapi="6")) assert 'missing DEPEND="app-arch/unzip"' in str(r) def test_without_dep(self): @@ -1280,23 +1344,22 @@ class TestMissingUnpackerDepCheck(use_based(), misc.ReportTestCase): pkg = self.mk_pkg(ext) r = self.assertReport(self.mk_check(), pkg) assert isinstance(r, metadata.MissingUnpackerDep) - assert r.filenames == (f'diffball-2.7.1{ext}',) - assert r.unpackers == tuple( - sorted(map(str, self.check_kls.non_system_unpackers[ext]))) + assert r.filenames == (f"diffball-2.7.1{ext}",) + assert r.unpackers == tuple(sorted(map(str, self.check_kls.non_system_unpackers[ext]))) def test_with_dep(self): for ext, unpackers in self.check_kls.non_system_unpackers.items(): - for dep_type in ('DEPEND', 'BDEPEND'): + for dep_type in ("DEPEND", "BDEPEND"): for unpacker in unpackers: - for dep in (unpacker, f'>={unpacker}-1'): + for dep in (unpacker, f">={unpacker}-1"): kwargs = {dep_type: dep} pkg = self.mk_pkg(ext, **kwargs) self.assertNoReport(self.mk_check(), pkg) def test_rar_with_or_dep(self): self.assertNoReport( - self.mk_check(), - self.mk_pkg('.rar', DEPEND='|| ( app-arch/rar app-arch/unrar )')) + self.mk_check(), self.mk_pkg(".rar", DEPEND="|| ( app-arch/rar app-arch/unrar )") + ) def test_without_multiple_unpackers(self): for combination in combinations(self.check_kls.non_system_unpackers.items(), 2): @@ -1310,19 +1373,19 @@ class TestMissingUnpackerDepCheck(use_based(), misc.ReportTestCase): assert len(set(unpackers)) == 1 r = reports[0] assert isinstance(r, metadata.MissingUnpackerDep) - assert r.filenames == tuple(sorted(f'diffball-2.7.1{ext}' for ext in exts)) + assert r.filenames == tuple(sorted(f"diffball-2.7.1{ext}" for ext in exts)) assert r.unpackers == tuple(sorted(map(str, unpackers[0]))) else: assert len(reports) == 2 for i, r in enumerate(reports): assert isinstance(r, metadata.MissingUnpackerDep) - assert r.filenames == (f'diffball-2.7.1{exts[i]}',) + assert r.filenames == (f"diffball-2.7.1{exts[i]}",) assert r.unpackers == tuple(sorted(map(str, unpackers[i]))) def test_with_multiple_unpackers_one_missing(self): r = self.assertReport( - self.mk_check(), - self.mk_pkg(['.zip', '.7z'], DEPEND='app-arch/unzip')) + self.mk_check(), self.mk_pkg([".zip", ".7z"], DEPEND="app-arch/unzip") + ) assert isinstance(r, metadata.MissingUnpackerDep) - assert r.filenames == (f'diffball-2.7.1.7z',) - assert r.unpackers == ('app-arch/p7zip',) + assert r.filenames == (f"diffball-2.7.1.7z",) + assert r.unpackers == ("app-arch/p7zip",) diff --git a/tests/checks/test_network.py b/tests/checks/test_network.py index bb3a7ef5..fb684954 100644 --- a/tests/checks/test_network.py +++ b/tests/checks/test_network.py @@ -10,34 +10,38 @@ from unittest.mock import patch import pytest from pkgcheck import objects, reporters, scan from pkgcheck.checks import NetworkCheck -from pkgcheck.checks.network import (DeadUrl, FetchablesUrlCheck, - HomepageUrlCheck) +from pkgcheck.checks.network import DeadUrl, FetchablesUrlCheck, HomepageUrlCheck from pkgcheck.packages import RawCPV from snakeoil.formatters import PlainTextFormatter # skip module tests if requests isn't available -requests = pytest.importorskip('requests') +requests = pytest.importorskip("requests") class TestNetworkChecks: - repos_data = pytest.REPO_ROOT / 'testdata/data/repos' - repos_dir = pytest.REPO_ROOT / 'testdata/repos' + repos_data = pytest.REPO_ROOT / "testdata/data/repos" + repos_dir = pytest.REPO_ROOT / "testdata/repos" @pytest.fixture(autouse=True) def _setup(self, testconfig, tmp_path): - base_args = ['--config', testconfig] + base_args = ["--config", testconfig] self.scan = partial(scan, base_args=base_args) self.scan_args = [ - '--config', 'no', '--cache-dir', str(tmp_path), '--net', - '-r', str(self.repos_dir / 'network'), + "--config", + "no", + "--cache-dir", + str(tmp_path), + "--net", + "-r", + str(self.repos_dir / "network"), ] _net_results = [ (cls, result) for _name, cls in sorted(objects.CHECKS.items()) if issubclass(cls, NetworkCheck) - for result in sorted(cls.known_results, key=attrgetter('__name__')) + for result in sorted(cls.known_results, key=attrgetter("__name__")) ] def _render_results(self, results, **kwargs): @@ -50,34 +54,34 @@ class TestNetworkChecks: output = f.read().decode() return output - @pytest.mark.parametrize('check, result', _net_results) + @pytest.mark.parametrize("check, result", _net_results) def test_scan(self, check, result): check_name = check.__name__ keyword = result.__name__ - result_dir = self.repos_dir / 'network' / check_name - paths = tuple(result_dir.glob(keyword + '*')) + result_dir = self.repos_dir / "network" / check_name + paths = tuple(result_dir.glob(keyword + "*")) if not paths: - pytest.skip('data unavailable') + pytest.skip("data unavailable") for path in paths: ebuild_name = os.path.basename(path) - data_dir = self.repos_data / 'network' / check_name / ebuild_name + data_dir = self.repos_data / "network" / check_name / ebuild_name # load response data to fake - module_path = path / 'responses.py' - spec = importlib.util.spec_from_file_location('responses_mod', module_path) + module_path = path / "responses.py" + spec = importlib.util.spec_from_file_location("responses_mod", module_path) responses_mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(responses_mod) results = [] - args = ['-c', check_name, '-k', keyword, f'{check_name}/{ebuild_name}'] - with patch('pkgcheck.addons.net.requests.Session.send') as send: + args = ["-c", check_name, "-k", keyword, f"{check_name}/{ebuild_name}"] + with patch("pkgcheck.addons.net.requests.Session.send") as send: send.side_effect = responses_mod.responses # load expected results if they exist try: - with (data_dir / 'expected.json').open() as f: + with (data_dir / "expected.json").open() as f: expected_results = set(reporters.JsonStream.from_iter(f)) except FileNotFoundError: # check stopped before making request or completed successfully @@ -85,37 +89,42 @@ class TestNetworkChecks: results = list(self.scan(self.scan_args + args)) rendered_results = self._render_results(results) - assert rendered_results, 'failed rendering results' + assert rendered_results, "failed rendering results" if set(results) != expected_results: - error = ['unmatched results:'] + error = ["unmatched results:"] expected = self._render_results(expected_results) - error.append(f'expected:\n{expected}') - error.append(f'got:\n{rendered_results}') - pytest.fail('\n'.join(error)) - - @pytest.mark.parametrize('check, result', ( - (HomepageUrlCheck, DeadUrl), - (FetchablesUrlCheck, DeadUrl), - )) + error.append(f"expected:\n{expected}") + error.append(f"got:\n{rendered_results}") + pytest.fail("\n".join(error)) + + @pytest.mark.parametrize( + "check, result", + ( + (HomepageUrlCheck, DeadUrl), + (FetchablesUrlCheck, DeadUrl), + ), + ) def test_scan_ftp(self, check, result): check_name = check.__name__ keyword = result.__name__ - pkg = RawCPV(check_name, f'ftp-{keyword}', '0') - if check_name == 'HomepageUrlCheck': - deadurl = DeadUrl('HOMEPAGE', 'ftp://pkgcheck.net/pkgcheck/', 'dead ftp', pkg=pkg) + pkg = RawCPV(check_name, f"ftp-{keyword}", "0") + if check_name == "HomepageUrlCheck": + deadurl = DeadUrl("HOMEPAGE", "ftp://pkgcheck.net/pkgcheck/", "dead ftp", pkg=pkg) else: - deadurl = DeadUrl('SRC_URI', 'ftp://pkgcheck.net/pkgcheck/foo.tar.gz', 'dead ftp', pkg=pkg) + deadurl = DeadUrl( + "SRC_URI", "ftp://pkgcheck.net/pkgcheck/foo.tar.gz", "dead ftp", pkg=pkg + ) data = ( - (urllib.error.URLError('dead ftp'), deadurl), - (socket.timeout('dead ftp'), deadurl), + (urllib.error.URLError("dead ftp"), deadurl), + (socket.timeout("dead ftp"), deadurl), (None, None), # faking a clean connection ) - args = ['-c', check_name, '-k', keyword, f'{check_name}/ftp-{keyword}'] + args = ["-c", check_name, "-k", keyword, f"{check_name}/ftp-{keyword}"] for side_effect, expected_result in data: - with patch('pkgcheck.checks.network.urllib.request.urlopen') as urlopen: + with patch("pkgcheck.checks.network.urllib.request.urlopen") as urlopen: if side_effect is not None: urlopen.side_effect = side_effect results = list(self.scan(self.scan_args + args)) @@ -123,4 +132,4 @@ class TestNetworkChecks: assert not results else: assert results == [expected_result] - assert self._render_results(results), 'failed rendering results' + assert self._render_results(results), "failed rendering results" diff --git a/tests/checks/test_perl.py b/tests/checks/test_perl.py index b9c25578..1b26e412 100644 --- a/tests/checks/test_perl.py +++ b/tests/checks/test_perl.py @@ -6,7 +6,7 @@ from snakeoil.cli import arghparse from .. import misc -REASON = '' +REASON = "" def perl_deps_missing(): @@ -28,49 +28,49 @@ class TestPerlCheck(misc.ReportTestCase): def mk_check(self, verbosity=0): return self.check_kls(arghparse.Namespace(verbosity=verbosity)) - def mk_pkg(self, PVR, dist_version='', eclasses=('perl-module',), **kwargs): - lines = ['inherit perl-module\n'] + def mk_pkg(self, PVR, dist_version="", eclasses=("perl-module",), **kwargs): + lines = ["inherit perl-module\n"] if dist_version: - lines.append(f'DIST_VERSION={dist_version}\n') - kwargs.setdefault('EAPI', '7') - kwargs.setdefault('_eclasses_', list(eclasses)) - return misc.FakePkg(f'app-foo/bar-{PVR}', lines=lines, data=kwargs) + lines.append(f"DIST_VERSION={dist_version}\n") + kwargs.setdefault("EAPI", "7") + kwargs.setdefault("_eclasses_", list(eclasses)) + return misc.FakePkg(f"app-foo/bar-{PVR}", lines=lines, data=kwargs) def test_matching(self): """Ebuilds with matching DIST_VERSION and package version.""" - for PVR in ('1.7.0-r0', '1.7.0', '1.7.0-r100'): - self.assertNoReport(self.mk_check(), self.mk_pkg(PVR, '1.007')) + for PVR in ("1.7.0-r0", "1.7.0", "1.7.0-r100"): + self.assertNoReport(self.mk_check(), self.mk_pkg(PVR, "1.007")) def test_nonmatching(self): """Ebuilds without matching DIST_VERSION and package version.""" - for PVR in ('1.7.0-r0', '1.7.0', '1.7.0-r100'): - r = self.assertReport(self.mk_check(), self.mk_pkg(PVR, '1.07')) + for PVR in ("1.7.0-r0", "1.7.0", "1.7.0-r100"): + r = self.assertReport(self.mk_check(), self.mk_pkg(PVR, "1.07")) assert isinstance(r, perl.MismatchedPerlVersion) - assert r.dist_version == '1.07' - assert r.normalized == '1.70.0' - assert 'DIST_VERSION=1.07 normalizes to 1.70.0' in str(r) - r = self.assertReport(self.mk_check(), self.mk_pkg(PVR, '1.7')) + assert r.dist_version == "1.07" + assert r.normalized == "1.70.0" + assert "DIST_VERSION=1.07 normalizes to 1.70.0" in str(r) + r = self.assertReport(self.mk_check(), self.mk_pkg(PVR, "1.7")) assert isinstance(r, perl.MismatchedPerlVersion) - assert r.dist_version == '1.7' - assert r.normalized == '1.700.0' - assert 'DIST_VERSION=1.7 normalizes to 1.700.0' in str(r) + assert r.dist_version == "1.7" + assert r.normalized == "1.700.0" + assert "DIST_VERSION=1.7 normalizes to 1.700.0" in str(r) def test_no_dist_version(self): """Ebuilds without DIST_VERSION defined are skipped.""" - self.assertNoReport(self.mk_check(), self.mk_pkg('1.7.0')) + self.assertNoReport(self.mk_check(), self.mk_pkg("1.7.0")) def test_no_perl(self): """Check initialization fails if perl isn't installed.""" - with patch('subprocess.Popen') as popen: - popen.side_effect = FileNotFoundError('perl not available') - with pytest.raises(SkipCheck, match='perl not installed'): + with patch("subprocess.Popen") as popen: + popen.side_effect = FileNotFoundError("perl not available") + with pytest.raises(SkipCheck, match="perl not installed"): self.mk_check() def test_no_perl_deps(self): """Check initialization fails if perl deps aren't installed.""" - with patch('pkgcheck.checks.perl.subprocess.Popen') as popen: - popen.return_value.stdout.readline.return_value = 'perl error' + with patch("pkgcheck.checks.perl.subprocess.Popen") as popen: + popen.return_value.stdout.readline.return_value = "perl error" popen.return_value.poll.return_value = 2 for verbosity in (0, 1): - with pytest.raises(SkipCheck, match='failed to run perl script'): + with pytest.raises(SkipCheck, match="failed to run perl script"): self.mk_check(verbosity=verbosity) diff --git a/tests/checks/test_pkgdir.py b/tests/checks/test_pkgdir.py index 1fc01b01..2a26e79c 100644 --- a/tests/checks/test_pkgdir.py +++ b/tests/checks/test_pkgdir.py @@ -21,33 +21,34 @@ class PkgDirCheckBase(misc.ReportTestCase): @pytest.fixture(autouse=True) def _create_repo(self, tmpdir): - self.repo = FakeRepo(repo_id='repo', location=str(tmpdir)) + self.repo = FakeRepo(repo_id="repo", location=str(tmpdir)) def mk_check(self, gentoo=False): options = arghparse.Namespace( - target_repo=self.repo, cache={'git': False}, gentoo_repo=gentoo) + target_repo=self.repo, cache={"git": False}, gentoo_repo=gentoo + ) kwargs = {} if addons.git.GitAddon in self.check_kls.required_addons: - kwargs['git_addon'] = addons.git.GitAddon(options) + kwargs["git_addon"] = addons.git.GitAddon(options) return self.check_kls(options, **kwargs) - def mk_pkg(self, files={}, category=None, package=None, version='0.7.1', revision=''): + def mk_pkg(self, files={}, category=None, package=None, version="0.7.1", revision=""): # generate random cat/PN category = misc.random_str() if category is None else category package = misc.random_str() if package is None else package pkg = f"{category}/{package}-{version}{revision}" - self.filesdir = pjoin(self.repo.location, category, package, 'files') + self.filesdir = pjoin(self.repo.location, category, package, "files") # create files dir with random empty subdir os.makedirs(pjoin(self.filesdir, misc.random_str()), exist_ok=True) # create dirs that should be ignored - for d in getattr(self.check_kls, 'ignore_dirs', ()): + for d in getattr(self.check_kls, "ignore_dirs", ()): os.makedirs(pjoin(self.filesdir, d), exist_ok=True) # create specified files in FILESDIR for fn, contents in files.items(): - with open(pjoin(self.filesdir, fn), 'w') as file: + with open(pjoin(self.filesdir, fn), "w") as file: file.write(contents) return misc.FakeFilesDirPkg(pkg, repo=self.repo) @@ -64,24 +65,30 @@ class TestDuplicateFiles(PkgDirCheckBase): """Check DuplicateFiles results.""" def test_unique_files(self): - self.assertNoReport(self.mk_check(), [self.mk_pkg({'test': 'abc', 'test2': 'bcd'})]) + self.assertNoReport(self.mk_check(), [self.mk_pkg({"test": "abc", "test2": "bcd"})]) def test_single_duplicate(self): - pkg = self.mk_pkg({'test': 'abc', 'test2': 'abc'}) + pkg = self.mk_pkg({"test": "abc", "test2": "abc"}) r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.DuplicateFiles) - assert r.files == ('files/test', 'files/test2') + assert r.files == ("files/test", "files/test2") assert "'files/test', 'files/test2'" in str(r) def test_multiple_duplicates(self): - r = self.assertReports(self.mk_check(), [self.mk_pkg( - {'test': 'abc', 'test2': 'abc', 'test3': 'bcd', 'test4': 'bcd', 'test5': 'zzz'})]) + r = self.assertReports( + self.mk_check(), + [ + self.mk_pkg( + {"test": "abc", "test2": "abc", "test3": "bcd", "test4": "bcd", "test5": "zzz"} + ) + ], + ) assert len(r) == 2 assert isinstance(r[0], pkgdir.DuplicateFiles) assert isinstance(r[1], pkgdir.DuplicateFiles) - assert ( - tuple(sorted(x.files for x in r)) == - (('files/test', 'files/test2'), ('files/test3', 'files/test4')) + assert tuple(sorted(x.files for x in r)) == ( + ("files/test", "files/test2"), + ("files/test3", "files/test4"), ) @@ -89,29 +96,29 @@ class TestEmptyFile(PkgDirCheckBase): """Check EmptyFile results.""" def test_nonempty_file(self): - self.assertNoReport(self.mk_check(), [self.mk_pkg({'test': 'asdfgh'})]) + self.assertNoReport(self.mk_check(), [self.mk_pkg({"test": "asdfgh"})]) def test_single_empty_file(self): assert isinstance( - self.assertReport(self.mk_check(), [self.mk_pkg({'test': ''})]), - pkgdir.EmptyFile) + self.assertReport(self.mk_check(), [self.mk_pkg({"test": ""})]), pkgdir.EmptyFile + ) def test_multiple_empty_files(self): - r = self.assertReports(self.mk_check(), [self.mk_pkg({'test': '', 'test2': ''})]) + r = self.assertReports(self.mk_check(), [self.mk_pkg({"test": "", "test2": ""})]) assert len(r) == 2 assert isinstance(r[0], pkgdir.EmptyFile) assert isinstance(r[1], pkgdir.EmptyFile) - assert sorted(x.filename for x in r) == ['files/test', 'files/test2'] + assert sorted(x.filename for x in r) == ["files/test", "files/test2"] def test_mixture_of_files(self): - r = self.assertReport(self.mk_check(), [self.mk_pkg({'test': 'asdfgh', 'test2': ''})]) + r = self.assertReport(self.mk_check(), [self.mk_pkg({"test": "asdfgh", "test2": ""})]) assert isinstance(r, pkgdir.EmptyFile) - assert r.filename == 'files/test2' - assert 'files/test2' in str(r) - r = self.assertReport(self.mk_check(), [self.mk_pkg({'test': '', 'test2': 'asdfgh'})]) + assert r.filename == "files/test2" + assert "files/test2" in str(r) + r = self.assertReport(self.mk_check(), [self.mk_pkg({"test": "", "test2": "asdfgh"})]) assert isinstance(r, pkgdir.EmptyFile) - assert r.filename == 'files/test' - assert 'files/test' in str(r) + assert r.filename == "files/test" + assert "files/test" in str(r) class TestMismatchedPN(PkgDirCheckBase): @@ -119,29 +126,29 @@ class TestMismatchedPN(PkgDirCheckBase): def test_multiple_regular_ebuilds(self): pkg = self.mk_pkg() - touch(pjoin(os.path.dirname(pkg.path), f'{pkg.package}-0.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), f'{pkg.package}-1.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), f'{pkg.package}-2.ebuild')) + touch(pjoin(os.path.dirname(pkg.path), f"{pkg.package}-0.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), f"{pkg.package}-1.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), f"{pkg.package}-2.ebuild")) self.assertNoReport(self.mk_check(), [pkg]) def test_single_mismatched_ebuild(self): pkg = self.mk_pkg() - touch(pjoin(os.path.dirname(pkg.path), 'mismatched-0.ebuild')) + touch(pjoin(os.path.dirname(pkg.path), "mismatched-0.ebuild")) r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.MismatchedPN) - assert r.ebuilds == ('mismatched-0',) - assert 'mismatched-0' in str(r) + assert r.ebuilds == ("mismatched-0",) + assert "mismatched-0" in str(r) def test_multiple_mismatched_ebuilds(self): pkg = self.mk_pkg() - touch(pjoin(os.path.dirname(pkg.path), f'{pkg.package}-0.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), f'{pkg.package}-1.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), 'mismatched-0.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), 'abc-1.ebuild')) + touch(pjoin(os.path.dirname(pkg.path), f"{pkg.package}-0.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), f"{pkg.package}-1.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), "mismatched-0.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), "abc-1.ebuild")) r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.MismatchedPN) - assert r.ebuilds == ('abc-1', 'mismatched-0') - assert 'abc-1, mismatched-0' in str(r) + assert r.ebuilds == ("abc-1", "mismatched-0") + assert "abc-1, mismatched-0" in str(r) class TestInvalidPN(PkgDirCheckBase): @@ -149,27 +156,27 @@ class TestInvalidPN(PkgDirCheckBase): def test_regular_ebuild(self): pkg = self.mk_pkg() - touch(pjoin(os.path.dirname(pkg.path), f'{pkg.package}-0.ebuild')) + touch(pjoin(os.path.dirname(pkg.path), f"{pkg.package}-0.ebuild")) self.assertNoReport(self.mk_check(), [pkg]) def test_single_invalid_ebuild(self): - pkg = self.mk_pkg(category='sys-apps', package='invalid') - touch(pjoin(os.path.dirname(pkg.path), 'invalid-0-foo.ebuild')) + pkg = self.mk_pkg(category="sys-apps", package="invalid") + touch(pjoin(os.path.dirname(pkg.path), "invalid-0-foo.ebuild")) r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.InvalidPN) - assert r.ebuilds == ('invalid-0-foo',) - assert 'invalid-0-foo' in str(r) + assert r.ebuilds == ("invalid-0-foo",) + assert "invalid-0-foo" in str(r) def test_multiple_invalid_ebuilds(self): - pkg = self.mk_pkg(category='sys-apps', package='bar') - touch(pjoin(os.path.dirname(pkg.path), 'bar-0.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), 'bar-1.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), 'bar-0-foo1.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), 'bar-1-foo2.ebuild')) + pkg = self.mk_pkg(category="sys-apps", package="bar") + touch(pjoin(os.path.dirname(pkg.path), "bar-0.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), "bar-1.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), "bar-0-foo1.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), "bar-1-foo2.ebuild")) r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.InvalidPN) - assert r.ebuilds == ('bar-0-foo1', 'bar-1-foo2') - assert 'bar-0-foo1, bar-1-foo2' in str(r) + assert r.ebuilds == ("bar-0-foo1", "bar-1-foo2") + assert "bar-0-foo1, bar-1-foo2" in str(r) class TestInvalidUTF8(PkgDirCheckBase): @@ -177,26 +184,26 @@ class TestInvalidUTF8(PkgDirCheckBase): def test_ascii_ebuild(self): pkg = self.mk_pkg() - ebuild_path = pjoin(os.path.dirname(pkg.path), f'{pkg.package}-0.ebuild') - with open(ebuild_path, 'w', encoding='ascii') as f: + ebuild_path = pjoin(os.path.dirname(pkg.path), f"{pkg.package}-0.ebuild") + with open(ebuild_path, "w", encoding="ascii") as f: f.write('EAPI=7\nDESCRIPTION="foobar"\n') self.assertNoReport(self.mk_check(), [pkg]) def test_utf8_ebuild(self): pkg = self.mk_pkg() - ebuild_path = pjoin(os.path.dirname(pkg.path), f'{pkg.package}-0.ebuild') - with open(ebuild_path, 'w') as f: + ebuild_path = pjoin(os.path.dirname(pkg.path), f"{pkg.package}-0.ebuild") + with open(ebuild_path, "w") as f: f.write('EAPI=6\nDESCRIPTION="fóóbár"\n') self.assertNoReport(self.mk_check(), [pkg]) def test_latin1_ebuild(self): pkg = self.mk_pkg() - ebuild_path = pjoin(os.path.dirname(pkg.path), f'{pkg.package}-0.ebuild') - with open(ebuild_path, 'w', encoding='latin-1') as f: + ebuild_path = pjoin(os.path.dirname(pkg.path), f"{pkg.package}-0.ebuild") + with open(ebuild_path, "w", encoding="latin-1") as f: f.write('EAPI=5\nDESCRIPTION="fôòbår"\n') r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.InvalidUTF8) - assert r.filename == f'{pkg.package}-0.ebuild' + assert r.filename == f"{pkg.package}-0.ebuild" assert r.filename in str(r) @@ -207,44 +214,48 @@ class TestEqualVersions(PkgDirCheckBase): def test_it(self): # pkg with no revision - pkg_a = self.mk_pkg(version='0') + pkg_a = self.mk_pkg(version="0") self.assertNoReport(self.mk_check(), [pkg_a]) # single, matching revision pkg_b = self.mk_pkg( - category=pkg_a.category, package=pkg_a.package, version='0', revision='-r0') + category=pkg_a.category, package=pkg_a.package, version="0", revision="-r0" + ) r = self.assertReport(self.mk_check(), [pkg_a, pkg_b]) assert isinstance(r, pkgdir.EqualVersions) - assert r.versions == ('0', '0-r0') - assert '[ 0, 0-r0 ]' in str(r) + assert r.versions == ("0", "0-r0") + assert "[ 0, 0-r0 ]" in str(r) # multiple, matching revisions pkg_c = self.mk_pkg( - category=pkg_a.category, package=pkg_a.package, version='0', revision='-r000') + category=pkg_a.category, package=pkg_a.package, version="0", revision="-r000" + ) r = self.assertReport(self.mk_check(), [pkg_a, pkg_b, pkg_c]) assert isinstance(r, pkgdir.EqualVersions) - assert r.versions == ('0', '0-r0', '0-r000') - assert '[ 0, 0-r0, 0-r000 ]' in str(r) + assert r.versions == ("0", "0-r0", "0-r000") + assert "[ 0, 0-r0, 0-r000 ]" in str(r) # unsorted, matching revisions - pkg_new_version = self.mk_pkg( - category=pkg_a.category, package=pkg_a.package, version='1') + pkg_new_version = self.mk_pkg(category=pkg_a.category, package=pkg_a.package, version="1") r = self.assertReport(self.mk_check(), [pkg_b, pkg_new_version, pkg_c, pkg_a]) assert isinstance(r, pkgdir.EqualVersions) - assert r.versions == ('0', '0-r0', '0-r000') - assert '[ 0, 0-r0, 0-r000 ]' in str(r) + assert r.versions == ("0", "0-r0", "0-r000") + assert "[ 0, 0-r0, 0-r000 ]" in str(r) # multiple, matching revisions with 0 prefixes pkg_d = self.mk_pkg( - category=pkg_a.category, package=pkg_a.package, version='0', revision='-r1') + category=pkg_a.category, package=pkg_a.package, version="0", revision="-r1" + ) pkg_e = self.mk_pkg( - category=pkg_a.category, package=pkg_a.package, version='0', revision='-r01') + category=pkg_a.category, package=pkg_a.package, version="0", revision="-r01" + ) pkg_f = self.mk_pkg( - category=pkg_a.category, package=pkg_a.package, version='0', revision='-r001') + category=pkg_a.category, package=pkg_a.package, version="0", revision="-r001" + ) r = self.assertReport(self.mk_check(), [pkg_d, pkg_e, pkg_f]) assert isinstance(r, pkgdir.EqualVersions) - assert r.versions == ('0-r001', '0-r01', '0-r1') - assert '[ 0-r001, 0-r01, 0-r1 ]' in str(r) + assert r.versions == ("0-r001", "0-r01", "0-r1") + assert "[ 0-r001, 0-r01, 0-r1 ]" in str(r) class TestSizeViolation(PkgDirCheckBase): @@ -252,50 +263,51 @@ class TestSizeViolation(PkgDirCheckBase): def test_files_under_size_limit(self): pkg = self.mk_pkg() - for name, size in (('small', 1024*10), - ('limit', 1024*20-1)): - with open(pjoin(self.filesdir, name), 'w') as f: + for name, size in (("small", 1024 * 10), ("limit", 1024 * 20 - 1)): + with open(pjoin(self.filesdir, name), "w") as f: f.seek(size) - f.write('\0') + f.write("\0") self.assertNoReport(self.mk_check(), [pkg]) def test_single_file_over_limit(self): pkg = self.mk_pkg() - with open(pjoin(self.filesdir, 'over'), 'w') as f: - f.seek(1024*20) - f.write('\0') + with open(pjoin(self.filesdir, "over"), "w") as f: + f.seek(1024 * 20) + f.write("\0") r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.SizeViolation) - assert r.filename == 'files/over' - assert r.size == 1024*20+1 - assert 'files/over' in str(r) + assert r.filename == "files/over" + assert r.size == 1024 * 20 + 1 + assert "files/over" in str(r) def test_multiple_files_over_limit(self): pkg = self.mk_pkg() - for name, size in (('small', 1024*10), - ('limit', 1024*20-1), - ('over', 1024*20), - ('massive', 1024*100)): - with open(pjoin(self.filesdir, name), 'w') as f: + for name, size in ( + ("small", 1024 * 10), + ("limit", 1024 * 20 - 1), + ("over", 1024 * 20), + ("massive", 1024 * 100), + ): + with open(pjoin(self.filesdir, name), "w") as f: f.seek(size) - f.write('\0') + f.write("\0") r = self.assertReports(self.mk_check(), [pkg]) assert len(r) == 3 assert isinstance(r[0], pkgdir.SizeViolation) assert isinstance(r[1], pkgdir.SizeViolation) assert isinstance(r[2], pkgdir.TotalSizeViolation) - assert ( - tuple(sorted((x.filename, x.size) for x in r[:2])) == - (('files/massive', 1024*100+1), ('files/over', 1024*20+1)) + assert tuple(sorted((x.filename, x.size) for x in r[:2])) == ( + ("files/massive", 1024 * 100 + 1), + ("files/over", 1024 * 20 + 1), ) - assert r[2].size == 1024*(10+20+20+100)+4-1 + assert r[2].size == 1024 * (10 + 20 + 20 + 100) + 4 - 1 class TestExecutableFile(PkgDirCheckBase): """Check ExecutableFile results.""" def test_non_empty_filesdir(self): - self.assertNoReport(self.mk_check(), [self.mk_pkg({'test': 'asdfgh'})]) + self.assertNoReport(self.mk_check(), [self.mk_pkg({"test": "asdfgh"})]) def test_executable_ebuild(self): pkg = self.mk_pkg() @@ -307,54 +319,53 @@ class TestExecutableFile(PkgDirCheckBase): def test_executable_manifest_and_metadata(self): pkg = self.mk_pkg() - touch(pjoin(os.path.dirname(pkg.path), 'Manifest'), mode=0o755) - touch(pjoin(os.path.dirname(pkg.path), 'metadata.xml'), mode=0o744) + touch(pjoin(os.path.dirname(pkg.path), "Manifest"), mode=0o755) + touch(pjoin(os.path.dirname(pkg.path), "metadata.xml"), mode=0o744) r = self.assertReports(self.mk_check(), [pkg]) assert len(r) == 2 assert isinstance(r[0], pkgdir.ExecutableFile) assert isinstance(r[1], pkgdir.ExecutableFile) - assert ( - tuple(sorted(x.filename for x in r)) == - ('Manifest', 'metadata.xml') - ) + assert tuple(sorted(x.filename for x in r)) == ("Manifest", "metadata.xml") def test_executable_filesdir_file(self): - pkg = self.mk_pkg({'foo.init': 'blah'}) + pkg = self.mk_pkg({"foo.init": "blah"}) touch(pkg.path) - touch(pjoin(os.path.dirname(pkg.path), 'Manifest')) - touch(pjoin(os.path.dirname(pkg.path), 'metadata.xml')) - os.chmod(pjoin(os.path.dirname(pkg.path), 'files', 'foo.init'), 0o645) + touch(pjoin(os.path.dirname(pkg.path), "Manifest")) + touch(pjoin(os.path.dirname(pkg.path), "metadata.xml")) + os.chmod(pjoin(os.path.dirname(pkg.path), "files", "foo.init"), 0o645) r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.ExecutableFile) - assert r.filename == 'files/foo.init' - assert 'files/foo.init' in str(r) + assert r.filename == "files/foo.init" + assert "files/foo.init" in str(r) class TestBannedCharacter(PkgDirCheckBase): """Check BannedCharacter results.""" def test_regular_files(self): - pkg = self.mk_pkg({'foo.init': 'blah'}) - touch(pjoin(os.path.dirname(pkg.path), 'Manifest')) - touch(pjoin(os.path.dirname(pkg.path), 'metadata.xml')) + pkg = self.mk_pkg({"foo.init": "blah"}) + touch(pjoin(os.path.dirname(pkg.path), "Manifest")) + touch(pjoin(os.path.dirname(pkg.path), "metadata.xml")) self.assertNoReport(self.mk_check(), [pkg]) def test_filenames_outside_allowed_charsets(self): - pkg = self.mk_pkg({ - 'foo.init': 'bar', - 'foo.init~': 'foo', - }) + pkg = self.mk_pkg( + { + "foo.init": "bar", + "foo.init~": "foo", + } + ) # vim backup files are flagged by default r = self.assertReport(self.mk_check(), [pkg]) assert isinstance(r, pkgdir.BannedCharacter) - assert 'files/foo.init~' in str(r) + assert "files/foo.init~" in str(r) # but results are suppressed if a matching git ignore entry exists - for ignore_file in ('.gitignore', '.git/info/exclude'): + for ignore_file in (".gitignore", ".git/info/exclude"): path = pjoin(self.repo.location, ignore_file) ensure_dirs(os.path.dirname(path)) - with open(path, 'w') as f: - f.write('*~') + with open(path, "w") as f: + f.write("*~") self.assertNoReport(self.mk_check(), [pkg]) os.unlink(path) @@ -363,40 +374,40 @@ class TestUnknownPkgDirEntry(PkgDirCheckBase): """Check UnknownPkgDirEntry results.""" def test_regular_files(self): - pkg = self.mk_pkg({'foo.init': 'blah'}) - touch(pjoin(os.path.dirname(pkg.path), 'Manifest')) - touch(pjoin(os.path.dirname(pkg.path), 'metadata.xml')) + pkg = self.mk_pkg({"foo.init": "blah"}) + touch(pjoin(os.path.dirname(pkg.path), "Manifest")) + touch(pjoin(os.path.dirname(pkg.path), "metadata.xml")) self.assertNoReport(self.mk_check(), [pkg]) def test_unknown_non_gentoo_repo(self): - pkg = self.mk_pkg({'foo.init': 'blah'}) - touch(pjoin(os.path.dirname(pkg.path), 'Manifest')) - touch(pjoin(os.path.dirname(pkg.path), 'metadata.xml')) - touch(pjoin(os.path.dirname(pkg.path), 'foo-2')) + pkg = self.mk_pkg({"foo.init": "blah"}) + touch(pjoin(os.path.dirname(pkg.path), "Manifest")) + touch(pjoin(os.path.dirname(pkg.path), "metadata.xml")) + touch(pjoin(os.path.dirname(pkg.path), "foo-2")) self.assertNoReport(self.mk_check(), [pkg]) def test_unknown_gentoo_repo(self): - pkg = self.mk_pkg({'foo.init': 'blah'}) - touch(pjoin(os.path.dirname(pkg.path), 'Manifest')) - touch(pjoin(os.path.dirname(pkg.path), 'metadata.xml')) - touch(pjoin(os.path.dirname(pkg.path), 'foo-2')) + pkg = self.mk_pkg({"foo.init": "blah"}) + touch(pjoin(os.path.dirname(pkg.path), "Manifest")) + touch(pjoin(os.path.dirname(pkg.path), "metadata.xml")) + touch(pjoin(os.path.dirname(pkg.path), "foo-2")) r = self.assertReport(self.mk_check(gentoo=True), [pkg]) assert isinstance(r, pkgdir.UnknownPkgDirEntry) - assert 'foo-2' in str(r) + assert "foo-2" in str(r) def test_unknown_gitignore(self): - pkg = self.mk_pkg(files={'foo.init': 'blah'}, category='dev-util', package='foo') - touch(pjoin(os.path.dirname(pkg.path), 'Manifest')) - touch(pjoin(os.path.dirname(pkg.path), 'metadata.xml')) - touch(pjoin(os.path.dirname(pkg.path), 'foo-0.ebuild')) - touch(pjoin(os.path.dirname(pkg.path), 'foo-0.ebuild.swp')) + pkg = self.mk_pkg(files={"foo.init": "blah"}, category="dev-util", package="foo") + touch(pjoin(os.path.dirname(pkg.path), "Manifest")) + touch(pjoin(os.path.dirname(pkg.path), "metadata.xml")) + touch(pjoin(os.path.dirname(pkg.path), "foo-0.ebuild")) + touch(pjoin(os.path.dirname(pkg.path), "foo-0.ebuild.swp")) r = self.assertReport(self.mk_check(gentoo=True), [pkg]) assert isinstance(r, pkgdir.UnknownPkgDirEntry) - assert 'foo-0.ebuild.swp' in str(r) + assert "foo-0.ebuild.swp" in str(r) # results are suppressed if a matching .gitignore entry exists - with open(pjoin(self.repo.location, '.gitignore'), 'w') as f: - f.write('*.swp') + with open(pjoin(self.repo.location, ".gitignore"), "w") as f: + f.write("*.swp") self.assertNoReport(self.mk_check(gentoo=True), [pkg]) @@ -411,17 +422,17 @@ class TestLiveOnlyCheck(misc.ReportTestCase): # initialize parent repo self.parent_git_repo = make_git_repo() - self.parent_repo = make_repo(self.parent_git_repo.path, repo_id='gentoo') - self.parent_git_repo.add_all('initial commit') + self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo") + self.parent_git_repo.add_all("initial commit") # create a stub pkg and commit it - self.parent_repo.create_ebuild('cat/pkg-0', properties='live') - self.parent_git_repo.add_all('cat/pkg-0') + self.parent_repo.create_ebuild("cat/pkg-0", properties="live") + self.parent_git_repo.add_all("cat/pkg-0") # initialize child repo self.child_git_repo = make_git_repo() - self.child_git_repo.run(['git', 'remote', 'add', 'origin', self.parent_git_repo.path]) - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + self.child_git_repo.run(["git", "remote", "add", "origin", self.parent_git_repo.path]) + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.child_repo = make_repo(self.child_git_repo.path) def init_check(self, options=None, future=0): @@ -434,45 +445,49 @@ class TestLiveOnlyCheck(misc.ReportTestCase): def _options(self, **kwargs): args = [ - 'scan', '-q', '--cache-dir', self.cache_dir, - '--repo', self.child_repo.location, + "scan", + "-q", + "--cache-dir", + self.cache_dir, + "--repo", + self.child_repo.location, ] options, _ = self._tool.parse_args(args) return options def test_no_git_support(self): options = self._options() - options.cache['git'] = False - with pytest.raises(SkipCheck, match='git cache support required'): + options.cache["git"] = False + with pytest.raises(SkipCheck, match="git cache support required"): self.init_check(options) def test_keywords_exist(self): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.child_git_repo.run(["git", "pull", "origin", "main"]) self.init_check() self.assertNoReport(self.check, self.source) def test_all_live_pkgs(self): - self.parent_repo.create_ebuild('cat/pkg-1', properties='live') - self.parent_git_repo.add_all('cat/pkg-1') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1", properties="live") + self.parent_git_repo.add_all("cat/pkg-1") + self.child_git_repo.run(["git", "pull", "origin", "main"]) self.init_check() # result will trigger for any package age - expected = pkgdir.LiveOnlyPackage(0, pkg=UnversionedCPV('cat/pkg')) + expected = pkgdir.LiveOnlyPackage(0, pkg=UnversionedCPV("cat/pkg")) r = self.assertReport(self.check, self.source) assert r == expected # packages are now a year old self.init_check(future=365) - expected = pkgdir.LiveOnlyPackage(365, pkg=UnversionedCPV('cat/pkg')) + expected = pkgdir.LiveOnlyPackage(365, pkg=UnversionedCPV("cat/pkg")) r = self.assertReport(self.check, self.source) assert r == expected def test_uncommitted_local_ebuild(self): - self.parent_repo.create_ebuild('cat/pkg-1', properties='live') - self.parent_git_repo.add_all('cat/pkg-1') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_repo.create_ebuild('cat/pkg-2', properties='live') + self.parent_repo.create_ebuild("cat/pkg-1", properties="live") + self.parent_git_repo.add_all("cat/pkg-1") + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_repo.create_ebuild("cat/pkg-2", properties="live") self.init_check(future=180) self.assertNoReport(self.check, self.source) diff --git a/tests/checks/test_python.py b/tests/checks/test_python.py index 843975b5..eb4c44fb 100644 --- a/tests/checks/test_python.py +++ b/tests/checks/test_python.py @@ -9,180 +9,201 @@ class TestPythonCheck(misc.ReportTestCase): check_kls = python.PythonCheck def mk_pkg(self, cpv="app-foo/bar-1", **kwargs): - kwargs.setdefault('EAPI', '7') + kwargs.setdefault("EAPI", "7") return misc.FakePkg(cpv, data=kwargs) def test_multiple_eclasses(self): r = self.assertReport( self.check, - self.mk_pkg(_eclasses_=['python-any-r1', 'python-single-r1'], - DEPEND='dev-lang/python')) + self.mk_pkg(_eclasses_=["python-any-r1", "python-single-r1"], DEPEND="dev-lang/python"), + ) assert isinstance(r, python.PythonEclassError) def test_missing_eclass_depend(self): self.assertNoReport( - self.check, - self.mk_pkg(_eclasses_=['python-any-r1'], DEPEND='dev-lang/python')) - self.assertNoReport(self.check, self.mk_pkg(DEPEND='dev-foo/frobnicate')) + self.check, self.mk_pkg(_eclasses_=["python-any-r1"], DEPEND="dev-lang/python") + ) + self.assertNoReport(self.check, self.mk_pkg(DEPEND="dev-foo/frobnicate")) - r = self.assertReport(self.check, self.mk_pkg(DEPEND='dev-lang/python')) + r = self.assertReport(self.check, self.mk_pkg(DEPEND="dev-lang/python")) assert isinstance(r, python.MissingPythonEclass) assert 'missing python-any-r1 eclass usage for DEPEND="dev-lang/python"' in str(r) - self.assertNoReport(self.check, self.mk_pkg(DEPEND='dev-lang/python:2.7')) + self.assertNoReport(self.check, self.mk_pkg(DEPEND="dev-lang/python:2.7")) assert isinstance( - self.assertReport(self.check, self.mk_pkg(DEPEND='dev-lang/python:*')), - python.MissingPythonEclass) + self.assertReport(self.check, self.mk_pkg(DEPEND="dev-lang/python:*")), + python.MissingPythonEclass, + ) assert isinstance( - self.assertReport(self.check, self.mk_pkg(DEPEND='=dev-lang/python-2*')), - python.MissingPythonEclass) + self.assertReport(self.check, self.mk_pkg(DEPEND="=dev-lang/python-2*")), + python.MissingPythonEclass, + ) assert isinstance( self.assertReport( - self.check, - self.mk_pkg(DEPEND='|| ( dev-lang/python:2.7 dev-lang/python:3.6 )')), - python.MissingPythonEclass) + self.check, self.mk_pkg(DEPEND="|| ( dev-lang/python:2.7 dev-lang/python:3.6 )") + ), + python.MissingPythonEclass, + ) def test_missing_eclass_bdepend(self): self.assertNoReport( - self.check, - self.mk_pkg(_eclasses_=['python-any-r1'], BDEPEND='dev-lang/python')) - self.assertNoReport(self.check, self.mk_pkg(BDEPEND='dev-foo/frobnicate')) + self.check, self.mk_pkg(_eclasses_=["python-any-r1"], BDEPEND="dev-lang/python") + ) + self.assertNoReport(self.check, self.mk_pkg(BDEPEND="dev-foo/frobnicate")) assert isinstance( - self.assertReport(self.check, self.mk_pkg(BDEPEND='dev-lang/python')), - python.MissingPythonEclass) - self.assertNoReport(self.check, self.mk_pkg(BDEPEND='dev-lang/python:2.7')) + self.assertReport(self.check, self.mk_pkg(BDEPEND="dev-lang/python")), + python.MissingPythonEclass, + ) + self.assertNoReport(self.check, self.mk_pkg(BDEPEND="dev-lang/python:2.7")) assert isinstance( - self.assertReport(self.check, self.mk_pkg(BDEPEND='dev-lang/python:*')), - python.MissingPythonEclass) + self.assertReport(self.check, self.mk_pkg(BDEPEND="dev-lang/python:*")), + python.MissingPythonEclass, + ) assert isinstance( - self.assertReport(self.check, self.mk_pkg(BDEPEND='=dev-lang/python-2*')), - python.MissingPythonEclass) + self.assertReport(self.check, self.mk_pkg(BDEPEND="=dev-lang/python-2*")), + python.MissingPythonEclass, + ) assert isinstance( self.assertReport( - self.check, - self.mk_pkg(BDEPEND='|| ( dev-lang/python:2.7 dev-lang/python:3.6 )')), - python.MissingPythonEclass) + self.check, self.mk_pkg(BDEPEND="|| ( dev-lang/python:2.7 dev-lang/python:3.6 )") + ), + python.MissingPythonEclass, + ) def test_missing_eclass_rdepend(self): self.assertNoReport( - self.check, - self.mk_pkg(_eclasses_=['python-r1'], RDEPEND='dev-lang/python:3.7')) + self.check, self.mk_pkg(_eclasses_=["python-r1"], RDEPEND="dev-lang/python:3.7") + ) self.assertNoReport( - self.check, - self.mk_pkg(_eclasses_=['python-single-r1'], RDEPEND='dev-lang/python:3.7')) - self.assertNoReport(self.check, self.mk_pkg(RDEPEND='dev-foo/frobnicate')) + self.check, self.mk_pkg(_eclasses_=["python-single-r1"], RDEPEND="dev-lang/python:3.7") + ) + self.assertNoReport(self.check, self.mk_pkg(RDEPEND="dev-foo/frobnicate")) - r = self.assertReport(self.check, self.mk_pkg(RDEPEND='dev-lang/python')) + r = self.assertReport(self.check, self.mk_pkg(RDEPEND="dev-lang/python")) assert isinstance(r, python.MissingPythonEclass) - assert 'missing python-r1 or python-single-r1 eclass' in str(r) + assert "missing python-r1 or python-single-r1 eclass" in str(r) - self.assertNoReport(self.check, self.mk_pkg(RDEPEND='dev-lang/python:2.7')) + self.assertNoReport(self.check, self.mk_pkg(RDEPEND="dev-lang/python:2.7")) assert isinstance( - self.assertReport(self.check, self.mk_pkg(RDEPEND='dev-lang/python:=')), - python.MissingPythonEclass) + self.assertReport(self.check, self.mk_pkg(RDEPEND="dev-lang/python:=")), + python.MissingPythonEclass, + ) assert isinstance( - self.assertReport(self.check, self.mk_pkg(RDEPEND='=dev-lang/python-2*')), - python.MissingPythonEclass) + self.assertReport(self.check, self.mk_pkg(RDEPEND="=dev-lang/python-2*")), + python.MissingPythonEclass, + ) assert isinstance( self.assertReport( - self.check, - self.mk_pkg(RDEPEND='|| ( dev-lang/python:2.7 dev-lang/python:3.6 )')), - python.MissingPythonEclass) + self.check, self.mk_pkg(RDEPEND="|| ( dev-lang/python:2.7 dev-lang/python:3.6 )") + ), + python.MissingPythonEclass, + ) def test_missing_eclass_pdepend(self): self.assertNoReport( - self.check, - self.mk_pkg(_eclasses_=['python-r1'], PDEPEND='dev-lang/python:3.7')) + self.check, self.mk_pkg(_eclasses_=["python-r1"], PDEPEND="dev-lang/python:3.7") + ) self.assertNoReport( - self.check, - self.mk_pkg(_eclasses_=['python-single-r1'], PDEPEND='dev-lang/python:3.7')) - self.assertNoReport(self.check, self.mk_pkg(PDEPEND='dev-foo/frobnicate')) + self.check, self.mk_pkg(_eclasses_=["python-single-r1"], PDEPEND="dev-lang/python:3.7") + ) + self.assertNoReport(self.check, self.mk_pkg(PDEPEND="dev-foo/frobnicate")) assert isinstance( - self.assertReport(self.check, self.mk_pkg(PDEPEND='dev-lang/python')), - python.MissingPythonEclass) - self.assertNoReport(self.check, self.mk_pkg(PDEPEND='dev-lang/python:2.7')) + self.assertReport(self.check, self.mk_pkg(PDEPEND="dev-lang/python")), + python.MissingPythonEclass, + ) + self.assertNoReport(self.check, self.mk_pkg(PDEPEND="dev-lang/python:2.7")) assert isinstance( - self.assertReport(self.check, self.mk_pkg(PDEPEND='dev-lang/python:=')), - python.MissingPythonEclass) + self.assertReport(self.check, self.mk_pkg(PDEPEND="dev-lang/python:=")), + python.MissingPythonEclass, + ) assert isinstance( - self.assertReport(self.check, self.mk_pkg(PDEPEND='=dev-lang/python-2*')), - python.MissingPythonEclass) + self.assertReport(self.check, self.mk_pkg(PDEPEND="=dev-lang/python-2*")), + python.MissingPythonEclass, + ) assert isinstance( self.assertReport( - self.check, - self.mk_pkg(PDEPEND='|| ( dev-lang/python:2.7 dev-lang/python:3.6 )')), - python.MissingPythonEclass) + self.check, self.mk_pkg(PDEPEND="|| ( dev-lang/python:2.7 dev-lang/python:3.6 )") + ), + python.MissingPythonEclass, + ) def test_valid_packages(self): self.assertNoReport( self.check, self.mk_pkg( - _eclasses_=['python-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6', - RDEPEND='python_targets_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_targets_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='|| ( python_targets_python3_5 ' - ' python_targets_python3_6 )')) + _eclasses_=["python-r1"], + IUSE="python_targets_python3_5 " "python_targets_python3_6", + RDEPEND="python_targets_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_targets_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="|| ( python_targets_python3_5 " " python_targets_python3_6 )", + ), + ) # python-single-r1 with one implementation does not use PST self.assertNoReport( self.check, - self.mk_pkg(_eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5', - RDEPEND='python_targets_python3_5? ( ' - ' dev-lang/python:3.5 )', - REQUIRED_USE='python_targets_python3_5')) + self.mk_pkg( + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5", + RDEPEND="python_targets_python3_5? ( " " dev-lang/python:3.5 )", + REQUIRED_USE="python_targets_python3_5", + ), + ) self.assertNoReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - RDEPEND='python_single_target_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_single_target_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='^^ ( python_single_target_python3_5 ' - ' python_single_target_python3_6 ) ' - 'python_single_target_python3_5? ( ' - ' python_targets_python3_5 ) ' - 'python_single_target_python3_6? ( ' - ' python_targets_python3_6 )')) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + RDEPEND="python_single_target_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_single_target_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="^^ ( python_single_target_python3_5 " + " python_single_target_python3_6 ) " + "python_single_target_python3_5? ( " + " python_targets_python3_5 ) " + "python_single_target_python3_6? ( " + " python_targets_python3_6 )", + ), + ) self.assertNoReport( self.check, - self.mk_pkg(_eclasses_=['python-any-r1'], - DEPEND='|| ( ' - ' dev-lang/python:3.5 ' - ' dev-lang/python:3.6 )')) + self.mk_pkg( + _eclasses_=["python-any-r1"], + DEPEND="|| ( " " dev-lang/python:3.5 " " dev-lang/python:3.6 )", + ), + ) self.assertNoReport( - self.check, - self.mk_pkg(_eclasses_=['python-any-r1'], DEPEND='dev-lang/python:3.5')) + self.check, self.mk_pkg(_eclasses_=["python-any-r1"], DEPEND="dev-lang/python:3.5") + ) self.assertNoReport( self.check, - self.mk_pkg(_eclasses_=['python-any-r1'], - BDEPEND='|| ( ' - ' dev-lang/python:3.5 ' - ' dev-lang/python:3.6 )')) + self.mk_pkg( + _eclasses_=["python-any-r1"], + BDEPEND="|| ( " " dev-lang/python:3.5 " " dev-lang/python:3.6 )", + ), + ) def test_missing_required_use(self): r = self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6', - RDEPEND='python_targets_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_targets_python3_6? ( ' - ' dev-lang/python:3.6 )')) + _eclasses_=["python-r1"], + IUSE="python_targets_python3_5 " "python_targets_python3_6", + RDEPEND="python_targets_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_targets_python3_6? ( " + " dev-lang/python:3.6 )", + ), + ) assert isinstance(r, python.PythonMissingRequiredUse) assert 'missing REQUIRED_USE="${PYTHON_REQUIRED_USE}"' in str(r) @@ -191,93 +212,105 @@ class TestPythonCheck(misc.ReportTestCase): self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6', - RDEPEND='python_targets_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_targets_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='|| ( python_targets_python3_5 )')), - python.PythonMissingRequiredUse) + _eclasses_=["python-r1"], + IUSE="python_targets_python3_5 " "python_targets_python3_6", + RDEPEND="python_targets_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_targets_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="|| ( python_targets_python3_5 )", + ), + ), + python.PythonMissingRequiredUse, + ) assert isinstance( self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_targets_python3_7', - RDEPEND='python_targets_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_targets_python3_6? ( ' - ' dev-lang/python:3.6 ) ' - 'python_targets_python3_7? ( ' - ' dev-lang/python:3.7 )', - REQUIRED_USE='|| ( python_targets_python3_6 ' - ' python_targets_python3_7 )')), - python.PythonMissingRequiredUse) + _eclasses_=["python-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_targets_python3_7", + RDEPEND="python_targets_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_targets_python3_6? ( " + " dev-lang/python:3.6 ) " + "python_targets_python3_7? ( " + " dev-lang/python:3.7 )", + REQUIRED_USE="|| ( python_targets_python3_6 " " python_targets_python3_7 )", + ), + ), + python.PythonMissingRequiredUse, + ) assert isinstance( self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - RDEPEND='python_single_target_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_single_target_python3_6? ( ' - ' dev-lang/python:3.6 )')), - python.PythonMissingRequiredUse) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + RDEPEND="python_single_target_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_single_target_python3_6? ( " + " dev-lang/python:3.6 )", + ), + ), + python.PythonMissingRequiredUse, + ) # incomplete REQUIRED_USE assert isinstance( self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - RDEPEND='python_single_target_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_single_target_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='^^ ( python_single_target_python3_5 )')), - python.PythonMissingRequiredUse) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + RDEPEND="python_single_target_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_single_target_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="^^ ( python_single_target_python3_5 )", + ), + ), + python.PythonMissingRequiredUse, + ) # || instead of ^^ in python-single-r1 assert isinstance( self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - RDEPEND='python_single_target_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_single_target_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='|| ( python_targets_python3_5 ' - ' python_targets_python3_6 )')), - python.PythonMissingRequiredUse) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + RDEPEND="python_single_target_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_single_target_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="|| ( python_targets_python3_5 " " python_targets_python3_6 )", + ), + ), + python.PythonMissingRequiredUse, + ) def test_missing_deps(self): r = self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6', - REQUIRED_USE='|| ( python_targets_python3_5 ' - ' python_targets_python3_6 )')) + _eclasses_=["python-r1"], + IUSE="python_targets_python3_5 " "python_targets_python3_6", + REQUIRED_USE="|| ( python_targets_python3_5 " " python_targets_python3_6 )", + ), + ) assert isinstance(r, python.PythonMissingDeps) assert 'missing RDEPEND="${PYTHON_DEPS}"' in str(r) @@ -285,13 +318,12 @@ class TestPythonCheck(misc.ReportTestCase): r = self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6', - RDEPEND='python_targets_python3_5? ( ' - ' dev-lang/python:3.5 )', - REQUIRED_USE='|| ( python_targets_python3_5 ' - ' python_targets_python3_6 )')) + _eclasses_=["python-r1"], + IUSE="python_targets_python3_5 " "python_targets_python3_6", + RDEPEND="python_targets_python3_5? ( " " dev-lang/python:3.5 )", + REQUIRED_USE="|| ( python_targets_python3_5 " " python_targets_python3_6 )", + ), + ) assert isinstance(r, python.PythonMissingDeps) assert 'missing RDEPEND="${PYTHON_DEPS}"' in str(r) @@ -301,69 +333,76 @@ class TestPythonCheck(misc.ReportTestCase): self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6', - RDEPEND='python_targets_python3_5? ( ' - ' dev-foo/bar ) ' - 'python_targets_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='|| ( python_targets_python3_5 ' - ' python_targets_python3_6 )')), - python.PythonMissingDeps) + _eclasses_=["python-r1"], + IUSE="python_targets_python3_5 " "python_targets_python3_6", + RDEPEND="python_targets_python3_5? ( " + " dev-foo/bar ) " + "python_targets_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="|| ( python_targets_python3_5 " " python_targets_python3_6 )", + ), + ), + python.PythonMissingDeps, + ) # DEPEND only, RDEPEND missing assert isinstance( self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6', - DEPEND='python_targets_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_targets_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='|| ( python_targets_python3_5 ' - ' python_targets_python3_6 )')), - python.PythonMissingDeps) + _eclasses_=["python-r1"], + IUSE="python_targets_python3_5 " "python_targets_python3_6", + DEPEND="python_targets_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_targets_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="|| ( python_targets_python3_5 " " python_targets_python3_6 )", + ), + ), + python.PythonMissingDeps, + ) assert isinstance( self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - REQUIRED_USE='^^ ( python_single_target_python3_5 ' - ' python_single_target_python3_6 ) ' - 'python_single_target_python3_5? ( ' - ' python_targets_python3_5 ) ' - 'python_single_target_python3_6? ( ' - ' python_targets_python3_6 )')), - python.PythonMissingDeps) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + REQUIRED_USE="^^ ( python_single_target_python3_5 " + " python_single_target_python3_6 ) " + "python_single_target_python3_5? ( " + " python_targets_python3_5 ) " + "python_single_target_python3_6? ( " + " python_targets_python3_6 )", + ), + ), + python.PythonMissingDeps, + ) # incomplete deps assert isinstance( self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - RDEPEND='python_single_target_python3_5? ( ' - ' dev-lang/python:3.5 )', - REQUIRED_USE='^^ ( python_single_target_python3_5 ' - ' python_single_target_python3_6 ) ' - 'python_single_target_python3_5? ( ' - ' python_targets_python3_5 ) ' - 'python_single_target_python3_6? ( ' - ' python_targets_python3_6 )')), - python.PythonMissingDeps) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + RDEPEND="python_single_target_python3_5? ( " " dev-lang/python:3.5 )", + REQUIRED_USE="^^ ( python_single_target_python3_5 " + " python_single_target_python3_6 ) " + "python_single_target_python3_5? ( " + " python_targets_python3_5 ) " + "python_single_target_python3_6? ( " + " python_targets_python3_6 )", + ), + ), + python.PythonMissingDeps, + ) # check that irrelevant dep with same USE conditional does not wrongly # satisfy the check @@ -371,44 +410,50 @@ class TestPythonCheck(misc.ReportTestCase): self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - RDEPEND='python_single_target_python3_5? ( ' - ' dev-foo/bar ) ' - 'python_single_target_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='^^ ( python_single_target_python3_5 ' - ' python_single_target_python3_6 ) ' - 'python_single_target_python3_5? ( ' - ' python_targets_python3_5 ) ' - 'python_single_target_python3_6? ( ' - ' python_targets_python3_6 )')), - python.PythonMissingDeps) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + RDEPEND="python_single_target_python3_5? ( " + " dev-foo/bar ) " + "python_single_target_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="^^ ( python_single_target_python3_5 " + " python_single_target_python3_6 ) " + "python_single_target_python3_5? ( " + " python_targets_python3_5 ) " + "python_single_target_python3_6? ( " + " python_targets_python3_6 )", + ), + ), + python.PythonMissingDeps, + ) # DEPEND only, RDEPEND missing assert isinstance( self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - DEPEND='python_single_target_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_single_target_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='^^ ( python_single_target_python3_5 ' - ' python_single_target_python3_6 ) ' - 'python_single_target_python3_5? ( ' - ' python_targets_python3_5 ) ' - 'python_single_target_python3_6? ( ' - ' python_targets_python3_6 )')), - python.PythonMissingDeps) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + DEPEND="python_single_target_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_single_target_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="^^ ( python_single_target_python3_5 " + " python_single_target_python3_6 ) " + "python_single_target_python3_5? ( " + " python_targets_python3_5 ) " + "python_single_target_python3_6? ( " + " python_targets_python3_6 )", + ), + ), + python.PythonMissingDeps, + ) # check that the check isn't wrongly satisfied by PYTHON_TARGETS # in python-single-r1 (PYTHON_SINGLE_TARGET expected) @@ -416,38 +461,40 @@ class TestPythonCheck(misc.ReportTestCase): self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-single-r1'], - IUSE='python_targets_python3_5 ' - 'python_targets_python3_6 ' - 'python_single_target_python3_5 ' - 'python_single_target_python3_6', - RDEPEND='python_targets_python3_5? ( ' - ' dev-lang/python:3.5 ) ' - 'python_targets_python3_6? ( ' - ' dev-lang/python:3.6 )', - REQUIRED_USE='^^ ( python_single_target_python3_5 ' - ' python_single_target_python3_6 ) ' - 'python_single_target_python3_5? ( ' - ' python_targets_python3_5 ) ' - 'python_single_target_python3_6? ( ' - ' python_targets_python3_6 )')), - python.PythonMissingDeps) + _eclasses_=["python-single-r1"], + IUSE="python_targets_python3_5 " + "python_targets_python3_6 " + "python_single_target_python3_5 " + "python_single_target_python3_6", + RDEPEND="python_targets_python3_5? ( " + " dev-lang/python:3.5 ) " + "python_targets_python3_6? ( " + " dev-lang/python:3.6 )", + REQUIRED_USE="^^ ( python_single_target_python3_5 " + " python_single_target_python3_6 ) " + "python_single_target_python3_5? ( " + " python_targets_python3_5 ) " + "python_single_target_python3_6? ( " + " python_targets_python3_6 )", + ), + ), + python.PythonMissingDeps, + ) assert isinstance( - self.assertReport(self.check, self.mk_pkg(_eclasses_=['python-any-r1'])), - python.PythonMissingDeps) + self.assertReport(self.check, self.mk_pkg(_eclasses_=["python-any-r1"])), + python.PythonMissingDeps, + ) def test_runtime_dep_in_any_r1(self): r = self.assertReport( self.check, self.mk_pkg( - _eclasses_=['python-any-r1'], - DEPEND='|| ( ' - ' dev-lang/python:3.5 ' - ' dev-lang/python:3.6 )', - RDEPEND='|| ( ' - ' dev-lang/python:3.5 ' - ' dev-lang/python:3.6 )')) + _eclasses_=["python-any-r1"], + DEPEND="|| ( " " dev-lang/python:3.5 " " dev-lang/python:3.6 )", + RDEPEND="|| ( " " dev-lang/python:3.5 " " dev-lang/python:3.6 )", + ), + ) assert isinstance(r, python.PythonRuntimeDepInAnyR1) assert 'inherits python-any-r1 with RDEPEND="dev-lang/python:3.5"' in str(r) @@ -455,6 +502,8 @@ class TestPythonCheck(misc.ReportTestCase): self.assertNoReport( self.check, self.mk_pkg( - _eclasses_=['python-any-r1'], - DEPEND='dev-lang/python:3.5', - RDEPEND='!dev-python/pypy3-bin:0')) + _eclasses_=["python-any-r1"], + DEPEND="dev-lang/python:3.5", + RDEPEND="!dev-python/pypy3-bin:0", + ), + ) diff --git a/tests/checks/test_repo.py b/tests/checks/test_repo.py index cd685a52..4220e055 100644 --- a/tests/checks/test_repo.py +++ b/tests/checks/test_repo.py @@ -17,15 +17,14 @@ class TestRepoDirCheck(misc.Tmpdir, misc.ReportTestCase): check_kls = repo.RepoDirCheck def mk_check(self): - self.repo = FakeRepo(repo_id='repo', location=self.dir) - options = arghparse.Namespace( - target_repo=self.repo, cache={'git': False}, gentoo_repo=True) + self.repo = FakeRepo(repo_id="repo", location=self.dir) + options = arghparse.Namespace(target_repo=self.repo, cache={"git": False}, gentoo_repo=True) git_addon = addons.git.GitAddon(options) return repo.RepoDirCheck(options, git_addon=git_addon) def mk_pkg(self, cpvstr): pkg = atom.atom(cpvstr) - filesdir = pjoin(self.repo.location, pkg.category, pkg.package, 'files') + filesdir = pjoin(self.repo.location, pkg.category, pkg.package, "files") os.makedirs(filesdir, exist_ok=True) return filesdir @@ -34,100 +33,100 @@ class TestRepoDirCheck(misc.Tmpdir, misc.ReportTestCase): def test_empty_file(self): check = self.mk_check() - bin_path = pjoin(self.repo.location, 'foo') + bin_path = pjoin(self.repo.location, "foo") touch(bin_path) self.assertNoReport(check, []) def test_regular_file(self): check = self.mk_check() - with open(pjoin(self.repo.location, 'foo'), 'w') as f: - f.write('bar') + with open(pjoin(self.repo.location, "foo"), "w") as f: + f.write("bar") self.assertNoReport(check, []) def test_unreadable_file(self): check = self.mk_check() - with open(pjoin(self.repo.location, 'foo'), 'w') as f: - f.write('bar') - with mock.patch('pkgcheck.open') as mocked_open: - mocked_open.side_effect = IOError('fake exception') + with open(pjoin(self.repo.location, "foo"), "w") as f: + f.write("bar") + with mock.patch("pkgcheck.open") as mocked_open: + mocked_open.side_effect = IOError("fake exception") self.assertNoReport(check, []) def test_ignored_root_dirs(self): for d in self.check_kls.ignored_root_dirs: check = self.mk_check() - bin_path = pjoin(self.repo.location, d, 'foo') + bin_path = pjoin(self.repo.location, d, "foo") os.makedirs(os.path.dirname(bin_path)) - with open(bin_path, 'wb') as f: - f.write(b'\xd3\xad\xbe\xef') + with open(bin_path, "wb") as f: + f.write(b"\xd3\xad\xbe\xef") self.assertNoReport(check, []) def test_null_bytes(self): check = self.mk_check() - with open(pjoin(self.repo.location, 'foo'), 'wb') as f: - f.write(b'foo\x00\xffbar') + with open(pjoin(self.repo.location, "foo"), "wb") as f: + f.write(b"foo\x00\xffbar") r = self.assertReport(check, []) assert isinstance(r, repo.BinaryFile) - assert r.path == 'foo' + assert r.path == "foo" assert "'foo'" in str(r) def test_root_dir_binary(self): check = self.mk_check() - bin_path = pjoin(self.repo.location, 'foo') - with open(bin_path, 'wb') as f: - f.write(b'\xd3\xad\xbe\xef') + bin_path = pjoin(self.repo.location, "foo") + with open(bin_path, "wb") as f: + f.write(b"\xd3\xad\xbe\xef") r = self.assertReport(check, []) assert isinstance(r, repo.BinaryFile) - assert r.path == 'foo' + assert r.path == "foo" assert "'foo'" in str(r) def test_ebuild_filesdir_binary(self): check = self.mk_check() - filesdir = self.mk_pkg('dev-util/foo') - with open(pjoin(filesdir, 'foo'), 'wb') as f: - f.write(b'\xd3\xad\xbe\xef') + filesdir = self.mk_pkg("dev-util/foo") + with open(pjoin(filesdir, "foo"), "wb") as f: + f.write(b"\xd3\xad\xbe\xef") r = self.assertReport(check, []) assert isinstance(r, repo.BinaryFile) - assert r.path == 'dev-util/foo/files/foo' + assert r.path == "dev-util/foo/files/foo" assert "'dev-util/foo/files/foo'" in str(r) def test_gitignore(self): # distfiles located in deprecated in-tree location are reported by default check = self.mk_check() - distfiles = pjoin(self.repo.location, 'distfiles') + distfiles = pjoin(self.repo.location, "distfiles") os.mkdir(distfiles) - with open(pjoin(distfiles, 'foo-0.tar.gz'), 'wb') as f: - f.write(b'\xd3\xad\xbe\xef') + with open(pjoin(distfiles, "foo-0.tar.gz"), "wb") as f: + f.write(b"\xd3\xad\xbe\xef") r = self.assertReport(check, []) assert isinstance(r, repo.BinaryFile) assert "distfiles/foo-0.tar.gz" in str(r) # but results are suppressed if a matching git ignore entry exists - for ignore_file in ('.gitignore', '.git/info/exclude'): + for ignore_file in (".gitignore", ".git/info/exclude"): path = pjoin(self.repo.location, ignore_file) ensure_dirs(os.path.dirname(path)) - with open(path, 'w') as f: - f.write('/distfiles/') + with open(path, "w") as f: + f.write("/distfiles/") self.assertNoReport(self.mk_check(), []) os.unlink(path) def test_non_utf8_encodings(self): # non-english languages courtesy of google translate mangling langs = ( - ("example text that shouldn't trigger", 'ascii'), - ('نص المثال الذي لا ينبغي أن يؤدي', 'cp1256'), # arabic - ('пример текста, который не должен срабатывать', 'koi8_r'), # russian - ('उदाहरण पाठ जो ट्रिगर नहीं होना चाहिए', 'utf-16'), # hindi - ('مثال کے متن جو ٹرگر نہ ہوں۔', 'utf-16'), # urdu - ('ဖြစ်ပေါ်မပေးသင့်ကြောင်းဥပမာစာသား', 'utf-32'), # burmese - ('उदाहरण पाठ जुन ट्रिगर हुँदैन', 'utf-32'), # nepali - ('トリガーするべきではないテキストの例', 'shift_jis'), # japanese - ('트리거해서는 안되는 예제 텍스트', 'cp949'), # korean - ('不应触发的示例文本', 'gb2312'), # simplified chinese - ('不應觸發的示例文本', 'gb18030'), # traditional chinese + ("example text that shouldn't trigger", "ascii"), + ("نص المثال الذي لا ينبغي أن يؤدي", "cp1256"), # arabic + ("пример текста, который не должен срабатывать", "koi8_r"), # russian + ("उदाहरण पाठ जो ट्रिगर नहीं होना चाहिए", "utf-16"), # hindi + ("مثال کے متن جو ٹرگر نہ ہوں۔", "utf-16"), # urdu + ("ဖြစ်ပေါ်မပေးသင့်ကြောင်းဥပမာစာသား", "utf-32"), # burmese + ("उदाहरण पाठ जुन ट्रिगर हुँदैन", "utf-32"), # nepali + ("トリガーするべきではないテキストの例", "shift_jis"), # japanese + ("트리거해서는 안되는 예제 텍스트", "cp949"), # korean + ("不应触发的示例文本", "gb2312"), # simplified chinese + ("不應觸發的示例文本", "gb18030"), # traditional chinese ) for text, encoding in langs: check = self.mk_check() - with open(pjoin(self.repo.location, 'foo'), 'wb') as f: + with open(pjoin(self.repo.location, "foo"), "wb") as f: data = text.encode(encoding) f.write(data) self.assertNoReport(check, []) diff --git a/tests/checks/test_repo_metadata.py b/tests/checks/test_repo_metadata.py index 2221e283..ff550d7d 100644 --- a/tests/checks/test_repo_metadata.py +++ b/tests/checks/test_repo_metadata.py @@ -16,24 +16,25 @@ class TestPackageUpdatesCheck(misc.Tmpdir, misc.ReportTestCase): def mk_check(self, pkgs=(), **kwargs): # TODO: switch to using a repo fixture when available repo_dir = pjoin(self.dir, misc.random_str()) - os.makedirs(pjoin(repo_dir, 'metadata')) - with open(pjoin(repo_dir, 'metadata', 'layout.conf'), 'w') as f: - f.write('masters =\n') + os.makedirs(pjoin(repo_dir, "metadata")) + with open(pjoin(repo_dir, "metadata", "layout.conf"), "w") as f: + f.write("masters =\n") - os.makedirs(pjoin(repo_dir, 'profiles', 'updates')) - with open(pjoin(repo_dir, 'profiles', 'repo_name'), 'w') as f: - f.write('fake\n') + os.makedirs(pjoin(repo_dir, "profiles", "updates")) + with open(pjoin(repo_dir, "profiles", "repo_name"), "w") as f: + f.write("fake\n") for filename, updates in kwargs.items(): - with open(pjoin(repo_dir, 'profiles', 'updates', filename), 'w') as f: - f.write('\n'.join(updates)) + with open(pjoin(repo_dir, "profiles", "updates", filename), "w") as f: + f.write("\n".join(updates)) for pkg in pkgs: pkg = FakePkg(pkg) pkg_path = pjoin( - repo_dir, pkg.category, pkg.package, f'{pkg.package}-{pkg.fullver}.ebuild') + repo_dir, pkg.category, pkg.package, f"{pkg.package}-{pkg.fullver}.ebuild" + ) os.makedirs(os.path.dirname(pkg_path), exist_ok=True) - with open(pkg_path, 'w') as f: - f.write('SLOT=0\n') + with open(pkg_path, "w") as f: + f.write("SLOT=0\n") repo = UnconfiguredTree(repo_dir) options = arghparse.Namespace(target_repo=repo, search_repo=repo) @@ -44,87 +45,91 @@ class TestPackageUpdatesCheck(misc.Tmpdir, misc.ReportTestCase): self.assertNoReport(self.mk_check(), []) # empty file - updates = {'1Q-2020': []} + updates = {"1Q-2020": []} self.assertNoReport(self.mk_check(**updates), []) def test_bad_update_filenames(self): # only files named using the format [1-4]Q-[YYYY] are allowed - updates = {'foobar': ['blah']} + updates = {"foobar": ["blah"]} r = self.assertReport(self.mk_check(**updates), []) assert isinstance(r, repo_metadata.BadPackageUpdate) assert "incorrectly named update file: 'foobar'" in str(r) - updates = {'5Q-2020': ['blah']} + updates = {"5Q-2020": ["blah"]} r = self.assertReport(self.mk_check(**updates), []) assert isinstance(r, repo_metadata.BadPackageUpdate) assert "incorrectly named update file: '5Q-2020'" in str(r) # hidden files will be flagged - updates = {'.1Q-2020.swp': ['blah']} + updates = {".1Q-2020.swp": ["blah"]} r = self.assertReport(self.mk_check(**updates), []) assert isinstance(r, repo_metadata.BadPackageUpdate) assert "incorrectly named update file: '.1Q-2020.swp'" in str(r) def test_empty_line(self): - updates = {'1Q-2020': [' ']} + updates = {"1Q-2020": [" "]} r = self.assertReport(self.mk_check(**updates), []) assert isinstance(r, repo_metadata.BadPackageUpdate) assert "file '1Q-2020': empty line 1" in str(r) def test_extra_whitespace(self): - pkgs = ('dev-util/foo-0', 'dev-util/bar-1') - for update in (' move dev-util/foo dev-util/bar', # prefix - 'move dev-util/foo dev-util/bar '): # suffix - updates = {'1Q-2020': [update]} + pkgs = ("dev-util/foo-0", "dev-util/bar-1") + for update in ( + " move dev-util/foo dev-util/bar", # prefix + "move dev-util/foo dev-util/bar ", + ): # suffix + updates = {"1Q-2020": [update]} r = self.assertReport(self.mk_check(pkgs=pkgs, **updates), []) assert isinstance(r, repo_metadata.BadPackageUpdate) - assert 'extra whitespace' in str(r) - assert 'on line 1' in str(r) + assert "extra whitespace" in str(r) + assert "on line 1" in str(r) def test_old_pkg_update(self): - pkgs = ('dev-util/blah-0', 'dev-libs/foon-1') - for update in ('move dev-util/foo dev-util/bar', # old pkg move - 'slotmove dev-util/bar 0 1'): # old slot move - updates = {'1Q-2020': [update]} + pkgs = ("dev-util/blah-0", "dev-libs/foon-1") + for update in ( + "move dev-util/foo dev-util/bar", # old pkg move + "slotmove dev-util/bar 0 1", + ): # old slot move + updates = {"1Q-2020": [update]} r = self.assertReport(self.mk_check(pkgs=pkgs, **updates), []) assert isinstance(r, repo_metadata.OldPackageUpdate) - assert r.pkg == 'dev-util/bar' + assert r.pkg == "dev-util/bar" assert "'dev-util/bar' unavailable" in str(r) def test_old_multimove_pkg_update(self): - update = ['move dev-util/foo dev-util/bar', 'move dev-util/bar dev-util/blah'] - pkgs = ('dev-util/blaz-0', 'dev-libs/foon-1') - updates = {'1Q-2020': update} + update = ["move dev-util/foo dev-util/bar", "move dev-util/bar dev-util/blah"] + pkgs = ("dev-util/blaz-0", "dev-libs/foon-1") + updates = {"1Q-2020": update} r = self.assertReport(self.mk_check(pkgs=pkgs, **updates), []) assert isinstance(r, repo_metadata.OldMultiMovePackageUpdate) - assert r.pkg == 'dev-util/blah' - assert r.moves == ('dev-util/foo', 'dev-util/bar', 'dev-util/blah') + assert r.pkg == "dev-util/blah" + assert r.moves == ("dev-util/foo", "dev-util/bar", "dev-util/blah") assert "'dev-util/blah' unavailable" in str(r) def test_multimove_pkg_update(self): - update = ['move dev-util/foo dev-util/bar', 'move dev-util/bar dev-util/blah'] - pkgs = ('dev-util/blah-0', 'dev-libs/foon-1') - updates = {'1Q-2020': update} + update = ["move dev-util/foo dev-util/bar", "move dev-util/bar dev-util/blah"] + pkgs = ("dev-util/blah-0", "dev-libs/foon-1") + updates = {"1Q-2020": update} r = self.assertReport(self.mk_check(pkgs=pkgs, **updates), []) assert isinstance(r, repo_metadata.MultiMovePackageUpdate) - assert r.pkg == 'dev-util/foo' - assert r.moves == ('dev-util/foo', 'dev-util/bar', 'dev-util/blah') + assert r.pkg == "dev-util/foo" + assert r.moves == ("dev-util/foo", "dev-util/bar", "dev-util/blah") assert "'dev-util/foo': multi-move update" in str(r) def test_move_to_self_pkg_update(self): - update = ['move dev-util/foo dev-util/foo'] - pkgs = ('dev-util/foo-0',) - updates = {'1Q-2020': update} + update = ["move dev-util/foo dev-util/foo"] + pkgs = ("dev-util/foo-0",) + updates = {"1Q-2020": update} r = self.assertReport(self.mk_check(pkgs=pkgs, **updates), []) assert isinstance(r, repo_metadata.RedundantPackageUpdate) - assert r.updates == ('move', 'dev-util/foo', 'dev-util/foo') + assert r.updates == ("move", "dev-util/foo", "dev-util/foo") assert "update line moves to the same package/slot" in str(r) def test_slot_move_to_self_pkg_update(self): - update = ['slotmove dev-util/foo 0 0'] - pkgs = ('dev-util/foo-0',) - updates = {'1Q-2020': update} + update = ["slotmove dev-util/foo 0 0"] + pkgs = ("dev-util/foo-0",) + updates = {"1Q-2020": update} r = self.assertReport(self.mk_check(pkgs=pkgs, **updates), []) assert isinstance(r, repo_metadata.RedundantPackageUpdate) - assert r.updates == ('slotmove', 'dev-util/foo', '0', '0') + assert r.updates == ("slotmove", "dev-util/foo", "0", "0") assert "update line moves to the same package/slot" in str(r) diff --git a/tests/checks/test_stablereq.py b/tests/checks/test_stablereq.py index b51bf9bc..2e181e57 100644 --- a/tests/checks/test_stablereq.py +++ b/tests/checks/test_stablereq.py @@ -21,17 +21,17 @@ class TestStableRequestCheck(ReportTestCase): # initialize parent repo self.parent_git_repo = make_git_repo() - self.parent_repo = make_repo(self.parent_git_repo.path, repo_id='gentoo') - self.parent_git_repo.add_all('initial commit') + self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo") + self.parent_git_repo.add_all("initial commit") # create a stub pkg and commit it - self.parent_repo.create_ebuild('cat/pkg-0') - self.parent_git_repo.add_all('cat/pkg-0') + self.parent_repo.create_ebuild("cat/pkg-0") + self.parent_git_repo.add_all("cat/pkg-0") # initialize child repo self.child_git_repo = make_git_repo() - self.child_git_repo.run(['git', 'remote', 'add', 'origin', self.parent_git_repo.path]) - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_git_repo.run(['git', 'remote', 'set-head', 'origin', 'main']) + self.child_git_repo.run(["git", "remote", "add", "origin", self.parent_git_repo.path]) + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_git_repo.run(["git", "remote", "set-head", "origin", "main"]) self.child_repo = make_repo(self.child_git_repo.path) def init_check(self, options=None, future=0, stable_time=None): @@ -44,50 +44,57 @@ class TestStableRequestCheck(ReportTestCase): def _options(self, stable_time=None, **kwargs): args = [ - 'scan', '-q', '--cache-dir', self.cache_dir, - '--repo', self.child_repo.location, + "scan", + "-q", + "--cache-dir", + self.cache_dir, + "--repo", + self.child_repo.location, ] if stable_time is not None: - args.extend(['--stabletime', str(stable_time)]) + args.extend(["--stabletime", str(stable_time)]) options, _ = self._tool.parse_args(args) return options def test_no_git_support(self): options = self._options() - options.cache['git'] = False - with pytest.raises(SkipCheck, match='git cache support required'): + options.cache["git"] = False + with pytest.raises(SkipCheck, match="git cache support required"): self.init_check(options) def test_no_stable_keywords(self): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.parent_repo.create_ebuild('cat/pkg-2', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg-2') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.parent_repo.create_ebuild("cat/pkg-2", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg-2") + self.child_git_repo.run(["git", "pull", "origin", "main"]) self.init_check() self.assertNoReport(self.check, self.source) def test_uncommitted_local_ebuild(self): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) - self.child_repo.create_ebuild('cat/pkg-2', keywords=['~amd64']) + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.child_git_repo.run(["git", "pull", "origin", "main"]) + self.child_repo.create_ebuild("cat/pkg-2", keywords=["~amd64"]) self.init_check(future=30) self.assertNoReport(self.check, self.source) - @pytest.mark.parametrize(("stable_time", "less_days", "more_days"), ( - pytest.param(None, (0, 1, 10, 20, 29), (30, 31), id="stable_time=unset"), - pytest.param(1, (0,), (1, 10), id="stable_time=1"), - pytest.param(14, (0, 1, 10, 13), (14, 15, 30), id="stable_time=14"), - pytest.param(30, (0, 1, 10, 20, 29), (30, 31), id="stable_time=30"), - pytest.param(100, (98, 99), (100, 101), id="stable_time=100"), - )) + @pytest.mark.parametrize( + ("stable_time", "less_days", "more_days"), + ( + pytest.param(None, (0, 1, 10, 20, 29), (30, 31), id="stable_time=unset"), + pytest.param(1, (0,), (1, 10), id="stable_time=1"), + pytest.param(14, (0, 1, 10, 13), (14, 15, 30), id="stable_time=14"), + pytest.param(30, (0, 1, 10, 20, 29), (30, 31), id="stable_time=30"), + pytest.param(100, (98, 99), (100, 101), id="stable_time=100"), + ), + ) def test_existing_stable_keywords(self, stable_time, less_days, more_days): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.parent_repo.create_ebuild('cat/pkg-2', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg-2') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.parent_repo.create_ebuild("cat/pkg-2", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg-2") + self.child_git_repo.run(["git", "pull", "origin", "main"]) # packages are not old enough to trigger any results for future in less_days: @@ -98,74 +105,74 @@ class TestStableRequestCheck(ReportTestCase): for future in more_days: self.init_check(future=future, stable_time=stable_time) r = self.assertReport(self.check, self.source) - expected = StableRequest('0', ['~amd64'], future, pkg=VersionedCPV('cat/pkg-2')) + expected = StableRequest("0", ["~amd64"], future, pkg=VersionedCPV("cat/pkg-2")) assert r == expected def test_multislot_with_unstable_slot(self): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.parent_repo.create_ebuild('cat/pkg-2', keywords=['~amd64'], slot='1') - self.parent_git_repo.add_all('cat/pkg-2') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.parent_repo.create_ebuild("cat/pkg-2", keywords=["~amd64"], slot="1") + self.parent_git_repo.add_all("cat/pkg-2") + self.child_git_repo.run(["git", "pull", "origin", "main"]) self.init_check(future=30) r = self.assertReport(self.check, self.source) - expected = StableRequest('1', ['~amd64'], 30, pkg=VersionedCPV('cat/pkg-2')) + expected = StableRequest("1", ["~amd64"], 30, pkg=VersionedCPV("cat/pkg-2")) assert r == expected def test_moved_category(self): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.parent_repo.create_ebuild('cat/pkg-2', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg-2') - self.parent_git_repo.move('cat', 'newcat') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.parent_repo.create_ebuild("cat/pkg-2", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg-2") + self.parent_git_repo.move("cat", "newcat") + self.child_git_repo.run(["git", "pull", "origin", "main"]) self.init_check(future=30) r = self.assertReport(self.check, self.source) - expected = StableRequest('0', ['~amd64'], 30, pkg=VersionedCPV('newcat/pkg-2')) + expected = StableRequest("0", ["~amd64"], 30, pkg=VersionedCPV("newcat/pkg-2")) assert r == expected def test_moved_package(self): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.parent_repo.create_ebuild('cat/pkg-2', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg-2') + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.parent_repo.create_ebuild("cat/pkg-2", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg-2") # rename pkg and commit results path = self.parent_git_repo.path - new_pkg_dir = pjoin(path, 'cat/newpkg') - os.rename(pjoin(path, 'cat/pkg'), new_pkg_dir) + new_pkg_dir = pjoin(path, "cat/newpkg") + os.rename(pjoin(path, "cat/pkg"), new_pkg_dir) for i, f in enumerate(sorted(os.listdir(new_pkg_dir))): - os.rename(pjoin(new_pkg_dir, f), pjoin(new_pkg_dir, f'newpkg-{i}.ebuild')) + os.rename(pjoin(new_pkg_dir, f), pjoin(new_pkg_dir, f"newpkg-{i}.ebuild")) self.parent_git_repo.add_all() - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.child_git_repo.run(["git", "pull", "origin", "main"]) self.init_check(future=30) r = self.assertReport(self.check, self.source) - expected = StableRequest('0', ['~amd64'], 30, pkg=VersionedCPV('cat/newpkg-2')) + expected = StableRequest("0", ["~amd64"], 30, pkg=VersionedCPV("cat/newpkg-2")) assert r == expected def test_renamed_ebuild(self): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.parent_repo.create_ebuild('cat/pkg-2_rc1', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg-2_rc1') - self.parent_git_repo.move('cat/pkg/pkg-2_rc1.ebuild', 'cat/pkg/pkg-2.ebuild') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.parent_repo.create_ebuild("cat/pkg-2_rc1", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg-2_rc1") + self.parent_git_repo.move("cat/pkg/pkg-2_rc1.ebuild", "cat/pkg/pkg-2.ebuild") + self.child_git_repo.run(["git", "pull", "origin", "main"]) self.init_check(future=30) r = self.assertReport(self.check, self.source) - expected = StableRequest('0', ['~amd64'], 30, pkg=VersionedCPV('cat/pkg-2')) + expected = StableRequest("0", ["~amd64"], 30, pkg=VersionedCPV("cat/pkg-2")) assert r == expected def test_modified_ebuild(self): - self.parent_repo.create_ebuild('cat/pkg-1', keywords=['amd64']) - self.parent_git_repo.add_all('cat/pkg-1') - self.parent_repo.create_ebuild('cat/pkg-2', keywords=['~amd64']) - self.parent_git_repo.add_all('cat/pkg-2') - with open(pjoin(self.parent_git_repo.path, 'cat/pkg/pkg-2.ebuild'), 'a') as f: - f.write('# comment\n') - self.parent_git_repo.add_all('cat/pkg-2: add comment') - self.child_git_repo.run(['git', 'pull', 'origin', 'main']) + self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"]) + self.parent_git_repo.add_all("cat/pkg-1") + self.parent_repo.create_ebuild("cat/pkg-2", keywords=["~amd64"]) + self.parent_git_repo.add_all("cat/pkg-2") + with open(pjoin(self.parent_git_repo.path, "cat/pkg/pkg-2.ebuild"), "a") as f: + f.write("# comment\n") + self.parent_git_repo.add_all("cat/pkg-2: add comment") + self.child_git_repo.run(["git", "pull", "origin", "main"]) self.init_check(future=30) r = self.assertReport(self.check, self.source) - expected = StableRequest('0', ['~amd64'], 30, pkg=VersionedCPV('cat/pkg-2')) + expected = StableRequest("0", ["~amd64"], 30, pkg=VersionedCPV("cat/pkg-2")) assert r == expected diff --git a/tests/checks/test_whitespace.py b/tests/checks/test_whitespace.py index bc61998c..f90495b6 100644 --- a/tests/checks/test_whitespace.py +++ b/tests/checks/test_whitespace.py @@ -15,7 +15,6 @@ class WhitespaceCheckTest(misc.ReportTestCase): class TestWhitespaceFound(WhitespaceCheckTest): - def test_leading(self): fake_src = [ "# This is our first fake ebuild\n", @@ -27,7 +26,7 @@ class TestWhitespaceFound(WhitespaceCheckTest): r = self.assertReport(self.check, fake_pkg) assert isinstance(r, whitespace.WhitespaceFound) assert r.lines == (2,) - assert 'leading whitespace' in str(r) + assert "leading whitespace" in str(r) def test_trailing(self): fake_src = [ @@ -40,11 +39,10 @@ class TestWhitespaceFound(WhitespaceCheckTest): r = self.assertReport(self.check, fake_pkg) assert isinstance(r, whitespace.WhitespaceFound) assert r.lines == (2,) - assert 'trailing whitespace' in str(r) + assert "trailing whitespace" in str(r) class TestWrongIndentFound(WhitespaceCheckTest): - def test_it(self): fake_src = [ "# This is our first fake ebuild\n", @@ -56,11 +54,10 @@ class TestWrongIndentFound(WhitespaceCheckTest): r = self.assertReport(self.check, fake_pkg) assert isinstance(r, whitespace.WrongIndentFound) assert r.lines == (2,) - assert 'whitespace in indentation' in str(r) + assert "whitespace in indentation" in str(r) class TestDoubleEmptyLine(WhitespaceCheckTest): - def test_it(self): fake_src = [ "# This is our first fake ebuild\n", @@ -73,11 +70,10 @@ class TestDoubleEmptyLine(WhitespaceCheckTest): r = self.assertReport(self.check, fake_pkg) assert isinstance(r, whitespace.DoubleEmptyLine) assert r.lines == (3,) - assert 'unneeded empty line' in str(r) + assert "unneeded empty line" in str(r) class TestNoNewLineOnEnd(WhitespaceCheckTest): - def test_it(self): fake_src = [ "# This is our first fake ebuild\n", @@ -87,11 +83,10 @@ class TestNoNewLineOnEnd(WhitespaceCheckTest): r = self.assertReport(self.check, fake_pkg) assert isinstance(r, whitespace.NoFinalNewline) - assert 'lacks an ending newline' in str(r) + assert "lacks an ending newline" in str(r) class TestTrailingNewLineOnEnd(WhitespaceCheckTest): - def test_it(self): fake_src = [ "# This is our first fake ebuild\n", @@ -102,43 +97,43 @@ class TestTrailingNewLineOnEnd(WhitespaceCheckTest): r = self.assertReport(self.check, fake_pkg) assert isinstance(r, whitespace.TrailingEmptyLine) - assert 'trailing blank line(s)' in str(r) + assert "trailing blank line(s)" in str(r) def generate_whitespace_data(): """Generate bad whitespace list for the current python version.""" all_whitespace_chars = set( - re.findall(r'\s', ''.join(chr(c) for c in range(sys.maxunicode + 1)))) - allowed_whitespace_chars = {'\t', '\n', ' '} + re.findall(r"\s", "".join(chr(c) for c in range(sys.maxunicode + 1))) + ) + allowed_whitespace_chars = {"\t", "\n", " "} bad_whitespace_chars = tuple(sorted(all_whitespace_chars - allowed_whitespace_chars)) return whitespace.WhitespaceData(unicodedata.unidata_version, bad_whitespace_chars) class TestBadWhitespaceCharacter(WhitespaceCheckTest): - def test_outdated_bad_whitespace_chars(self): """Check if the hardcoded bad whitespace character list is outdated.""" updated_whitespace_data = generate_whitespace_data() if updated_whitespace_data.unicode_version != whitespace.whitespace_data.unicode_version: - assert updated_whitespace_data.chars == whitespace.whitespace_data.chars, \ - f'outdated character list for Unicode version {unicodedata.unidata_version}' + assert ( + updated_whitespace_data.chars == whitespace.whitespace_data.chars + ), f"outdated character list for Unicode version {unicodedata.unidata_version}" def test_bad_whitespace_chars(self): for char in whitespace.whitespace_data.chars: fake_src = [ - 'src_prepare() {\n', + "src_prepare() {\n", f'\tcd "${{S}}"/cpp ||{char}die\n', - '}\n', + "}\n", ] fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) r = self.assertReport(self.check, fake_pkg) assert isinstance(r, whitespace.BadWhitespaceCharacter) - assert f'bad whitespace character {repr(char)} on line 2' in str(r) + assert f"bad whitespace character {repr(char)} on line 2" in str(r) class TestMultipleChecks(WhitespaceCheckTest): - def test_it(self): fake_src = [ "# This is our first fake ebuild\n", diff --git a/tests/conftest.py b/tests/conftest.py index 675110a6..a836e3ba 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,7 +17,7 @@ from snakeoil.contexts import os_environ from snakeoil.formatters import PlainTextFormatter from snakeoil.osutils import pjoin -pytest_plugins = ['pkgcore'] +pytest_plugins = ["pkgcore"] REPO_ROOT = Path(__file__).parent.parent @@ -43,7 +43,7 @@ def default_session_fixture(request): """Fixture run globally for the entire test session.""" stack = ExitStack() # don't load the default system or user config files - stack.enter_context(patch('pkgcheck.cli.ConfigFileParser.default_configs', ())) + stack.enter_context(patch("pkgcheck.cli.ConfigFileParser.default_configs", ())) stack.enter_context(os_environ(**(git_config := GitConfig()).config_env)) def unpatch(): @@ -59,40 +59,44 @@ def testconfig(tmp_path_factory): Also, repo entries for all the bundled test repos. """ - config = tmp_path_factory.mktemp('testconfig') - repos_conf = config / 'repos.conf' - stubrepo = pjoin(pkgcore_const.DATA_PATH, 'stubrepo') - testdir = REPO_ROOT / 'testdata/repos' - with open(repos_conf, 'w') as f: - f.write(textwrap.dedent(f"""\ - [DEFAULT] - main-repo = standalone - [stubrepo] - location = {stubrepo} - """)) + config = tmp_path_factory.mktemp("testconfig") + repos_conf = config / "repos.conf" + stubrepo = pjoin(pkgcore_const.DATA_PATH, "stubrepo") + testdir = REPO_ROOT / "testdata/repos" + with open(repos_conf, "w") as f: + f.write( + textwrap.dedent( + f"""\ + [DEFAULT] + main-repo = standalone + [stubrepo] + location = {stubrepo} + """ + ) + ) for repo in testdir.iterdir(): - f.write(f'[{repo.name}]\n') - f.write(f'location = {repo}\n') - profile_path = pjoin(stubrepo, 'profiles', 'default') - os.symlink(profile_path, str(config / 'make.profile')) + f.write(f"[{repo.name}]\n") + f.write(f"location = {repo}\n") + profile_path = pjoin(stubrepo, "profiles", "default") + os.symlink(profile_path, str(config / "make.profile")) return str(config) @pytest.fixture(scope="session") def cache_dir(tmp_path_factory): """Generate a cache directory for pkgcheck.""" - cache_dir = tmp_path_factory.mktemp('cache') + cache_dir = tmp_path_factory.mktemp("cache") return str(cache_dir) @pytest.fixture def fakerepo(tmp_path_factory): """Generate a stub repo.""" - fakerepo = tmp_path_factory.mktemp('fakerepo') - (profiles := fakerepo / 'profiles').mkdir(parents=True) - (profiles / 'repo_name').write_text('fakerepo\n') - (metadata := fakerepo / 'metadata').mkdir(parents=True) - (metadata / 'layout.conf').write_text('masters =\n') + fakerepo = tmp_path_factory.mktemp("fakerepo") + (profiles := fakerepo / "profiles").mkdir(parents=True) + (profiles / "repo_name").write_text("fakerepo\n") + (metadata := fakerepo / "metadata").mkdir(parents=True) + (metadata / "layout.conf").write_text("masters =\n") return fakerepo diff --git a/tests/misc.py b/tests/misc.py index cf317e4e..92d25721 100644 --- a/tests/misc.py +++ b/tests/misc.py @@ -26,18 +26,18 @@ from snakeoil.sequences import split_negations @dataclass class Profile: """Profile record used to create profiles in a repository.""" + path: str arch: str - status: str = 'stable' + status: str = "stable" deprecated: bool = False defaults: List[str] = None - eapi: str = '5' + eapi: str = "5" # TODO: merge this with the pkgcore-provided equivalent class FakePkg(package): - - def __init__(self, cpvstr, data=None, parent=None, ebuild='', **kwargs): + def __init__(self, cpvstr, data=None, parent=None, ebuild="", **kwargs): if data is None: data = {} @@ -46,7 +46,7 @@ class FakePkg(package): cpv = VersionedCPV(cpvstr) # TODO: make pkgcore generate empty shared pkg data when None is passed - mxml = repo_objs.LocalMetadataXml('') + mxml = repo_objs.LocalMetadataXml("") shared = repo_objs.SharedPkgData(metadata_xml=mxml, manifest=None) super().__init__(shared, parent, cpv.category, cpv.package, cpv.fullver) object.__setattr__(self, "data", data) @@ -58,7 +58,7 @@ class FakePkg(package): @property def eapi(self): - return get_eapi(self.data.get('EAPI', '0')) + return get_eapi(self.data.get("EAPI", "0")) @property def ebuild(self): @@ -88,8 +88,11 @@ class FakeFilesDirPkg(package): cpv = VersionedCPV(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')) + object.__setattr__( + self, + "path", + pjoin(repo.location, cpv.category, cpv.package, f"{cpv.package}-{cpv.fullver}.ebuild"), + ) class ReportTestCase: @@ -133,7 +136,7 @@ class ReportTestCase: def assertReport(self, check, data): results = self.assertReports(check, data) - results_str = '\n'.join(map(str, results)) + results_str = "\n".join(map(str, results)) assert len(results) == 1, f"expected one report, got {len(results)}:\n{results_str}" self._assertReportSanity(*results) result = results[0] @@ -141,40 +144,51 @@ class ReportTestCase: class FakeProfile: - - def __init__(self, masked_use={}, stable_masked_use={}, forced_use={}, - stable_forced_use={}, pkg_use={}, provides={}, iuse_effective=[], - use=[], masks=[], unmasks=[], arch='x86', name='none'): + def __init__( + self, + masked_use={}, + stable_masked_use={}, + forced_use={}, + stable_forced_use={}, + pkg_use={}, + provides={}, + iuse_effective=[], + use=[], + masks=[], + unmasks=[], + arch="x86", + name="none", + ): self.provides_repo = SimpleTree(provides) self.masked_use = ChunkedDataDict() self.masked_use.update_from_stream( - chunked_data(atom(k), *split_negations(v)) - for k, v in masked_use.items()) + chunked_data(atom(k), *split_negations(v)) for k, v in masked_use.items() + ) self.masked_use.freeze() self.stable_masked_use = ChunkedDataDict() self.stable_masked_use.update_from_stream( - chunked_data(atom(k), *split_negations(v)) - for k, v in stable_masked_use.items()) + chunked_data(atom(k), *split_negations(v)) for k, v in stable_masked_use.items() + ) self.stable_masked_use.freeze() self.forced_use = ChunkedDataDict() self.forced_use.update_from_stream( - chunked_data(atom(k), *split_negations(v)) - for k, v in forced_use.items()) + chunked_data(atom(k), *split_negations(v)) for k, v in forced_use.items() + ) self.forced_use.freeze() self.stable_forced_use = ChunkedDataDict() self.stable_forced_use.update_from_stream( - chunked_data(atom(k), *split_negations(v)) - for k, v in stable_forced_use.items()) + chunked_data(atom(k), *split_negations(v)) for k, v in stable_forced_use.items() + ) self.stable_forced_use.freeze() self.pkg_use = ChunkedDataDict() self.pkg_use.update_from_stream( - chunked_data(atom(k), *split_negations(v)) - for k, v in pkg_use.items()) + chunked_data(atom(k), *split_negations(v)) for k, v in pkg_use.items() + ) self.pkg_use.freeze() self.masks = tuple(map(atom, masks)) @@ -199,7 +213,7 @@ class Tmpdir: def random_str(length=10): """Generate a random string of ASCII characters of a given length.""" - return ''.join(random.choice(string.ascii_letters) for _ in range(length)) + return "".join(random.choice(string.ascii_letters) for _ in range(length)) # TODO: combine this with pkgcheck.checks.init_checks() @@ -224,6 +238,5 @@ def init_check(check_cls, options): except CacheDisabled as e: raise SkipCheck(cls, e) - required_addons = { - base.param_name(x): addons_map[x] for x in addon.required_addons} + required_addons = {base.param_name(x): addons_map[x] for x in addon.required_addons} return addon, required_addons, source diff --git a/tests/scripts/test_argparse_actions.py b/tests/scripts/test_argparse_actions.py index d46d4560..283eb716 100644 --- a/tests/scripts/test_argparse_actions.py +++ b/tests/scripts/test_argparse_actions.py @@ -11,61 +11,59 @@ from snakeoil.cli import arghparse class TestConfigArg: - @pytest.fixture(autouse=True) def _create_argparser(self): self.parser = arghparse.ArgumentParser() - self.parser.add_argument('--config', action=argparse_actions.ConfigArg) + self.parser.add_argument("--config", action=argparse_actions.ConfigArg) def test_none(self): options = self.parser.parse_args([]) assert options.config is None def test_enabled(self): - for arg in ('config_file', '/path/to/config/file'): - options = self.parser.parse_args(['--config', arg]) + for arg in ("config_file", "/path/to/config/file"): + options = self.parser.parse_args(["--config", arg]) assert options.config == arg def test_disabled(self): - for arg in ('False', 'false', 'No', 'no', 'N', 'n'): - options = self.parser.parse_args(['--config', arg]) + for arg in ("False", "false", "No", "no", "N", "n"): + options = self.parser.parse_args(["--config", arg]) assert options.config is False class TestFilterArgs: - @pytest.fixture(autouse=True) def _create_argparser(self): self.parser = arghparse.ArgumentParser() - self.parser.set_defaults(config_checksets={'cset': ['StableRequestCheck']}) - self.parser.add_argument('--filter', action=argparse_actions.FilterArgs) + self.parser.set_defaults(config_checksets={"cset": ["StableRequestCheck"]}) + self.parser.add_argument("--filter", action=argparse_actions.FilterArgs) def test_none(self): options = self.parser.parse_args([]) assert options.filter is None def test_unknown_filter(self, capsys): - for arg in ('foo', 'foo:PkgDirCheck'): + for arg in ("foo", "foo:PkgDirCheck"): with pytest.raises(SystemExit) as excinfo: - self.parser.parse_args(['--filter', arg]) + self.parser.parse_args(["--filter", arg]) out, err = capsys.readouterr() assert not out assert "unknown filter: 'foo'" in err assert excinfo.value.code == 2 def test_disabled(self): - for arg in ('False', 'false', 'No', 'no', 'N', 'n'): - options = self.parser.parse_args(['--filter', arg]) + for arg in ("False", "false", "No", "no", "N", "n"): + options = self.parser.parse_args(["--filter", arg]) assert options.filter == {} def test_enabled(self): - for arg in ('latest', 'latest:StableRequest', 'latest:StableRequestCheck', 'latest:cset'): - options = self.parser.parse_args(['--filter', arg]) - assert objects.KEYWORDS['StableRequest'] in options.filter + for arg in ("latest", "latest:StableRequest", "latest:StableRequestCheck", "latest:cset"): + options = self.parser.parse_args(["--filter", arg]) + assert objects.KEYWORDS["StableRequest"] in options.filter def test_unknown_value(self, capsys): with pytest.raises(SystemExit) as excinfo: - self.parser.parse_args(['--filter', 'latest:foo']) + self.parser.parse_args(["--filter", "latest:foo"]) out, err = capsys.readouterr() assert not out assert "unknown checkset, check, or keyword: 'foo'" in err @@ -73,11 +71,10 @@ class TestFilterArgs: class TestCacheNegations: - @pytest.fixture(autouse=True) def _create_argparser(self): self.parser = arghparse.ArgumentParser() - self.parser.add_argument('--cache', action=argparse_actions.CacheNegations) + self.parser.add_argument("--cache", action=argparse_actions.CacheNegations) self.caches = [x.type for x in CachedAddon.caches.values()] def test_defaults(self): @@ -86,27 +83,27 @@ class TestCacheNegations: def test_unknown(self, capsys): with pytest.raises(SystemExit) as excinfo: - self.parser.parse_args(['--cache', 'foo']) + self.parser.parse_args(["--cache", "foo"]) out, err = capsys.readouterr() assert not out assert "unknown cache type: 'foo'" in err assert excinfo.value.code == 2 def test_all(self): - for arg in ('True', 'true', 'Yes', 'yes', 'Y', 'y'): - options = self.parser.parse_args(['--cache', arg]) + for arg in ("True", "true", "Yes", "yes", "Y", "y"): + options = self.parser.parse_args(["--cache", arg]) for k, v in options.cache.items(): assert v is True def test_none(self): - for arg in ('False', 'false', 'No', 'no', 'N', 'n'): - options = self.parser.parse_args(['--cache', arg]) + for arg in ("False", "false", "No", "no", "N", "n"): + options = self.parser.parse_args(["--cache", arg]) for k, v in options.cache.items(): assert v is False def test_enabled(self): cache = self.caches[random.randrange(len(self.caches))] - options = self.parser.parse_args(['--cache', cache]) + options = self.parser.parse_args(["--cache", cache]) for k, v in options.cache.items(): if k == cache: assert v is True @@ -115,7 +112,7 @@ class TestCacheNegations: def test_disabled(self): cache = self.caches[random.randrange(len(self.caches))] - options = self.parser.parse_args([f'--cache=-{cache}']) + options = self.parser.parse_args([f"--cache=-{cache}"]) for k, v in options.cache.items(): if k == cache: assert v is False @@ -124,66 +121,70 @@ class TestCacheNegations: class TestChecksetArgs: - @pytest.fixture(autouse=True) def _setup(self, tool, tmp_path): self.tool = tool - self.cache_dir = str(tmp_path / '.cache') - self.config = str(tmp_path / 'config') - self.args = ['scan', '--cache-dir', self.cache_dir] + self.cache_dir = str(tmp_path / ".cache") + self.config = str(tmp_path / "config") + self.args = ["scan", "--cache-dir", self.cache_dir] def test_unknown(self, capsys): - for opt in ('-C', '--checksets'): + for opt in ("-C", "--checksets"): with pytest.raises(SystemExit) as excinfo: - self.tool.parse_args(self.args + [opt, 'foo']) + self.tool.parse_args(self.args + [opt, "foo"]) out, err = capsys.readouterr() assert not out assert "unknown checkset: 'foo'" in err assert excinfo.value.code == 2 def test_aliases(self): - for opt in ('-C', '--checksets'): + for opt in ("-C", "--checksets"): # net - options, _ = self.tool.parse_args(self.args + [opt, 'net']) + options, _ = self.tool.parse_args(self.args + [opt, "net"]) network_checks = [ - c for c, v in objects.CHECKS.items() if issubclass(v, checks.NetworkCheck)] + c for c, v in objects.CHECKS.items() if issubclass(v, checks.NetworkCheck) + ] assert options.selected_checks == set(network_checks) # all - options, _ = self.tool.parse_args(self.args + [opt, 'all']) + options, _ = self.tool.parse_args(self.args + [opt, "all"]) assert options.selected_checks == set(objects.CHECKS) def test_sets(self, capsys): - with open(self.config, 'w') as f: - f.write(textwrap.dedent("""\ - [CHECKSETS] - set1=StableRequest - set2=-StableRequest - set3=SourcingCheck,-InvalidEapi,-InvalidSlot - bad=foo - """)) + with open(self.config, "w") as f: + f.write( + textwrap.dedent( + """\ + [CHECKSETS] + set1=StableRequest + set2=-StableRequest + set3=SourcingCheck,-InvalidEapi,-InvalidSlot + bad=foo + """ + ) + ) configs = [self.config] - with patch('pkgcheck.cli.ConfigFileParser.default_configs', configs): - for opt in ('-C', '--checksets'): + with patch("pkgcheck.cli.ConfigFileParser.default_configs", configs): + for opt in ("-C", "--checksets"): # enabled keyword - for arg in ('set1', '-set2'): - options, _ = self.tool.parse_args(self.args + [f'{opt}={arg}']) - assert options.filtered_keywords == {objects.KEYWORDS['StableRequest']} - assert options.enabled_checks == {objects.CHECKS['StableRequestCheck']} + for arg in ("set1", "-set2"): + options, _ = self.tool.parse_args(self.args + [f"{opt}={arg}"]) + assert options.filtered_keywords == {objects.KEYWORDS["StableRequest"]} + assert options.enabled_checks == {objects.CHECKS["StableRequestCheck"]} # disabled keyword - for arg in ('-set1', 'set2'): - options, _ = self.tool.parse_args(self.args + [f'{opt}={arg}']) - assert objects.KEYWORDS['StableRequest'] not in options.filtered_keywords + for arg in ("-set1", "set2"): + options, _ = self.tool.parse_args(self.args + [f"{opt}={arg}"]) + assert objects.KEYWORDS["StableRequest"] not in options.filtered_keywords # check/keywords mixture - options, _ = self.tool.parse_args(self.args + [f'{opt}=set3']) - assert options.filtered_keywords == {objects.KEYWORDS['SourcingError']} - assert options.enabled_checks == {objects.CHECKS['SourcingCheck']} + options, _ = self.tool.parse_args(self.args + [f"{opt}=set3"]) + assert options.filtered_keywords == {objects.KEYWORDS["SourcingError"]} + assert options.enabled_checks == {objects.CHECKS["SourcingCheck"]} # unknown value with pytest.raises(SystemExit) as excinfo: - self.tool.parse_args(self.args + [f'{opt}=bad']) + self.tool.parse_args(self.args + [f"{opt}=bad"]) out, err = capsys.readouterr() assert not out assert "'bad' checkset, unknown check or keyword: 'foo'" in err @@ -191,173 +192,167 @@ class TestChecksetArgs: class TestScopeArgs: - @pytest.fixture(autouse=True) def _setup(self, tool, tmp_path): self.tool = tool self.cache_dir = str(tmp_path) - self.args = ['scan', '--cache-dir', self.cache_dir] + self.args = ["scan", "--cache-dir", self.cache_dir] def test_unknown_scope(self, capsys): - for opt in ('-s', '--scopes'): + for opt in ("-s", "--scopes"): with pytest.raises(SystemExit) as excinfo: - options, _ = self.tool.parse_args(self.args + [opt, 'foo']) + options, _ = self.tool.parse_args(self.args + [opt, "foo"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') + err = err.strip().split("\n") assert "unknown scope: 'foo'" in err[-1] def test_missing_scope(self, capsys): - for opt in ('-s', '--scopes'): + for opt in ("-s", "--scopes"): with pytest.raises(SystemExit) as excinfo: options, _ = self.tool.parse_args(self.args + [opt]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') - assert err[0] == ( - 'pkgcheck scan: error: argument -s/--scopes: expected one argument') + err = err.strip().split("\n") + assert err[0] == ("pkgcheck scan: error: argument -s/--scopes: expected one argument") def test_disabled(self): - options, _ = self.tool.parse_args(self.args + ['--scopes=-eclass']) + options, _ = self.tool.parse_args(self.args + ["--scopes=-eclass"]) assert options.selected_scopes == frozenset() def test_enabled(self): - options, _ = self.tool.parse_args(self.args + ['--scopes', 'repo']) - assert options.selected_scopes == frozenset([base.scopes['repo']]) + options, _ = self.tool.parse_args(self.args + ["--scopes", "repo"]) + assert options.selected_scopes == frozenset([base.scopes["repo"]]) class TestCheckArgs: - @pytest.fixture(autouse=True) def _setup(self, tool, tmp_path): self.tool = tool self.cache_dir = str(tmp_path) - self.args = ['scan', '--cache-dir', self.cache_dir] + self.args = ["scan", "--cache-dir", self.cache_dir] def test_unknown_check(self, capsys): - for opt in ('-c', '--checks'): + for opt in ("-c", "--checks"): with pytest.raises(SystemExit) as excinfo: - options, _ = self.tool.parse_args(self.args + [opt, 'foo']) + options, _ = self.tool.parse_args(self.args + [opt, "foo"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') + err = err.strip().split("\n") assert "unknown check: 'foo'" in err[-1] def test_token_errors(self): - for opt in ('-c', '--checks'): - for operation in ('-', '+'): + for opt in ("-c", "--checks"): + for operation in ("-", "+"): with pytest.raises(argparse.ArgumentTypeError) as excinfo: - options, _ = self.tool.parse_args(self.args + [f'{opt}={operation}']) - assert 'without a token' in str(excinfo.value) + options, _ = self.tool.parse_args(self.args + [f"{opt}={operation}"]) + assert "without a token" in str(excinfo.value) def test_missing_check(self, capsys): - for opt in ('-c', '--checks'): + for opt in ("-c", "--checks"): with pytest.raises(SystemExit) as excinfo: options, _ = self.tool.parse_args(self.args + [opt]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') - assert err[0] == ( - 'pkgcheck scan: error: argument -c/--checks: expected one argument') + err = err.strip().split("\n") + assert err[0] == ("pkgcheck scan: error: argument -c/--checks: expected one argument") def test_neutral(self): - for opt in ('-c', '--checks'): - options, _ = self.tool.parse_args(self.args + [opt, 'UnusedLicensesCheck']) - assert options.selected_checks == frozenset(['UnusedLicensesCheck']) + for opt in ("-c", "--checks"): + options, _ = self.tool.parse_args(self.args + [opt, "UnusedLicensesCheck"]) + assert options.selected_checks == frozenset(["UnusedLicensesCheck"]) def test_subtractive(self): - for opt in ('-c', '--checks'): + for opt in ("-c", "--checks"): check = list(objects.CHECKS)[random.randrange(len(objects.CHECKS))] - options, _ = self.tool.parse_args(self.args + [f'{opt}=-{check}']) + options, _ = self.tool.parse_args(self.args + [f"{opt}=-{check}"]) assert options.selected_checks == frozenset() def test_additive(self): - for opt in ('-c', '--checks'): + for opt in ("-c", "--checks"): options, _ = self.tool.parse_args(self.args) assert issubclass(checks.perl.PerlCheck, checks.OptionalCheck) assert checks.perl.PerlCheck not in set(options.enabled_checks) - options, _ = self.tool.parse_args(self.args + [f'{opt}=+PerlCheck']) + options, _ = self.tool.parse_args(self.args + [f"{opt}=+PerlCheck"]) assert checks.perl.PerlCheck in set(options.enabled_checks) - assert options.selected_checks == frozenset(['PerlCheck']) + assert options.selected_checks == frozenset(["PerlCheck"]) class TestKeywordArgs: - @pytest.fixture(autouse=True) def _setup(self, tool, tmp_path): self.tool = tool self.cache_dir = str(tmp_path) - self.args = ['scan', '--cache-dir', self.cache_dir] + self.args = ["scan", "--cache-dir", self.cache_dir] def test_unknown_keyword(self, capsys): - for opt in ('-k', '--keywords'): + for opt in ("-k", "--keywords"): with pytest.raises(SystemExit) as excinfo: - options, _ = self.tool.parse_args(self.args + [opt, 'foo']) + options, _ = self.tool.parse_args(self.args + [opt, "foo"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') + err = err.strip().split("\n") assert "unknown keyword: 'foo'" in err[-1] def test_missing_keyword(self, capsys): - for opt in ('-k', '--keywords'): + for opt in ("-k", "--keywords"): with pytest.raises(SystemExit) as excinfo: options, _ = self.tool.parse_args(self.args + [opt]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') - assert err[0] == ( - 'pkgcheck scan: error: argument -k/--keywords: expected one argument') + err = err.strip().split("\n") + assert err[0] == ("pkgcheck scan: error: argument -k/--keywords: expected one argument") def test_enabled(self): - for opt in ('-k', '--keywords'): - options, _ = self.tool.parse_args(self.args + [opt, 'UnusedLicenses']) - assert options.selected_keywords == frozenset(['UnusedLicenses']) - assert options.filtered_keywords == frozenset([objects.KEYWORDS['UnusedLicenses']]) + for opt in ("-k", "--keywords"): + options, _ = self.tool.parse_args(self.args + [opt, "UnusedLicenses"]) + assert options.selected_keywords == frozenset(["UnusedLicenses"]) + assert options.filtered_keywords == frozenset([objects.KEYWORDS["UnusedLicenses"]]) assert options.enabled_checks == {checks.repo_metadata.UnusedLicensesCheck} def test_disabled_check(self): """Disabling all keywords for a given check also disables the check.""" - for opt in ('-k', '--keywords'): + for opt in ("-k", "--keywords"): default_checks = set(objects.CHECKS.default.values()) default_keywords = set().union(*(v.known_results for v in default_checks)) keyword = checks.repo_metadata.UnusedLicenses check = checks.repo_metadata.UnusedLicensesCheck assert check in default_checks assert check.known_results == frozenset([keyword]) - options, _ = self.tool.parse_args(self.args + [f'{opt}=-UnusedLicenses']) + options, _ = self.tool.parse_args(self.args + [f"{opt}=-UnusedLicenses"]) assert options.selected_keywords == frozenset() assert options.filtered_keywords == frozenset(default_keywords - {keyword}) assert check not in set(options.enabled_checks) def test_disabled(self): - for opt in ('-k', '--keywords'): + for opt in ("-k", "--keywords"): default_keywords = set().union( - *(v.known_results for v in objects.CHECKS.default.values())) + *(v.known_results for v in objects.CHECKS.default.values()) + ) keyword_cls = list(default_keywords)[random.randrange(len(default_keywords))] keyword = keyword_cls.__name__ - options, _ = self.tool.parse_args(self.args + [f'{opt}=-{keyword}']) + options, _ = self.tool.parse_args(self.args + [f"{opt}=-{keyword}"]) assert options.selected_keywords == frozenset() assert options.filtered_keywords == frozenset(default_keywords - {keyword_cls}) def test_aliases(self): - for opt in ('-k', '--keywords'): - for alias in ('error', 'warning', 'info'): + for opt in ("-k", "--keywords"): + for alias in ("error", "warning", "info"): options, _ = self.tool.parse_args(self.args + [opt, alias]) alias_keywords = list(getattr(objects.KEYWORDS, alias)) assert options.selected_keywords == frozenset(alias_keywords) class TestExitArgs: - @pytest.fixture(autouse=True) def _setup(self, tool, tmp_path): self.tool = tool self.cache_dir = str(tmp_path) - self.args = ['scan', '--cache-dir', self.cache_dir] + self.args = ["scan", "--cache-dir", self.cache_dir] def test_unknown(self, capsys): with pytest.raises(SystemExit) as excinfo: - self.tool.parse_args(self.args + ['--exit', 'foo']) + self.tool.parse_args(self.args + ["--exit", "foo"]) out, err = capsys.readouterr() assert not out assert "unknown checkset, check, or keyword: 'foo'" in err @@ -368,22 +363,22 @@ class TestExitArgs: assert options.exit_keywords == () def test_default(self): - options, _ = self.tool.parse_args(self.args + ['--exit']) + options, _ = self.tool.parse_args(self.args + ["--exit"]) assert options.exit_keywords == frozenset(objects.KEYWORDS.error.values()) def test_enabled(self): keyword = list(objects.KEYWORDS)[random.randrange(len(objects.KEYWORDS))] objs = (objects.KEYWORDS[x] for x in objects.KEYWORDS.aliases.get(keyword, [keyword])) - options, _ = self.tool.parse_args(self.args + ['--exit', keyword]) + options, _ = self.tool.parse_args(self.args + ["--exit", keyword]) assert options.exit_keywords == frozenset(objs) def test_disabled(self): keyword = list(objects.KEYWORDS)[random.randrange(len(objects.KEYWORDS))] objs = (objects.KEYWORDS[x] for x in objects.KEYWORDS.aliases.get(keyword, [keyword])) - options, _ = self.tool.parse_args(self.args + [f'--exit=-{keyword}']) + options, _ = self.tool.parse_args(self.args + [f"--exit=-{keyword}"]) assert options.exit_keywords == frozenset(objects.KEYWORDS.error.values()) - frozenset(objs) def test_aliases(self): - for alias in ('error', 'warning', 'info'): - options, _ = self.tool.parse_args(self.args + [f'--exit={alias}']) + for alias in ("error", "warning", "info"): + options, _ = self.tool.parse_args(self.args + [f"--exit={alias}"]) assert options.exit_keywords == frozenset(getattr(objects.KEYWORDS, alias).values()) diff --git a/tests/scripts/test_pkgcheck.py b/tests/scripts/test_pkgcheck.py index 8478a746..49e2f8b6 100644 --- a/tests/scripts/test_pkgcheck.py +++ b/tests/scripts/test_pkgcheck.py @@ -11,27 +11,27 @@ def test_script_run(capsys): """Test regular code path for running scripts.""" script = partial(run, project) - with patch(f'{project}.scripts.import_module') as import_module: + with patch(f"{project}.scripts.import_module") as import_module: import_module.side_effect = ImportError("baz module doesn't exist") # default error path when script import fails - with patch('sys.argv', [project]): + with patch("sys.argv", [project]): with pytest.raises(SystemExit) as excinfo: script() assert excinfo.value.code == 1 out, err = capsys.readouterr() - err = err.strip().split('\n') + err = err.strip().split("\n") assert len(err) == 3 assert err[0] == "Failed importing: baz module doesn't exist!" assert err[1].startswith(f"Verify that {project} and its deps") assert err[2] == "Add --debug to the commandline for a traceback." # running with --debug should raise an ImportError when there are issues - with patch('sys.argv', [project, '--debug']): + with patch("sys.argv", [project, "--debug"]): with pytest.raises(ImportError): script() out, err = capsys.readouterr() - err = err.strip().split('\n') + err = err.strip().split("\n") assert len(err) == 2 assert err[0] == "Failed importing: baz module doesn't exist!" assert err[1].startswith(f"Verify that {project} and its deps") @@ -44,7 +44,7 @@ class TestPkgcheck: script = partial(run, project) def test_version(self, capsys): - with patch('sys.argv', [project, '--version']): + with patch("sys.argv", [project, "--version"]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 0 diff --git a/tests/scripts/test_pkgcheck_cache.py b/tests/scripts/test_pkgcheck_cache.py index 0414b4ec..023a3161 100644 --- a/tests/scripts/test_pkgcheck_cache.py +++ b/tests/scripts/test_pkgcheck_cache.py @@ -14,95 +14,95 @@ class TestPkgcheckCache: @pytest.fixture(autouse=True) def _setup(self, testconfig, tmp_path): self.cache_dir = str(tmp_path) - self.args = [ - project, '--config', testconfig, - 'cache', '--cache-dir', self.cache_dir] + self.args = [project, "--config", testconfig, "cache", "--cache-dir", self.cache_dir] def test_cache_profiles(self, capsys): # force standalone repo profiles cache regen - for args in (['-u', '-f'], ['--update', '--force']): - with patch('sys.argv', self.args + args + ['-t', 'profiles']): + for args in (["-u", "-f"], ["--update", "--force"]): + with patch("sys.argv", self.args + args + ["-t", "profiles"]): with pytest.raises(SystemExit): self.script() # verify the profiles cache shows up - with patch('sys.argv', self.args): + with patch("sys.argv", self.args): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err out = out.strip().splitlines() - assert out[-1].startswith('standalone-') + assert out[-1].startswith("standalone-") assert excinfo.value.code == 0 # pretend to remove it - for arg in ('-n', '--dry-run'): - with patch('sys.argv', self.args + [arg] + ['-Rt', 'profiles']): + for arg in ("-n", "--dry-run"): + with patch("sys.argv", self.args + [arg] + ["-Rt", "profiles"]): with pytest.raises(SystemExit): self.script() out, err = capsys.readouterr() - assert err == '' - assert out.startswith(f'Would remove {self.cache_dir}') + assert err == "" + assert out.startswith(f"Would remove {self.cache_dir}") # fail to remove it - for arg in ('-R', '--remove'): - with patch('pkgcheck.addons.caches.os.unlink') as unlink, \ - patch('sys.argv', self.args + [arg] + ['-t', 'profiles']): - unlink.side_effect = IOError('bad perms') + for arg in ("-R", "--remove"): + with patch("pkgcheck.addons.caches.os.unlink") as unlink, patch( + "sys.argv", self.args + [arg] + ["-t", "profiles"] + ): + unlink.side_effect = IOError("bad perms") with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not out assert os.listdir(self.cache_dir) - assert err.startswith('pkgcheck cache: error: failed removing profiles cache') + assert err.startswith("pkgcheck cache: error: failed removing profiles cache") assert excinfo.value.code == 2 # actually remove it - for arg in ('-R', '--remove'): - with patch('sys.argv', self.args + [arg] + ['-t', 'profiles']): + for arg in ("-R", "--remove"): + with patch("sys.argv", self.args + [arg] + ["-t", "profiles"]): with pytest.raises(SystemExit): self.script() # verify it's gone - with patch('sys.argv', self.args): + with patch("sys.argv", self.args): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() - assert (out, err) == ('', '') + assert (out, err) == ("", "") assert excinfo.value.code == 0 def test_cache_forced_removal(self, capsys): # force standalone repo profiles cache regen - with patch('sys.argv', self.args + ['-uf']): + with patch("sys.argv", self.args + ["-uf"]): with pytest.raises(SystemExit): self.script() # fail to forcibly remove all - with patch('pkgcheck.addons.caches.shutil.rmtree') as rmtree, \ - patch('sys.argv', self.args + ['-Rf']): - rmtree.side_effect = IOError('bad perms') + with patch("pkgcheck.addons.caches.shutil.rmtree") as rmtree, patch( + "sys.argv", self.args + ["-Rf"] + ): + rmtree.side_effect = IOError("bad perms") with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not out - assert err.strip() == 'pkgcheck cache: error: failed removing cache dir: bad perms' + assert err.strip() == "pkgcheck cache: error: failed removing cache dir: bad perms" assert excinfo.value.code == 2 # actually forcibly remove all - with patch('sys.argv', self.args + ['-Rf']): + with patch("sys.argv", self.args + ["-Rf"]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() - assert (out, err) == ('', '') + assert (out, err) == ("", "") assert excinfo.value.code == 0 # cache dir has been entirely blown away assert not os.path.exists(self.cache_dir) # forcing removal again does nothing - with patch('sys.argv', self.args + ['-Rf']): + with patch("sys.argv", self.args + ["-Rf"]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() - assert (out, err) == ('', '') + assert (out, err) == ("", "") assert excinfo.value.code == 0 diff --git a/tests/scripts/test_pkgcheck_ci.py b/tests/scripts/test_pkgcheck_ci.py index 2ac21d7c..bc0d9cbf 100644 --- a/tests/scripts/test_pkgcheck_ci.py +++ b/tests/scripts/test_pkgcheck_ci.py @@ -10,61 +10,61 @@ from pkgcore.ebuild.cpv import VersionedCPV class TestPkgcheckCi: - script = partial(run, 'pkgcheck') + script = partial(run, "pkgcheck") @pytest.fixture(autouse=True) def _setup(self, testconfig, tmp_path): self.cache_dir = str(tmp_path) - base_args = ['--config', testconfig] - self.scan_args = ['--config', 'no', '--cache-dir', self.cache_dir] + base_args = ["--config", testconfig] + self.scan_args = ["--config", "no", "--cache-dir", self.cache_dir] # args for running pkgcheck like a script - self.args = ['pkgcheck'] + base_args + ['ci'] + self.scan_args + self.args = ["pkgcheck"] + base_args + ["ci"] + self.scan_args def test_empty_repo(self, capsys, repo): - with patch('sys.argv', self.args + [repo.location]): + with patch("sys.argv", self.args + [repo.location]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 0 out, err = capsys.readouterr() - assert out == err == '' + assert out == err == "" def test_exit_status(self, repo): # create good ebuild and another with an invalid EAPI - repo.create_ebuild('cat/pkg-0') - repo.create_ebuild('cat/pkg-1', eapi='-1') + repo.create_ebuild("cat/pkg-0") + repo.create_ebuild("cat/pkg-1", eapi="-1") # exit status isn't enabled by default - args = ['-r', repo.location] - with patch('sys.argv', self.args + args): + args = ["-r", repo.location] + with patch("sys.argv", self.args + args): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 0 # all error level results are flagged by default when enabled - with patch('sys.argv', self.args + args + ['--exit']): + with patch("sys.argv", self.args + args + ["--exit"]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 1 # selective error results will only flag those specified - with patch('sys.argv', self.args + args + ['--exit', 'InvalidSlot']): + with patch("sys.argv", self.args + args + ["--exit", "InvalidSlot"]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 0 - with patch('sys.argv', self.args + args + ['--exit', 'InvalidEapi']): + with patch("sys.argv", self.args + args + ["--exit", "InvalidEapi"]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 1 def test_failures(self, tmp_path, repo): - repo.create_ebuild('cat/pkg-1', slot='') - failures = str(tmp_path / 'failures.json') - args = ['--failures', failures, '--exit', '-r', repo.location] - with patch('sys.argv', self.args + args): + repo.create_ebuild("cat/pkg-1", slot="") + failures = str(tmp_path / "failures.json") + args = ["--failures", failures, "--exit", "-r", repo.location] + with patch("sys.argv", self.args + args): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 1 with open(str(failures)) as f: results = list(JsonStream.from_iter(f)) - pkg = VersionedCPV('cat/pkg-1') - assert results == [InvalidSlot('slot', 'SLOT cannot be unset or empty', pkg=pkg)] + pkg = VersionedCPV("cat/pkg-1") + assert results == [InvalidSlot("slot", "SLOT cannot be unset or empty", pkg=pkg)] diff --git a/tests/scripts/test_pkgcheck_replay.py b/tests/scripts/test_pkgcheck_replay.py index 67ad3486..c2aeda66 100644 --- a/tests/scripts/test_pkgcheck_replay.py +++ b/tests/scripts/test_pkgcheck_replay.py @@ -18,70 +18,69 @@ class TestPkgcheckReplay: @pytest.fixture(autouse=True) def _setup(self, testconfig): - self.args = [project, '--config', testconfig, 'replay'] + self.args = [project, "--config", testconfig, "replay"] def test_missing_file_arg(self, capsys): - with patch('sys.argv', self.args): + with patch("sys.argv", self.args): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not out - err = err.strip().split('\n') + err = err.strip().split("\n") assert len(err) == 1 - assert err[0] == ( - 'pkgcheck replay: error: the following arguments are required: FILE') + assert err[0] == ("pkgcheck replay: error: the following arguments are required: FILE") assert excinfo.value.code == 2 def test_replay(self, capsys): - result = ProfileWarning('profile warning: foo') + result = ProfileWarning("profile warning: foo") with tempfile.NamedTemporaryFile() as f: out = PlainTextFormatter(f) with JsonStream(out) as reporter: reporter.report(result) - with patch('sys.argv', self.args + ['-R', 'StrReporter', f.name]): + with patch("sys.argv", self.args + ["-R", "StrReporter", f.name]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - assert out == 'profile warning: foo\n' + assert out == "profile warning: foo\n" assert excinfo.value.code == 0 def test_corrupted_resuts(self, capsys): - result = ProfileWarning('profile warning: foo') + result = ProfileWarning("profile warning: foo") with tempfile.NamedTemporaryFile() as f: out = PlainTextFormatter(f) with JsonStream(out) as reporter: reporter.report(result) - f.write(b'corrupted') + f.write(b"corrupted") f.seek(0) - with patch('sys.argv', self.args + ['-R', 'StrReporter', f.name]): + with patch("sys.argv", self.args + ["-R", "StrReporter", f.name]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() - assert 'corrupted results file' in err + assert "corrupted results file" in err assert excinfo.value.code == 2 def test_invalid_file(self, capsys): - with tempfile.NamedTemporaryFile(mode='wt') as f: - f.write('invalid file') + with tempfile.NamedTemporaryFile(mode="wt") as f: + f.write("invalid file") f.seek(0) - with patch('sys.argv', self.args + ['-R', 'StrReporter', f.name]): + with patch("sys.argv", self.args + ["-R", "StrReporter", f.name]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() - assert err.strip() == 'pkgcheck replay: error: invalid or unsupported replay file' + assert err.strip() == "pkgcheck replay: error: invalid or unsupported replay file" assert excinfo.value.code == 2 def test_replay_pipe_stdin(self): - script = pytest.REPO_ROOT / 'bin/pkgcheck' - result = ProfileWarning('profile warning: foo') + script = pytest.REPO_ROOT / "bin/pkgcheck" + result = ProfileWarning("profile warning: foo") with tempfile.NamedTemporaryFile() as f: out = PlainTextFormatter(f) with JsonStream(out) as reporter: reporter.report(result) f.seek(0) p = subprocess.run( - [script, 'replay', '-R', 'StrReporter', '-'], - stdin=f, stdout=subprocess.PIPE) - assert p.stdout.decode() == 'profile warning: foo\n' + [script, "replay", "-R", "StrReporter", "-"], stdin=f, stdout=subprocess.PIPE + ) + assert p.stdout.decode() == "profile warning: foo\n" assert p.returncode == 0 diff --git a/tests/scripts/test_pkgcheck_scan.py b/tests/scripts/test_pkgcheck_scan.py index c224d83a..bba0547d 100644 --- a/tests/scripts/test_pkgcheck_scan.py +++ b/tests/scripts/test_pkgcheck_scan.py @@ -28,36 +28,35 @@ from ..misc import Profile class TestPkgcheckScanParseArgs: - def test_skipped_checks(self, tool): - options, _ = tool.parse_args(['scan']) + options, _ = tool.parse_args(["scan"]) assert options.enabled_checks # some checks should always be skipped by default assert set(options.enabled_checks) != set(objects.CHECKS.values()) def test_enabled_check(self, tool): - options, _ = tool.parse_args(['scan', '-c', 'PkgDirCheck']) + options, _ = tool.parse_args(["scan", "-c", "PkgDirCheck"]) assert options.enabled_checks == {checks_mod.pkgdir.PkgDirCheck} def test_disabled_check(self, tool): - options, _ = tool.parse_args(['scan']) + options, _ = tool.parse_args(["scan"]) assert checks_mod.pkgdir.PkgDirCheck in options.enabled_checks - options, _ = tool.parse_args(['scan', '-c=-PkgDirCheck']) + options, _ = tool.parse_args(["scan", "-c=-PkgDirCheck"]) assert options.enabled_checks assert checks_mod.pkgdir.PkgDirCheck not in options.enabled_checks def test_targets(self, tool): - options, _ = tool.parse_args(['scan', 'dev-util/foo']) - assert list(options.restrictions) == [(base.package_scope, atom.atom('dev-util/foo'))] + options, _ = tool.parse_args(["scan", "dev-util/foo"]) + assert list(options.restrictions) == [(base.package_scope, atom.atom("dev-util/foo"))] def test_stdin_targets(self, tool): - with patch('sys.stdin', StringIO('dev-util/foo')): - options, _ = tool.parse_args(['scan', '-']) - assert list(options.restrictions) == [(base.package_scope, atom.atom('dev-util/foo'))] + with patch("sys.stdin", StringIO("dev-util/foo")): + options, _ = tool.parse_args(["scan", "-"]) + assert list(options.restrictions) == [(base.package_scope, atom.atom("dev-util/foo"))] def test_invalid_targets(self, tool, capsys): with pytest.raises(SystemExit) as excinfo: - options, _ = tool.parse_args(['scan', 'dev-util/f$o']) + options, _ = tool.parse_args(["scan", "dev-util/f$o"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() err = err.strip() @@ -65,91 +64,97 @@ class TestPkgcheckScanParseArgs: def test_unknown_path_target(self, tool, capsys): with pytest.raises(SystemExit) as excinfo: - tool.parse_args(['scan', '/foo/bar']) + tool.parse_args(["scan", "/foo/bar"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') + err = err.strip().split("\n") assert err[-1].startswith( - "pkgcheck scan: error: 'standalone' repo doesn't contain: '/foo/bar'") + "pkgcheck scan: error: 'standalone' repo doesn't contain: '/foo/bar'" + ) def test_target_repo_id(self, tool): - options, _ = tool.parse_args(['scan', 'standalone']) - assert options.target_repo.repo_id == 'standalone' + options, _ = tool.parse_args(["scan", "standalone"]) + assert options.target_repo.repo_id == "standalone" assert list(options.restrictions) == [(base.repo_scope, packages.AlwaysTrue)] def test_target_dir_path(self, repo, tool): - options, _ = tool.parse_args(['scan', repo.location]) - assert options.target_repo.repo_id == 'fake' + options, _ = tool.parse_args(["scan", repo.location]) + assert options.target_repo.repo_id == "fake" assert list(options.restrictions) == [(base.repo_scope, packages.AlwaysTrue)] def test_target_dir_path_in_repo(self, repo, tool): - path = pjoin(repo.location, 'profiles') - options, _ = tool.parse_args(['scan', path]) - assert options.target_repo.repo_id == 'fake' + path = pjoin(repo.location, "profiles") + options, _ = tool.parse_args(["scan", path]) + assert options.target_repo.repo_id == "fake" assert list(options.restrictions) == [(base.profiles_scope, packages.AlwaysTrue)] def test_target_dir_path_in_configured_repo(self, tool): - options, _ = tool.parse_args(['scan', 'standalone']) - path = pjoin(options.target_repo.location, 'profiles') - options, _ = tool.parse_args(['scan', path]) - assert options.target_repo.repo_id == 'standalone' + options, _ = tool.parse_args(["scan", "standalone"]) + path = pjoin(options.target_repo.location, "profiles") + options, _ = tool.parse_args(["scan", path]) + assert options.target_repo.repo_id == "standalone" assert list(options.restrictions) == [(base.profiles_scope, packages.AlwaysTrue)] def test_target_non_repo_path(self, tool, capsys, tmp_path): with pytest.raises(SystemExit) as excinfo: - tool.parse_args(['scan', str(tmp_path)]) + tool.parse_args(["scan", str(tmp_path)]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out assert err.startswith( - f"pkgcheck scan: error: 'standalone' repo doesn't contain: '{str(tmp_path)}'") + f"pkgcheck scan: error: 'standalone' repo doesn't contain: '{str(tmp_path)}'" + ) def test_target_invalid_repo(self, tool, capsys, make_repo): - repo = make_repo(masters=['unknown']) + repo = make_repo(masters=["unknown"]) with pytest.raises(SystemExit) as excinfo: - tool.parse_args(['scan', repo.location]) + tool.parse_args(["scan", repo.location]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out err = err.strip() - assert err.startswith('pkgcheck scan: error: repo init failed') + assert err.startswith("pkgcheck scan: error: repo init failed") assert err.endswith("has missing masters: 'unknown'") def test_target_file_path(self, repo, tool): - os.makedirs(pjoin(repo.location, 'dev-util', 'foo')) - ebuild_path = pjoin(repo.location, 'dev-util', 'foo', 'foo-0.ebuild') + os.makedirs(pjoin(repo.location, "dev-util", "foo")) + ebuild_path = pjoin(repo.location, "dev-util", "foo", "foo-0.ebuild") touch(ebuild_path) - options, _ = tool.parse_args(['scan', ebuild_path]) + options, _ = tool.parse_args(["scan", ebuild_path]) restrictions = [ - restricts.CategoryDep('dev-util'), - restricts.PackageDep('foo'), - restricts.VersionMatch('=', '0'), + restricts.CategoryDep("dev-util"), + restricts.PackageDep("foo"), + restricts.VersionMatch("=", "0"), + ] + assert list(options.restrictions) == [ + (base.version_scope, packages.AndRestriction(*restrictions)) ] - assert list(options.restrictions) == [(base.version_scope, packages.AndRestriction(*restrictions))] - assert options.target_repo.repo_id == 'fake' + assert options.target_repo.repo_id == "fake" def test_target_package_dir_cwd(self, repo, tool): - os.makedirs(pjoin(repo.location, 'dev-util', 'foo')) - with chdir(pjoin(repo.location, 'dev-util', 'foo')): - options, _ = tool.parse_args(['scan']) - assert options.target_repo.repo_id == 'fake' + os.makedirs(pjoin(repo.location, "dev-util", "foo")) + with chdir(pjoin(repo.location, "dev-util", "foo")): + options, _ = tool.parse_args(["scan"]) + assert options.target_repo.repo_id == "fake" restrictions = [ - restricts.CategoryDep('dev-util'), - restricts.PackageDep('foo'), + restricts.CategoryDep("dev-util"), + restricts.PackageDep("foo"), + ] + assert list(options.restrictions) == [ + (base.package_scope, packages.AndRestriction(*restrictions)) ] - assert list(options.restrictions) == [(base.package_scope, packages.AndRestriction(*restrictions))] def test_target_repo_dir_cwd(self, repo, tool): with chdir(repo.location): - options, _ = tool.parse_args(['scan']) - assert options.target_repo.repo_id == 'fake' + options, _ = tool.parse_args(["scan"]) + assert options.target_repo.repo_id == "fake" assert list(options.restrictions) == [(base.repo_scope, packages.AlwaysTrue)] def test_unknown_repo(self, tmp_path, capsys, tool): - for opt in ('-r', '--repo'): + for opt in ("-r", "--repo"): with pytest.raises(SystemExit) as excinfo: with chdir(str(tmp_path)): - options, _ = tool.parse_args(['scan', opt, 'foo']) + options, _ = tool.parse_args(["scan", opt, "foo"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out @@ -158,27 +163,26 @@ class TestPkgcheckScanParseArgs: ) def test_invalid_repo(self, tmp_path, capsys, tool): - (tmp_path / 'foo').touch() - for opt in ('-r', '--repo'): + (tmp_path / "foo").touch() + for opt in ("-r", "--repo"): with pytest.raises(SystemExit) as excinfo: with chdir(str(tmp_path)): - options, _ = tool.parse_args(['scan', opt, 'foo']) + options, _ = tool.parse_args(["scan", opt, "foo"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out - assert err.startswith( - "pkgcheck scan: error: argument -r/--repo: repo init failed:") + assert err.startswith("pkgcheck scan: error: argument -r/--repo: repo init failed:") def test_valid_repo(self, tool): - for opt in ('-r', '--repo'): - options, _ = tool.parse_args(['scan', opt, 'standalone']) - assert options.target_repo.repo_id == 'standalone' + for opt in ("-r", "--repo"): + options, _ = tool.parse_args(["scan", opt, "standalone"]) + assert options.target_repo.repo_id == "standalone" assert list(options.restrictions) == [(base.repo_scope, packages.AlwaysTrue)] def test_unknown_reporter(self, capsys, tool): - for opt in ('-R', '--reporter'): + for opt in ("-R", "--reporter"): with pytest.raises(SystemExit) as excinfo: - options, _ = tool.parse_args(['scan', opt, 'foo']) + options, _ = tool.parse_args(["scan", opt, "foo"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out @@ -187,161 +191,185 @@ class TestPkgcheckScanParseArgs: def test_format_reporter(self, capsys, tool): # missing --format with pytest.raises(SystemExit) as excinfo: - tool.parse_args(['scan', '-R', 'FormatReporter']) + tool.parse_args(["scan", "-R", "FormatReporter"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') - assert err[-1].endswith( - "missing or empty --format option required by FormatReporter") + err = err.strip().split("\n") + assert err[-1].endswith("missing or empty --format option required by FormatReporter") # missing -R FormatReporter with pytest.raises(SystemExit) as excinfo: - tool.parse_args(['scan', '--format', 'foo']) + tool.parse_args(["scan", "--format", "foo"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() - err = err.strip().split('\n') - assert err[-1].endswith( - "--format option is only valid when using FormatReporter") + err = err.strip().split("\n") + assert err[-1].endswith("--format option is only valid when using FormatReporter") # properly set - options, _ = tool.parse_args( - ['scan', '-R', 'FormatReporter', '--format', 'foo']) + options, _ = tool.parse_args(["scan", "-R", "FormatReporter", "--format", "foo"]) def test_cwd(self, capsys, tool): # regularly working - options, _ = tool.parse_args(['scan']) + options, _ = tool.parse_args(["scan"]) assert options.cwd == os.getcwd() # pretend the CWD was removed out from under us - with patch('os.getcwd') as getcwd: - getcwd.side_effect = FileNotFoundError('CWD is gone') - options, _ = tool.parse_args(['scan']) + with patch("os.getcwd") as getcwd: + getcwd.side_effect = FileNotFoundError("CWD is gone") + options, _ = tool.parse_args(["scan"]) assert options.cwd == const.DATA_PATH def test_eclass_target(self, fakerepo, tool): - (eclass_dir := fakerepo / 'eclass').mkdir() - (eclass_path := eclass_dir / 'foo.eclass').touch() - options, _ = tool.parse_args(['scan', str(eclass_path)]) - assert list(options.restrictions) == [(base.eclass_scope, 'foo')] + (eclass_dir := fakerepo / "eclass").mkdir() + (eclass_path := eclass_dir / "foo.eclass").touch() + options, _ = tool.parse_args(["scan", str(eclass_path)]) + assert list(options.restrictions) == [(base.eclass_scope, "foo")] def test_profiles_target(self, fakerepo, tool): - profiles_path = str(fakerepo / 'profiles') - options, _ = tool.parse_args(['scan', profiles_path]) + profiles_path = str(fakerepo / "profiles") + options, _ = tool.parse_args(["scan", profiles_path]) assert list(options.restrictions) == [(base.profiles_scope, packages.AlwaysTrue)] def test_profiles_path_target_file(self, fakerepo, tool): - (pkg_mask_path := fakerepo / 'profiles/package.mask').touch() - options, _ = tool.parse_args(['scan', str(pkg_mask_path)]) + (pkg_mask_path := fakerepo / "profiles/package.mask").touch() + options, _ = tool.parse_args(["scan", str(pkg_mask_path)]) assert list(options.restrictions) == [(base.profile_node_scope, str(pkg_mask_path))] def test_profiles_path_target_dir(self, fakerepo, tool): - (profile_dir := fakerepo / 'profiles/default').mkdir(parents=True) - (pkg_mask_path := profile_dir / 'package.mask').touch() - (pkg_use_path := profile_dir / 'package.use').touch() - options, _ = tool.parse_args(['scan', str(profile_dir)]) - assert list(options.restrictions) == [(base.profile_node_scope, {str(pkg_mask_path), str(pkg_use_path)})] + (profile_dir := fakerepo / "profiles/default").mkdir(parents=True) + (pkg_mask_path := profile_dir / "package.mask").touch() + (pkg_use_path := profile_dir / "package.use").touch() + options, _ = tool.parse_args(["scan", str(profile_dir)]) + assert list(options.restrictions) == [ + (base.profile_node_scope, {str(pkg_mask_path), str(pkg_use_path)}) + ] def test_no_default_repo(self, tool, capsys): - stubconfig = pjoin(pkgcore_const.DATA_PATH, 'stubconfig') + stubconfig = pjoin(pkgcore_const.DATA_PATH, "stubconfig") with pytest.raises(SystemExit) as excinfo: - tool.parse_args(['--config', stubconfig, 'scan']) + tool.parse_args(["--config", stubconfig, "scan"]) assert excinfo.value.code == 2 out, err = capsys.readouterr() assert not out assert err.strip() == "pkgcheck scan: error: no default repo found" - @pytest.mark.parametrize(('makeopts', 'expected_jobs'), ( - ('', 4), - ('-j1', 1), - ('--jobs=6 -l 1', 6), - ('--load 1', 4), - )) + @pytest.mark.parametrize( + ("makeopts", "expected_jobs"), + ( + ("", 4), + ("-j1", 1), + ("--jobs=6 -l 1", 6), + ("--load 1", 4), + ), + ) def test_makeopts_parsing(self, parser, makeopts, expected_jobs): - with patch('os.cpu_count', return_value=4), \ - os_environ(MAKEOPTS=makeopts): + with patch("os.cpu_count", return_value=4), os_environ(MAKEOPTS=makeopts): - options = parser.parse_args(['scan']) + options = parser.parse_args(["scan"]) assert options.jobs == expected_jobs assert options.tasks == 5 * expected_jobs def test_no_color(self, parser, tmp_path): - (config_file := tmp_path / 'config').write_text(textwrap.dedent('''\ - [DEFAULT] - color = true - ''')) + (config_file := tmp_path / "config").write_text( + textwrap.dedent( + """\ + [DEFAULT] + color = true + """ + ) + ) - args = ('scan', '--config', str(config_file)) - with os_environ('NOCOLOR'): + args = ("scan", "--config", str(config_file)) + with os_environ("NOCOLOR"): assert parser.parse_args(args).color is True - with os_environ(NOCOLOR='1'): + with os_environ(NOCOLOR="1"): # NOCOLOR overrides config file assert parser.parse_args(args).color is False # cmd line option overrides NOCOLOR - assert parser.parse_args([*args, '--color', 'n']).color is False - assert parser.parse_args([*args, '--color', 'y']).color is True + assert parser.parse_args([*args, "--color", "n"]).color is False + assert parser.parse_args([*args, "--color", "y"]).color is True class TestPkgcheckScanParseConfigArgs: - @pytest.fixture(autouse=True) def _setup(self, parser, tmp_path, repo): self.parser = parser self.repo = repo - self.args = ['scan', '-r', repo.location] + self.args = ["scan", "-r", repo.location] self.system_config = str(tmp_path / "system-config") self.user_config = str(tmp_path / "user-config") self.config = str(tmp_path / "custom-config") def test_config_precedence(self): configs = [self.system_config, self.user_config] - with patch('pkgcheck.cli.ConfigFileParser.default_configs', configs): - with open(self.system_config, 'w') as f: - f.write(textwrap.dedent("""\ - [DEFAULT] - jobs=1000 - """)) + with patch("pkgcheck.cli.ConfigFileParser.default_configs", configs): + with open(self.system_config, "w") as f: + f.write( + textwrap.dedent( + """\ + [DEFAULT] + jobs=1000 + """ + ) + ) options = self.parser.parse_args(self.args) assert options.jobs == 1000 # user config overrides system config - with open(self.user_config, 'w') as f: - f.write(textwrap.dedent("""\ - [DEFAULT] - jobs=1001 - """)) + with open(self.user_config, "w") as f: + f.write( + textwrap.dedent( + """\ + [DEFAULT] + jobs=1001 + """ + ) + ) options = self.parser.parse_args(self.args) assert options.jobs == 1001 # repo config overrides user config - with open(pjoin(self.repo.location, 'metadata', 'pkgcheck.conf'), 'w') as f: - f.write(textwrap.dedent("""\ - [DEFAULT] - jobs=1002 - """)) + with open(pjoin(self.repo.location, "metadata", "pkgcheck.conf"), "w") as f: + f.write( + textwrap.dedent( + """\ + [DEFAULT] + jobs=1002 + """ + ) + ) options = self.parser.parse_args(self.args) assert options.jobs == 1002 # custom config overrides user config - with open(self.config, 'w') as f: - f.write(textwrap.dedent("""\ - [DEFAULT] - jobs=1003 - """)) - config_args = self.args + ['--config', self.config] + with open(self.config, "w") as f: + f.write( + textwrap.dedent( + """\ + [DEFAULT] + jobs=1003 + """ + ) + ) + config_args = self.args + ["--config", self.config] options = self.parser.parse_args(config_args) assert options.jobs == 1003 # repo defaults override general defaults - with open(self.config, 'a') as f: - f.write(textwrap.dedent(f"""\ - [{self.repo.repo_id}] - jobs=1004 - """)) + with open(self.config, "a") as f: + f.write( + textwrap.dedent( + f"""\ + [{self.repo.repo_id}] + jobs=1004 + """ + ) + ) options = self.parser.parse_args(config_args) assert options.jobs == 1004 # command line options override all config settings - options = self.parser.parse_args(config_args + ['--jobs', '9999']) + options = self.parser.parse_args(config_args + ["--jobs", "9999"]) assert options.jobs == 9999 @@ -349,143 +377,146 @@ class TestPkgcheckScan: script = staticmethod(partial(run, project)) - repos_data = pytest.REPO_ROOT / 'testdata/data/repos' - repos_dir = pytest.REPO_ROOT / 'testdata/repos' - repos = tuple(sorted(x.name for x in repos_data.iterdir() if x.name != 'network')) + repos_data = pytest.REPO_ROOT / "testdata/data/repos" + repos_dir = pytest.REPO_ROOT / "testdata/repos" + repos = tuple(sorted(x.name for x in repos_data.iterdir() if x.name != "network")) _all_results = [ (cls, result) for name, cls in sorted(objects.CHECKS.items()) if not issubclass(cls, checks_mod.NetworkCheck) - for result in sorted(cls.known_results, key=attrgetter('__name__')) + for result in sorted(cls.known_results, key=attrgetter("__name__")) ] @pytest.fixture(autouse=True) def _setup(self, testconfig, tmp_path): self.cache_dir = str(tmp_path) - base_args = ['--config', testconfig] + base_args = ["--config", testconfig] self.scan = partial(scan, base_args=base_args) # args for running `pkgcheck scan` via API call - self.scan_args = ['--config', 'no', '--cache-dir', self.cache_dir] + self.scan_args = ["--config", "no", "--cache-dir", self.cache_dir] # args for running pkgcheck like a script - self.args = [project] + base_args + ['scan'] + self.scan_args + self.args = [project] + base_args + ["scan"] + self.scan_args def test_empty_repo(self, capsys, repo): - with patch('sys.argv', self.args + [repo.location]): + with patch("sys.argv", self.args + [repo.location]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 0 out, err = capsys.readouterr() - assert out == err == '' + assert out == err == "" def test_no_matching_checks_scope(self, tool): - options, _ = tool.parse_args(['scan', 'standalone']) - path = pjoin(options.target_repo.location, 'profiles') - error = 'no matching checks available for profiles scope' + options, _ = tool.parse_args(["scan", "standalone"]) + path = pjoin(options.target_repo.location, "profiles") + error = "no matching checks available for profiles scope" with pytest.raises(base.PkgcheckUserException, match=error): - self.scan(self.scan_args + ['-c', 'PkgDirCheck', path]) + self.scan(self.scan_args + ["-c", "PkgDirCheck", path]) def test_stdin_targets_with_no_args(self): - with patch('sys.stdin', StringIO()): - with pytest.raises(base.PkgcheckUserException, match='no targets'): - self.scan(self.scan_args + ['-']) + with patch("sys.stdin", StringIO()): + with pytest.raises(base.PkgcheckUserException, match="no targets"): + self.scan(self.scan_args + ["-"]) def test_exit_status(self, repo): # create good ebuild and another with an invalid EAPI - repo.create_ebuild('newcat/pkg-0') - repo.create_ebuild('newcat/pkg-1', eapi='-1') + repo.create_ebuild("newcat/pkg-0") + repo.create_ebuild("newcat/pkg-1", eapi="-1") # exit status isn't enabled by default - args = ['-r', repo.location] - with patch('sys.argv', self.args + args): + args = ["-r", repo.location] + with patch("sys.argv", self.args + args): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 0 # all error level results are flagged by default when enabled - with patch('sys.argv', self.args + args + ['--exit']): + with patch("sys.argv", self.args + args + ["--exit"]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 1 # selective error results will only flag those specified - with patch('sys.argv', self.args + args + ['--exit', 'InvalidSlot']): + with patch("sys.argv", self.args + args + ["--exit", "InvalidSlot"]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 0 - with patch('sys.argv', self.args + args + ['--exit', 'InvalidEapi']): + with patch("sys.argv", self.args + args + ["--exit", "InvalidEapi"]): with pytest.raises(SystemExit) as excinfo: self.script() assert excinfo.value.code == 1 def test_filter_latest(self, make_repo): - repo = make_repo(arches=['amd64']) + repo = make_repo(arches=["amd64"]) # create stub profile to suppress ArchesWithoutProfiles result - repo.create_profiles([Profile('stub', 'amd64')]) + repo.create_profiles([Profile("stub", "amd64")]) # create ebuild with unknown keywords - repo.create_ebuild('cat/pkg-0', keywords=['unknown'], homepage='https://example.com') + repo.create_ebuild("cat/pkg-0", keywords=["unknown"], homepage="https://example.com") # and a good ebuild for the latest version - repo.create_ebuild('cat/pkg-1', keywords=['amd64'], homepage='https://example.com') + repo.create_ebuild("cat/pkg-1", keywords=["amd64"], homepage="https://example.com") # results for old pkgs will be shown by default - args = ['-r', repo.location] - with patch('sys.argv', self.args + args): + args = ["-r", repo.location] + with patch("sys.argv", self.args + args): results = list(self.scan(self.scan_args + args)) assert len(results) == 1 # but are ignored when running using the 'latest' filter - for opt in ('-f', '--filter'): - for arg in ('latest', 'latest:KeywordsCheck', 'latest:UnknownKeywords'): + for opt in ("-f", "--filter"): + for arg in ("latest", "latest:KeywordsCheck", "latest:UnknownKeywords"): assert not list(self.scan(self.scan_args + args + [opt, arg])) def test_scan_restrictions(self, repo): # create two ebuilds with bad EAPIs - repo.create_ebuild('cat/pkg-0', eapi='-1') - repo.create_ebuild('cat/pkg-1', eapi='-1') + repo.create_ebuild("cat/pkg-0", eapi="-1") + repo.create_ebuild("cat/pkg-1", eapi="-1") # matching version restriction returns a single result - results = list(self.scan(self.scan_args + ['-r', repo.location, '=cat/pkg-0'])) - assert [x.version for x in results] == ['0'] + results = list(self.scan(self.scan_args + ["-r", repo.location, "=cat/pkg-0"])) + assert [x.version for x in results] == ["0"] # unmatching version restriction returns no results - results = list(self.scan(self.scan_args + ['-r', repo.location, '=cat/pkg-2'])) + results = list(self.scan(self.scan_args + ["-r", repo.location, "=cat/pkg-2"])) assert not results # matching package restriction returns two sorted results - results = list(self.scan(self.scan_args + ['-r', repo.location, 'cat/pkg'])) - assert [x.version for x in results] == ['0', '1'] + results = list(self.scan(self.scan_args + ["-r", repo.location, "cat/pkg"])) + assert [x.version for x in results] == ["0", "1"] # unmatching package restriction returns no results - results = list(self.scan(self.scan_args + ['-r', repo.location, 'cat/unknown'])) + results = list(self.scan(self.scan_args + ["-r", repo.location, "cat/unknown"])) assert not results def test_explict_skip_check(self): """SkipCheck exceptions are raised when triggered for explicitly enabled checks.""" - error = 'network checks not enabled' + error = "network checks not enabled" with pytest.raises(base.PkgcheckException, match=error): - self.scan(self.scan_args + ['-C', 'net']) + self.scan(self.scan_args + ["-C", "net"]) def test_cache_disabled_skip_check(self): """SkipCheck exceptions are raised when enabled checks require disabled cache types.""" - args = ['--cache=-git', '-c', 'StableRequestCheck'] - error = 'StableRequestCheck: git cache support required' + args = ["--cache=-git", "-c", "StableRequestCheck"] + error = "StableRequestCheck: git cache support required" with pytest.raises(base.PkgcheckException, match=error): self.scan(self.scan_args + args) - @pytest.mark.parametrize('module', ( - pytest.param('pkgcheck.pipeline.UnversionedSource', id='producer'), - pytest.param('pkgcheck.runners.SyncCheckRunner.run', id='consumer'), - )) + @pytest.mark.parametrize( + "module", + ( + pytest.param("pkgcheck.pipeline.UnversionedSource", id="producer"), + pytest.param("pkgcheck.runners.SyncCheckRunner.run", id="consumer"), + ), + ) def test_pipeline_exceptions(self, module): """Test checkrunner pipeline against unhandled exceptions.""" with patch(module) as faked: - faked.side_effect = Exception('pipeline failed') - with pytest.raises(base.PkgcheckException, match='Exception: pipeline failed'): + faked.side_effect = Exception("pipeline failed") + with pytest.raises(base.PkgcheckException, match="Exception: pipeline failed"): list(self.scan(self.scan_args)) # nested mapping of repos to checks/keywords they cover _checks = defaultdict(lambda: defaultdict(set)) - @pytest.mark.parametrize('repo', repos) + @pytest.mark.parametrize("repo", repos) def test_scan_repo_data(self, repo): """Make sure the test data is up to date check/result naming wise.""" for check in (self.repos_data / repo).iterdir(): @@ -506,19 +537,19 @@ class TestPkgcheckScan: _results = {} _verbose_results = {} - @pytest.mark.parametrize('repo', repos) + @pytest.mark.parametrize("repo", repos) def test_scan_repo(self, repo, tmp_path, verbosity=0): """Scan a target repo, saving results for verification.""" repo_dir = self.repos_dir / repo # run all existing triggers triggers = [ - pjoin(root, 'trigger.sh') + pjoin(root, "trigger.sh") for root, _dirs, files in os.walk(self.repos_data / repo) - if 'trigger.sh' in files + if "trigger.sh" in files ] if triggers: - triggered_repo = tmp_path / f'triggered-{repo}' + triggered_repo = tmp_path / f"triggered-{repo}" shutil.copytree(repo_dir, triggered_repo) for trigger in triggers: self._script(trigger, triggered_repo) @@ -526,19 +557,19 @@ class TestPkgcheckScan: if repo not in self._checks: self.test_scan_repo_data(repo) - args = (['-v'] * verbosity) + ['-r', str(repo_dir), '-c', ','.join(self._checks[repo])] + args = (["-v"] * verbosity) + ["-r", str(repo_dir), "-c", ",".join(self._checks[repo])] # add any defined extra repo args try: - args.extend(shlex.split((repo_dir / 'metadata/pkgcheck-args').read_text())) + args.extend(shlex.split((repo_dir / "metadata/pkgcheck-args").read_text())) except FileNotFoundError: pass results = [] for result in self.scan(self.scan_args + args): # ignore results generated from stubs - stubs = (getattr(result, x, '') for x in ('category', 'package')) - if any(x.startswith('stub') for x in stubs): + stubs = (getattr(result, x, "") for x in ("category", "package")) + if any(x.startswith("stub") for x in stubs): continue results.append(result) @@ -549,7 +580,7 @@ class TestPkgcheckScan: self._results[repo] = set(results) assert len(results) == len(self._results[repo]) - @pytest.mark.parametrize('repo', repos) + @pytest.mark.parametrize("repo", repos) def test_scan_repo_verbose(self, repo, tmp_path): """Scan a target repo in verbose mode, saving results for verification.""" return self.test_scan_repo(repo, tmp_path, verbosity=1) @@ -572,7 +603,7 @@ class TestPkgcheckScan: output = f.read().decode() return output - @pytest.mark.parametrize('repo', repos) + @pytest.mark.parametrize("repo", repos) def test_scan_verify(self, repo, tmp_path): """Run pkgcheck against test pkgs in bundled repo, verifying result output.""" results = set() @@ -584,15 +615,19 @@ class TestPkgcheckScan: for check, keywords in self._checks[repo].items(): for keyword in keywords: # verify the expected results were seen during the repo scans - expected_results = self._get_results(f'{repo}/{check}/{keyword}/expected.json') - assert expected_results, 'regular results must always exist' - assert self._render_results(expected_results), 'failed rendering results' + expected_results = self._get_results(f"{repo}/{check}/{keyword}/expected.json") + assert expected_results, "regular results must always exist" + assert self._render_results(expected_results), "failed rendering results" results.update(expected_results) # when expected verbose results exist use them, otherwise fallback to using the regular ones - expected_verbose_results = self._get_results(f'{repo}/{check}/{keyword}/expected-verbose.json') + expected_verbose_results = self._get_results( + f"{repo}/{check}/{keyword}/expected-verbose.json" + ) if expected_verbose_results: - assert self._render_results(expected_verbose_results), 'failed rendering verbose results' + assert self._render_results( + expected_verbose_results + ), "failed rendering verbose results" verbose_results.update(expected_verbose_results) else: verbose_results.update(expected_results) @@ -600,34 +635,39 @@ class TestPkgcheckScan: if results != self._results[repo]: missing = self._render_results(results - self._results[repo]) unknown = self._render_results(self._results[repo] - results) - error = ['unmatched repo scan results:'] + error = ["unmatched repo scan results:"] if missing: - error.append(f'{repo} repo missing expected results:\n{missing}') + error.append(f"{repo} repo missing expected results:\n{missing}") if unknown: - error.append(f'{repo} repo unknown results:\n{unknown}') - pytest.fail('\n'.join(error)) + error.append(f"{repo} repo unknown results:\n{unknown}") + pytest.fail("\n".join(error)) if verbose_results != self._verbose_results[repo]: missing = self._render_results(verbose_results - self._verbose_results[repo]) unknown = self._render_results(self._verbose_results[repo] - verbose_results) - error = ['unmatched verbose repo scan results:'] + error = ["unmatched verbose repo scan results:"] if missing: - error.append(f'{repo} repo missing expected results:\n{missing}') + error.append(f"{repo} repo missing expected results:\n{missing}") if unknown: - error.append(f'{repo} repo unknown results:\n{unknown}') - pytest.fail('\n'.join(error)) + error.append(f"{repo} repo unknown results:\n{unknown}") + pytest.fail("\n".join(error)) @staticmethod def _patch(fix, repo_path): with fix.open() as fix_file: try: subprocess.run( - ['patch', '-p1'], cwd=repo_path, stdin=fix_file, - capture_output=True, check=True, text=True) + ["patch", "-p1"], + cwd=repo_path, + stdin=fix_file, + capture_output=True, + check=True, + text=True, + ) except subprocess.CalledProcessError as exc: error = exc.stderr if exc.stderr else exc.stdout pytest.fail(error) - @pytest.mark.parametrize('check, result', _all_results) + @pytest.mark.parametrize("check, result", _all_results) def test_fix(self, check, result, tmp_path): """Apply fixes to pkgs, verifying the related results are fixed.""" check_name = check.__name__ @@ -635,36 +675,36 @@ class TestPkgcheckScan: tested = False for repo in self.repos: keyword_dir = self.repos_data / repo / check_name / keyword - if (fix := keyword_dir / 'fix.patch').exists(): + if (fix := keyword_dir / "fix.patch").exists(): func = self._patch - elif (fix := keyword_dir / 'fix.sh').exists(): + elif (fix := keyword_dir / "fix.sh").exists(): func = self._script else: continue # apply a fix if one exists and make sure the related result doesn't appear repo_dir = self.repos_dir / repo - fixed_repo = tmp_path / f'fixed-{repo}' + fixed_repo = tmp_path / f"fixed-{repo}" shutil.copytree(repo_dir, fixed_repo) func(fix, fixed_repo) - args = ['-r', str(fixed_repo), '-c', check_name, '-k', keyword] + args = ["-r", str(fixed_repo), "-c", check_name, "-k", keyword] # add any defined extra repo args try: - with open(f'{repo_dir}/metadata/pkgcheck-args') as f: + with open(f"{repo_dir}/metadata/pkgcheck-args") as f: args.extend(shlex.split(f.read())) except FileNotFoundError: pass results = list(self.scan(self.scan_args + args)) if results: - error = ['unexpected repo scan results:'] + error = ["unexpected repo scan results:"] error.append(self._render_results(results)) - pytest.fail('\n'.join(error)) + pytest.fail("\n".join(error)) shutil.rmtree(fixed_repo) tested = True if not tested: - pytest.skip('fix not available') + pytest.skip("fix not available") diff --git a/tests/scripts/test_pkgcheck_show.py b/tests/scripts/test_pkgcheck_show.py index 4557ecfd..ee40f7cf 100644 --- a/tests/scripts/test_pkgcheck_show.py +++ b/tests/scripts/test_pkgcheck_show.py @@ -15,39 +15,39 @@ class TestPkgcheckShow: @pytest.fixture(autouse=True) def _setup(self, testconfig): - self.args = [project, '--config', testconfig, 'show'] + self.args = [project, "--config", testconfig, "show"] def test_show_no_args(self, capsys): # defaults to outputting keywords list if no option is passed - with patch('sys.argv', self.args): + with patch("sys.argv", self.args): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") assert out == sorted(objects.KEYWORDS.keys()) assert excinfo.value.code == 0 def test_show_keywords(self, capsys): - for arg in ('-k', '--keywords'): + for arg in ("-k", "--keywords"): # regular mode - with patch('sys.argv', self.args + [arg]): + with patch("sys.argv", self.args + [arg]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") regular_output = out assert out == sorted(objects.KEYWORDS.keys()) assert excinfo.value.code == 0 # verbose mode - with patch('sys.argv', self.args + [arg, '-v']): + with patch("sys.argv", self.args + [arg, "-v"]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") verbose_output = out assert excinfo.value.code == 0 @@ -55,25 +55,25 @@ class TestPkgcheckShow: assert len(regular_output) < len(verbose_output) def test_show_checks(self, capsys): - for arg in ('-c', '--checks'): + for arg in ("-c", "--checks"): # regular mode - with patch('sys.argv', self.args + [arg]): + with patch("sys.argv", self.args + [arg]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") regular_output = out assert out == sorted(objects.CHECKS.keys()) assert excinfo.value.code == 0 # verbose mode - with patch('sys.argv', self.args + [arg, '-v']): + with patch("sys.argv", self.args + [arg, "-v"]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") verbose_output = out assert excinfo.value.code == 0 @@ -81,50 +81,50 @@ class TestPkgcheckShow: assert len(regular_output) < len(verbose_output) def test_show_scopes(self, capsys): - for arg in ('-s', '--scopes'): - with patch('sys.argv', self.args + [arg]): + for arg in ("-s", "--scopes"): + with patch("sys.argv", self.args + [arg]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") assert out == list(base.scopes) assert excinfo.value.code == 0 - regular_output = '\n'.join(itertools.chain(out)) + regular_output = "\n".join(itertools.chain(out)) # verbose mode - with patch('sys.argv', self.args + [arg, '-v']): + with patch("sys.argv", self.args + [arg, "-v"]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") assert excinfo.value.code == 0 - verbose_output = '\n'.join(itertools.chain(out)) + verbose_output = "\n".join(itertools.chain(out)) # verbose output shows more info assert len(regular_output) < len(verbose_output) def test_show_reporters(self, capsys): - for arg in ('-r', '--reporters'): + for arg in ("-r", "--reporters"): # regular mode - with patch('sys.argv', self.args + [arg]): + with patch("sys.argv", self.args + [arg]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") regular_output = out assert out == sorted(objects.REPORTERS.keys()) assert excinfo.value.code == 0 # verbose mode - with patch('sys.argv', self.args + [arg, '-v']): + with patch("sys.argv", self.args + [arg, "-v"]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") verbose_output = out assert excinfo.value.code == 0 @@ -132,27 +132,27 @@ class TestPkgcheckShow: assert len(regular_output) < len(verbose_output) def test_show_caches(self, capsys): - for arg in ('-C', '--caches'): - with patch('sys.argv', self.args + [arg]): + for arg in ("-C", "--caches"): + with patch("sys.argv", self.args + [arg]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") cache_objs = caches.CachedAddon.caches.values() assert out == sorted(x.type for x in cache_objs) assert excinfo.value.code == 0 - regular_output = '\n'.join(itertools.chain(out)) + regular_output = "\n".join(itertools.chain(out)) # verbose mode - with patch('sys.argv', self.args + [arg, '-v']): + with patch("sys.argv", self.args + [arg, "-v"]): with pytest.raises(SystemExit) as excinfo: self.script() out, err = capsys.readouterr() assert not err - out = out.strip().split('\n') + out = out.strip().split("\n") assert excinfo.value.code == 0 - verbose_output = '\n'.join(itertools.chain(out)) + verbose_output = "\n".join(itertools.chain(out)) # verbose output shows more info assert len(regular_output) < len(verbose_output) diff --git a/tests/test_api.py b/tests/test_api.py index f3db534b..cf546ee5 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -8,31 +8,32 @@ from pkgcheck import objects class TestScanApi: - @pytest.fixture(autouse=True) def _setup(self, testconfig): - self.base_args = ['--config', testconfig] - self.scan_args = ['--config', 'no', '--cache', 'no'] + self.base_args = ["--config", testconfig] + self.scan_args = ["--config", "no", "--cache", "no"] def test_argparse_error(self, repo): - with pytest.raises(PkgcheckException, match='unrecognized arguments'): - scan(['-r', repo.location, '--foo']) + with pytest.raises(PkgcheckException, match="unrecognized arguments"): + scan(["-r", repo.location, "--foo"]) def test_no_scan_args(self): pipe = scan(base_args=self.base_args) - assert pipe.options.target_repo.repo_id == 'standalone' + assert pipe.options.target_repo.repo_id == "standalone" def test_no_base_args(self, repo): - assert [] == list(scan(self.scan_args + ['-r', repo.location])) + assert [] == list(scan(self.scan_args + ["-r", repo.location])) def test_keyword_import(self): """Keyword classes are importable from the top-level module.""" from pkgcheck import NonsolvableDeps, Result + assert issubclass(NonsolvableDeps, Result) def test_module_attributes(self): """All keyword class names are shown for the top-level module.""" import pkgcheck + assert set(objects.KEYWORDS) < set(dir(pkgcheck)) def test_sigint_handling(self, repo): @@ -49,10 +50,10 @@ class TestScanApi: def sleep(): """Notify testing process then sleep.""" - queue.put('ready') + queue.put("ready") time.sleep(100) - with patch('pkgcheck.pipeline.Pipeline.__iter__') as fake_iter: + with patch("pkgcheck.pipeline.Pipeline.__iter__") as fake_iter: fake_iter.side_effect = partial(sleep) try: iter(scan([repo.location])) @@ -62,7 +63,7 @@ class TestScanApi: queue.put(None) sys.exit(1) - mp_ctx = multiprocessing.get_context('fork') + mp_ctx = multiprocessing.get_context("fork") queue = mp_ctx.SimpleQueue() p = mp_ctx.Process(target=run, args=(queue,)) p.start() diff --git a/tests/test_base.py b/tests/test_base.py index 08acaf8d..7c6aa905 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -6,7 +6,6 @@ from pkgcheck.base import ProgressManager class TestScope: - def test_rich_comparisons(self): assert base.commit_scope < base.repo_scope assert base.commit_scope < 0 @@ -32,15 +31,14 @@ class TestScope: class TestProgressManager: - def test_no_output(self, capsys): # output disabled due to lower verbosity setting - with patch('sys.stdout.isatty', return_value=True): + with patch("sys.stdout.isatty", return_value=True): with ProgressManager(verbosity=-1) as progress: for x in range(10): progress(x) # output disabled due to non-tty output - with patch('sys.stdout.isatty', return_value=False): + with patch("sys.stdout.isatty", return_value=False): with ProgressManager(verbosity=1) as progress: for x in range(10): progress(x) @@ -49,20 +47,20 @@ class TestProgressManager: assert not err def test_output(self, capsys): - with patch('sys.stdout.isatty', return_value=True): + with patch("sys.stdout.isatty", return_value=True): with ProgressManager(verbosity=0) as progress: for x in range(10): progress(x) out, err = capsys.readouterr() assert not out - assert not err.strip().split('\r') == list(range(10)) + assert not err.strip().split("\r") == list(range(10)) def test_cached_output(self, capsys): - with patch('sys.stdout.isatty', return_value=True): + with patch("sys.stdout.isatty", return_value=True): with ProgressManager(verbosity=0) as progress: data = list(range(10)) for x in chain.from_iterable(zip(data, data)): progress(x) out, err = capsys.readouterr() assert not out - assert not err.strip().split('\r') == list(range(10)) + assert not err.strip().split("\r") == list(range(10)) diff --git a/tests/test_cli.py b/tests/test_cli.py index 4ad8011d..b2935b28 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -6,10 +6,9 @@ from snakeoil.cli import arghparse class TestConfigFileParser: - @pytest.fixture(autouse=True) def _create_argparser(self, tmp_path): - self.config_file = str(tmp_path / 'config') + self.config_file = str(tmp_path / "config") self.parser = arghparse.ArgumentParser() self.namespace = arghparse.Namespace() self.config_parser = cli.ConfigFileParser(self.parser) @@ -22,65 +21,81 @@ class TestConfigFileParser: def test_ignored_configs(self): # nonexistent config files are ignored - config = self.config_parser.parse_config(('foo', 'bar')) + config = self.config_parser.parse_config(("foo", "bar")) assert config.sections() == [] def test_bad_config_format(self, capsys): - with open(self.config_file, 'w') as f: - f.write('foobar\n') + with open(self.config_file, "w") as f: + f.write("foobar\n") with pytest.raises(SystemExit) as excinfo: self.config_parser.parse_config((self.config_file,)) out, err = capsys.readouterr() assert not out - assert 'parsing config file failed:' in err + assert "parsing config file failed:" in err assert excinfo.value.code == 2 def test_nonexistent_config_options(self, capsys): """Nonexistent parser arguments cause errors.""" - with open(self.config_file, 'w') as f: - f.write(textwrap.dedent(""" - [DEFAULT] - foo=bar - """)) + with open(self.config_file, "w") as f: + f.write( + textwrap.dedent( + """ + [DEFAULT] + foo=bar + """ + ) + ) with pytest.raises(SystemExit) as excinfo: self.config_parser.parse_config_options(self.namespace, configs=[self.config_file]) out, err = capsys.readouterr() assert not out - assert 'failed loading config: unknown arguments: --foo=bar' in err + assert "failed loading config: unknown arguments: --foo=bar" in err assert excinfo.value.code == 2 def test_config_options(self): - self.parser.add_argument('--foo') - with open(self.config_file, 'w') as f: - f.write(textwrap.dedent(""" - [DEFAULT] - foo=bar - """)) - namespace = self.parser.parse_args(['--foo', 'foo']) - assert namespace.foo == 'foo' + self.parser.add_argument("--foo") + with open(self.config_file, "w") as f: + f.write( + textwrap.dedent( + """ + [DEFAULT] + foo=bar + """ + ) + ) + namespace = self.parser.parse_args(["--foo", "foo"]) + assert namespace.foo == "foo" # config args override matching namespace attrs namespace = self.config_parser.parse_config_options(namespace, configs=[self.config_file]) - assert namespace.foo == 'bar' + assert namespace.foo == "bar" def test_config_checksets(self): namespace = self.parser.parse_args([]) namespace.config_checksets = {} # checksets section exists with no entries - with open(self.config_file, 'w') as f: - f.write(textwrap.dedent(""" - [CHECKSETS] - """)) + with open(self.config_file, "w") as f: + f.write( + textwrap.dedent( + """ + [CHECKSETS] + """ + ) + ) namespace = self.config_parser.parse_config_options(namespace, configs=[self.config_file]) assert namespace.config_checksets == {} # checksets section with entries including empty set - with open(self.config_file, 'w') as f: - f.write(textwrap.dedent(""" - [CHECKSETS] - set1=keyword - set2=check,-keyword - set3= - """)) + with open(self.config_file, "w") as f: + f.write( + textwrap.dedent( + """ + [CHECKSETS] + set1=keyword + set2=check,-keyword + set3= + """ + ) + ) namespace = self.config_parser.parse_config_options(namespace, configs=[self.config_file]) - assert namespace.config_checksets == {'set1': ['keyword'], 'set2': ['check', '-keyword']} + assert namespace.config_checksets == {"set1": ["keyword"], "set2": ["check", "-keyword"]} diff --git a/tests/test_feeds.py b/tests/test_feeds.py index a1540048..c098f060 100644 --- a/tests/test_feeds.py +++ b/tests/test_feeds.py @@ -6,54 +6,52 @@ from .misc import FakePkg, Profile class TestQueryCacheAddon: - @pytest.fixture(autouse=True) def _setup(self, tool): self.tool = tool - self.args = ['scan'] + self.args = ["scan"] def test_opts(self): - for val in ('version', 'package', 'category'): - options, _ = self.tool.parse_args(self.args + ['--reset-caching-per', val]) + for val in ("version", "package", "category"): + options, _ = self.tool.parse_args(self.args + ["--reset-caching-per", val]) assert options.query_caching_freq == val def test_default(self): options, _ = self.tool.parse_args(self.args) - assert options.query_caching_freq == 'package' + assert options.query_caching_freq == "package" def test_feed(self): options, _ = self.tool.parse_args(self.args) addon = feeds.QueryCache(options) - assert addon.options.query_caching_freq == 'package' - addon.query_cache['foo'] = 'bar' - pkg = FakePkg('dev-util/diffball-0.5') + assert addon.options.query_caching_freq == "package" + addon.query_cache["foo"] = "bar" + pkg = FakePkg("dev-util/diffball-0.5") addon.feed(pkg) assert not addon.query_cache class TestEvaluateDepSet: - @pytest.fixture(autouse=True) def _setup(self, tool, repo, tmp_path): self.tool = tool self.repo = repo - self.args = ['scan', '--cache-dir', str(tmp_path), '--repo', repo.location] + self.args = ["scan", "--cache-dir", str(tmp_path), "--repo", repo.location] profiles = [ - Profile('1', 'x86'), - Profile('2', 'x86'), - Profile('3', 'ppc'), + Profile("1", "x86"), + Profile("2", "x86"), + Profile("3", "ppc"), ] self.repo.create_profiles(profiles) - self.repo.arches.update(['amd64', 'ppc', 'x86']) + self.repo.arches.update(["amd64", "ppc", "x86"]) - with open(pjoin(self.repo.path, 'profiles', '1', 'package.use.stable.mask'), 'w') as f: - f.write('dev-util/diffball foo') - with open(pjoin(self.repo.path, 'profiles', '2', 'package.use.stable.force'), 'w') as f: - f.write('=dev-util/diffball-0.1 bar foo') - with open(pjoin(self.repo.path, 'profiles', '3', 'package.use.stable.force'), 'w') as f: - f.write('dev-util/diffball bar foo') + with open(pjoin(self.repo.path, "profiles", "1", "package.use.stable.mask"), "w") as f: + f.write("dev-util/diffball foo") + with open(pjoin(self.repo.path, "profiles", "2", "package.use.stable.force"), "w") as f: + f.write("=dev-util/diffball-0.1 bar foo") + with open(pjoin(self.repo.path, "profiles", "3", "package.use.stable.force"), "w") as f: + f.write("dev-util/diffball bar foo") - options, _ = self.tool.parse_args(self.args + ['--profiles=1,2,3']) + options, _ = self.tool.parse_args(self.args + ["--profiles=1,2,3"]) profile_addon = addons.init_addon(addons.profiles.ProfileAddon, options) self.addon = feeds.EvaluateDepSet(options, profile_addon=profile_addon) @@ -72,35 +70,45 @@ class TestEvaluateDepSet: l = get_rets("0.0.2", "depend") assert len(l) == 1, f"must collapse all profiles down to one run: got {l!r}" assert len(l[0][1]) == 4, "must have four runs, (arch and ~arch for each profile)" - assert sorted(set(x.name for x in l[0][1])) == ['1', '2'], f"must have two profiles: got {l!r}" - assert l[0][1][0].key == 'x86' - assert l[0][1][1].key == 'x86' + assert sorted(set(x.name for x in l[0][1])) == [ + "1", + "2", + ], f"must have two profiles: got {l!r}" + assert l[0][1][0].key == "x86" + assert l[0][1][1].key == "x86" l = get_rets( - "0.1", "rdepend", + "0.1", + "rdepend", RDEPEND="x? ( dev-util/confcache ) foo? ( dev-util/foo ) " - "bar? ( dev-util/bar ) !bar? ( dev-util/nobar ) x11-libs/xserver" + "bar? ( dev-util/bar ) !bar? ( dev-util/nobar ) x11-libs/xserver", ) assert len(l) == 3, f"must collapse all profiles down to 3 runs: got {l!r}" # ordering is potentially random; thus pull out which depset result is # which based upon profile - l1 = [x for x in l if x[1][0].name == '1'][0] - l2 = [x for x in l if x[1][0].name == '2'][0] - - assert ( - set(str(l1[0]).split()) == - {'dev-util/confcache', 'dev-util/bar', 'dev-util/nobar', 'x11-libs/xserver'}) - - assert ( - set(str(l2[0]).split()) == - {'dev-util/confcache', 'dev-util/foo', 'dev-util/bar', 'x11-libs/xserver'}) + l1 = [x for x in l if x[1][0].name == "1"][0] + l2 = [x for x in l if x[1][0].name == "2"][0] + + assert set(str(l1[0]).split()) == { + "dev-util/confcache", + "dev-util/bar", + "dev-util/nobar", + "x11-libs/xserver", + } + + assert set(str(l2[0]).split()) == { + "dev-util/confcache", + "dev-util/foo", + "dev-util/bar", + "x11-libs/xserver", + } # test feed wiping, using an empty depset; if it didn't clear, then # results from a pkg/attr tuple from above would come through rather # then an empty. - pkg = FakePkg('dev-util/diffball-0.5') + pkg = FakePkg("dev-util/diffball-0.5") self.addon.feed(pkg) l = get_rets("0.1", "rdepend") assert len(l) == 1, f"feed didn't clear the cache- should be len 1: {l!r}" @@ -110,20 +118,25 @@ class TestEvaluateDepSet: # ensure it handles arch right. l = get_rets("0", "depend", KEYWORDS="ppc x86") assert len(l) == 1, f"should be len 1, got {l!r}" - assert sorted(set(x.name for x in l[0][1])) == ["1", "2", "3"], ( - f"should have three profiles of 1-3, got {l[0][1]!r}") + assert sorted(set(x.name for x in l[0][1])) == [ + "1", + "2", + "3", + ], f"should have three profiles of 1-3, got {l[0][1]!r}" # ensure it's caching profile collapsing, iow, keywords for same ver # that's partially cached (single attr at least) should *not* change # things. l = get_rets("0", "depend", KEYWORDS="ppc") - assert sorted(set(x.name for x in l[0][1])) == ['1', '2', '3'], ( + assert sorted(set(x.name for x in l[0][1])) == ["1", "2", "3"], ( f"should have 3 profiles, got {l[0][1]!r}\nthis indicates it's " - "re-identifying profiles every invocation, which is unwarranted ") + "re-identifying profiles every invocation, which is unwarranted " + ) - l = get_rets("1", "depend", KEYWORDS="ppc x86", - DEPEND="ppc? ( dev-util/ppc ) !ppc? ( dev-util/x86 )") + l = get_rets( + "1", "depend", KEYWORDS="ppc x86", DEPEND="ppc? ( dev-util/ppc ) !ppc? ( dev-util/x86 )" + ) assert len(l) == 2, f"should be len 2, got {l!r}" # same issue, figure out what is what diff --git a/tests/test_reporters.py b/tests/test_reporters.py index 462cc44e..4a0cda39 100644 --- a/tests/test_reporters.py +++ b/tests/test_reporters.py @@ -16,15 +16,15 @@ class BaseReporter: @pytest.fixture(autouse=True) def _setup(self): - self.log_warning = profiles.ProfileWarning(Exception('profile warning')) - self.log_error = profiles.ProfileError(Exception('profile error')) - pkg = FakePkg('dev-libs/foo-0') - self.commit_result = git.InvalidCommitMessage('no commit message', commit='8d86269bb4c7') - self.category_result = metadata_xml.CatMissingMetadataXml('metadata.xml', pkg=pkg) - self.package_result = pkgdir.InvalidPN(('bar', 'baz'), pkg=pkg) - self.versioned_result = metadata.BadFilename(('0.tar.gz', 'foo.tar.gz'), pkg=pkg) - self.line_result = codingstyle.ReadonlyVariable('P', line='P=6', lineno=7, pkg=pkg) - self.lines_result = codingstyle.EbuildUnquotedVariable('D', lines=(5, 7), pkg=pkg) + self.log_warning = profiles.ProfileWarning(Exception("profile warning")) + self.log_error = profiles.ProfileError(Exception("profile error")) + pkg = FakePkg("dev-libs/foo-0") + self.commit_result = git.InvalidCommitMessage("no commit message", commit="8d86269bb4c7") + self.category_result = metadata_xml.CatMissingMetadataXml("metadata.xml", pkg=pkg) + self.package_result = pkgdir.InvalidPN(("bar", "baz"), pkg=pkg) + self.versioned_result = metadata.BadFilename(("0.tar.gz", "foo.tar.gz"), pkg=pkg) + self.line_result = codingstyle.ReadonlyVariable("P", line="P=6", lineno=7, pkg=pkg) + self.lines_result = codingstyle.EbuildUnquotedVariable("D", lines=(5, 7), pkg=pkg) def mk_reporter(self, **kwargs): out = PlainTextFormatter(sys.stdout) @@ -49,106 +49,121 @@ class BaseReporter: class TestStrReporter(BaseReporter): reporter_cls = reporters.StrReporter - add_report_output = dedent("""\ - commit 8d86269bb4c7: no commit message - profile warning - dev-libs: category is missing metadata.xml - dev-libs/foo: invalid package names: [ bar, baz ] - dev-libs/foo-0: bad filenames: [ 0.tar.gz, foo.tar.gz ] - dev-libs/foo-0: read-only variable 'P' assigned, line 7: P=6 - dev-libs/foo-0: unquoted variable D on lines: 5, 7 - """) + add_report_output = dedent( + """\ + commit 8d86269bb4c7: no commit message + profile warning + dev-libs: category is missing metadata.xml + dev-libs/foo: invalid package names: [ bar, baz ] + dev-libs/foo-0: bad filenames: [ 0.tar.gz, foo.tar.gz ] + dev-libs/foo-0: read-only variable 'P' assigned, line 7: P=6 + dev-libs/foo-0: unquoted variable D on lines: 5, 7 + """ + ) class TestFancyReporter(BaseReporter): reporter_cls = reporters.FancyReporter - add_report_output = dedent("""\ - commit - InvalidCommitMessage: commit 8d86269bb4c7: no commit message + add_report_output = dedent( + """\ + commit + InvalidCommitMessage: commit 8d86269bb4c7: no commit message - profiles - ProfileWarning: profile warning + profiles + ProfileWarning: profile warning - dev-libs - CatMissingMetadataXml: category is missing metadata.xml + dev-libs + CatMissingMetadataXml: category is missing metadata.xml - dev-libs/foo - InvalidPN: invalid package names: [ bar, baz ] - BadFilename: version 0: bad filenames: [ 0.tar.gz, foo.tar.gz ] - ReadonlyVariable: version 0: read-only variable 'P' assigned, line 7: P=6 - UnquotedVariable: version 0: unquoted variable D on lines: 5, 7 - """) + dev-libs/foo + InvalidPN: invalid package names: [ bar, baz ] + BadFilename: version 0: bad filenames: [ 0.tar.gz, foo.tar.gz ] + ReadonlyVariable: version 0: read-only variable 'P' assigned, line 7: P=6 + UnquotedVariable: version 0: unquoted variable D on lines: 5, 7 + """ + ) class TestJsonReporter(BaseReporter): reporter_cls = reporters.JsonReporter - add_report_output = dedent("""\ - {"_style": {"InvalidCommitMessage": "commit 8d86269bb4c7: no commit message"}} - {"_warning": {"ProfileWarning": "profile warning"}} - {"dev-libs": {"_error": {"CatMissingMetadataXml": "category is missing metadata.xml"}}} - {"dev-libs": {"foo": {"_error": {"InvalidPN": "invalid package names: [ bar, baz ]"}}}} - {"dev-libs": {"foo": {"0": {"_warning": {"BadFilename": "bad filenames: [ 0.tar.gz, foo.tar.gz ]"}}}}} - {"dev-libs": {"foo": {"0": {"_warning": {"ReadonlyVariable": "read-only variable 'P' assigned, line 7: P=6"}}}}} - {"dev-libs": {"foo": {"0": {"_warning": {"UnquotedVariable": "unquoted variable D on lines: 5, 7"}}}}} - """) + add_report_output = dedent( + """\ + {"_style": {"InvalidCommitMessage": "commit 8d86269bb4c7: no commit message"}} + {"_warning": {"ProfileWarning": "profile warning"}} + {"dev-libs": {"_error": {"CatMissingMetadataXml": "category is missing metadata.xml"}}} + {"dev-libs": {"foo": {"_error": {"InvalidPN": "invalid package names: [ bar, baz ]"}}}} + {"dev-libs": {"foo": {"0": {"_warning": {"BadFilename": "bad filenames: [ 0.tar.gz, foo.tar.gz ]"}}}}} + {"dev-libs": {"foo": {"0": {"_warning": {"ReadonlyVariable": "read-only variable 'P' assigned, line 7: P=6"}}}}} + {"dev-libs": {"foo": {"0": {"_warning": {"UnquotedVariable": "unquoted variable D on lines: 5, 7"}}}}} + """ + ) class TestXmlReporter(BaseReporter): reporter_cls = reporters.XmlReporter - add_report_output = dedent("""\ - <checks> - <result><class>InvalidCommitMessage</class><msg>commit 8d86269bb4c7: no commit message</msg></result> - <result><class>ProfileWarning</class><msg>profile warning</msg></result> - <result><category>dev-libs</category><class>CatMissingMetadataXml</class><msg>category is missing metadata.xml</msg></result> - <result><category>dev-libs</category><package>foo</package><class>InvalidPN</class><msg>invalid package names: [ bar, baz ]</msg></result> - <result><category>dev-libs</category><package>foo</package><version>0</version><class>BadFilename</class><msg>bad filenames: [ 0.tar.gz, foo.tar.gz ]</msg></result> - <result><category>dev-libs</category><package>foo</package><version>0</version><class>ReadonlyVariable</class><msg>read-only variable 'P' assigned, line 7: P=6</msg></result> - <result><category>dev-libs</category><package>foo</package><version>0</version><class>UnquotedVariable</class><msg>unquoted variable D on lines: 5, 7</msg></result> - </checks> - """) + add_report_output = dedent( + """\ + <checks> + <result><class>InvalidCommitMessage</class><msg>commit 8d86269bb4c7: no commit message</msg></result> + <result><class>ProfileWarning</class><msg>profile warning</msg></result> + <result><category>dev-libs</category><class>CatMissingMetadataXml</class><msg>category is missing metadata.xml</msg></result> + <result><category>dev-libs</category><package>foo</package><class>InvalidPN</class><msg>invalid package names: [ bar, baz ]</msg></result> + <result><category>dev-libs</category><package>foo</package><version>0</version><class>BadFilename</class><msg>bad filenames: [ 0.tar.gz, foo.tar.gz ]</msg></result> + <result><category>dev-libs</category><package>foo</package><version>0</version><class>ReadonlyVariable</class><msg>read-only variable 'P' assigned, line 7: P=6</msg></result> + <result><category>dev-libs</category><package>foo</package><version>0</version><class>UnquotedVariable</class><msg>unquoted variable D on lines: 5, 7</msg></result> + </checks> + """ + ) class TestCsvReporter(BaseReporter): reporter_cls = reporters.CsvReporter - add_report_output = dedent("""\ - ,,,commit 8d86269bb4c7: no commit message - ,,,profile warning - dev-libs,,,category is missing metadata.xml - dev-libs,foo,,"invalid package names: [ bar, baz ]" - dev-libs,foo,0,"bad filenames: [ 0.tar.gz, foo.tar.gz ]" - dev-libs,foo,0,"read-only variable 'P' assigned, line 7: P=6" - dev-libs,foo,0,"unquoted variable D on lines: 5, 7" - """) + add_report_output = dedent( + """\ + ,,,commit 8d86269bb4c7: no commit message + ,,,profile warning + dev-libs,,,category is missing metadata.xml + dev-libs,foo,,"invalid package names: [ bar, baz ]" + dev-libs,foo,0,"bad filenames: [ 0.tar.gz, foo.tar.gz ]" + dev-libs,foo,0,"read-only variable 'P' assigned, line 7: P=6" + dev-libs,foo,0,"unquoted variable D on lines: 5, 7" + """ + ) class TestFormatReporter(BaseReporter): - reporter_cls = partial(reporters.FormatReporter, '') + reporter_cls = partial(reporters.FormatReporter, "") def test_add_report(self, capsys): for format_str, expected in ( - ('r', 'r\n' * 7), - ('{category}', 'dev-libs\n' * 5), - ('{category}/{package}', '/\n/\ndev-libs/\n' + 'dev-libs/foo\n' * 4), - ('{category}/{package}-{version}', '/-\n/-\ndev-libs/-\ndev-libs/foo-\n' + 'dev-libs/foo-0\n' * 3), - ('{name}', - 'InvalidCommitMessage\nProfileWarning\nCatMissingMetadataXml\nInvalidPN\nBadFilename\nReadonlyVariable\nUnquotedVariable\n'), - ('{foo}', ''), - ): + ("r", "r\n" * 7), + ("{category}", "dev-libs\n" * 5), + ("{category}/{package}", "/\n/\ndev-libs/\n" + "dev-libs/foo\n" * 4), + ( + "{category}/{package}-{version}", + "/-\n/-\ndev-libs/-\ndev-libs/foo-\n" + "dev-libs/foo-0\n" * 3, + ), + ( + "{name}", + "InvalidCommitMessage\nProfileWarning\nCatMissingMetadataXml\nInvalidPN\nBadFilename\nReadonlyVariable\nUnquotedVariable\n", + ), + ("{foo}", ""), + ): self.reporter_cls = partial(reporters.FormatReporter, format_str) self.add_report_output = expected super().test_add_report(capsys) def test_unsupported_index(self, capsys): - self.reporter_cls = partial(reporters.FormatReporter, '{0}') + self.reporter_cls = partial(reporters.FormatReporter, "{0}") with self.mk_reporter() as reporter: with pytest.raises(base.PkgcheckUserException) as excinfo: reporter.report(self.versioned_result) - assert 'integer indexes are not supported' in str(excinfo.value) + assert "integer indexes are not supported" in str(excinfo.value) class TestJsonStream(BaseReporter): @@ -158,8 +173,13 @@ class TestJsonStream(BaseReporter): def test_add_report(self, capsys): with self.mk_reporter() as reporter: for result in ( - self.log_warning, self.log_error, self.commit_result, - self.category_result, self.package_result, self.versioned_result): + self.log_warning, + self.log_error, + self.commit_result, + self.category_result, + self.package_result, + self.versioned_result, + ): reporter.report(result) out, err = capsys.readouterr() assert not err @@ -169,28 +189,30 @@ class TestJsonStream(BaseReporter): def test_deserialize_error(self): with self.mk_reporter() as reporter: # deserializing non-result objects raises exception - obj = reporter.to_json(['result']) - with pytest.raises(reporters.DeserializationError, match='failed loading'): + obj = reporter.to_json(["result"]) + with pytest.raises(reporters.DeserializationError, match="failed loading"): next(reporter.from_iter([obj])) # deserializing mangled JSON result objects raises exception obj = reporter.to_json(self.versioned_result) - del obj['__class__'] + del obj["__class__"] json_obj = json.dumps(obj) - with pytest.raises(reporters.DeserializationError, match='unknown result'): + with pytest.raises(reporters.DeserializationError, match="unknown result"): next(reporter.from_iter([json_obj])) class TestFlycheckReporter(BaseReporter): reporter_cls = reporters.FlycheckReporter - add_report_output = dedent("""\ - -.ebuild:0:style:InvalidCommitMessage: commit 8d86269bb4c7: no commit message - -.ebuild:0:warning:ProfileWarning: profile warning - -.ebuild:0:error:CatMissingMetadataXml: category is missing metadata.xml - foo-.ebuild:0:error:InvalidPN: invalid package names: [ bar, baz ] - foo-0.ebuild:0:warning:BadFilename: bad filenames: [ 0.tar.gz, foo.tar.gz ] - foo-0.ebuild:7:warning:ReadonlyVariable: read-only variable 'P' assigned, line 7: P=6 - foo-0.ebuild:5:warning:UnquotedVariable: unquoted variable D - foo-0.ebuild:7:warning:UnquotedVariable: unquoted variable D - """) + add_report_output = dedent( + """\ + -.ebuild:0:style:InvalidCommitMessage: commit 8d86269bb4c7: no commit message + -.ebuild:0:warning:ProfileWarning: profile warning + -.ebuild:0:error:CatMissingMetadataXml: category is missing metadata.xml + foo-.ebuild:0:error:InvalidPN: invalid package names: [ bar, baz ] + foo-0.ebuild:0:warning:BadFilename: bad filenames: [ 0.tar.gz, foo.tar.gz ] + foo-0.ebuild:7:warning:ReadonlyVariable: read-only variable 'P' assigned, line 7: P=6 + foo-0.ebuild:5:warning:UnquotedVariable: unquoted variable D + foo-0.ebuild:7:warning:UnquotedVariable: unquoted variable D + """ + ) |