diff options
Diffstat (limited to 'tests/checks/test_codingstyle.py')
-rw-r--r-- | tests/checks/test_codingstyle.py | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/tests/checks/test_codingstyle.py b/tests/checks/test_codingstyle.py new file mode 100644 index 00000000..958976d3 --- /dev/null +++ b/tests/checks/test_codingstyle.py @@ -0,0 +1,391 @@ +from itertools import chain + +from pkgcheck.checks import codingstyle +from pkgcore.ebuild.eapi import EAPI + +from .. import misc + + +class TestInsintoCheck(misc.ReportTestCase): + + check_kls = codingstyle.InsintoCheck + + def test_insinto(self): + fake_src = [ + "# This is our first fake ebuild\n", + "\n", + "\tinsinto /usr/bin\n", + "\tinsinto /etc/env.d\n", + "\tinsinto /etc/env.d/foo\n", + "\tinsinto /etc/conf.d\n", + "\tinsinto /etc/init.d/\n", + "\tinsinto /etc/pam.d\n", + "\tinsinto /usr/share/applications\n", + "\tinsinto /usr/share/applications/\n", + "\tinsinto //usr/share//applications//\n", + "# That's it for now\n", + ] + 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", + "//usr/share//applications", + ) + check = self.check_kls(None) + + reports = self.assertReports(check, fake_pkg) + for r, path in zip(reports, bad): + assert path in str(r) + + def test_docinto(self): + check = self.check_kls(None) + 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_pkg = misc.FakePkg( + "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) + else: + self.assertNoReport(check, fake_pkg) + + +class TestAbsoluteSymlink(misc.ReportTestCase): + + check_kls = codingstyle.AbsoluteSymlinkCheck + + def test_it(self): + absolute = [ + ("/bin/blah", "/bin/baz"), + ('"/bin/blah baz"', "/bin/blahbaz"), + ("'/bin/blah baz'", "/bin/blahbaz"), + ("/etc/Boo", "/etc/boo"), + ] + + absolute_prefixed = [] + for path_var in codingstyle.PATH_VARIABLES: + 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') + absolute_prefixed.append((f'"${{{path_var}}}{src}"', dest)) + absolute_prefixed.append((f'"${{{path_var}%/}}{src}"', dest)) + + relative = [ + ("blah", "/bin/baz"), + ('"blah baz"', "/bin/blahbaz"), + ("Boo", "/etc/boo"), + ] + + unhandled = [ + ("/crazy/root/dir", "/crazy/symlink"), + ] + + fake_src = [ + "# This is our first fake ebuild\n", + "\n", + ] + for src, dest in chain.from_iterable((absolute, absolute_prefixed, relative, unhandled)): + fake_src.append(f"\tdosym {src} {dest}\n") + fake_src.append("# That's it for now\n") + fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) + + check = self.check_kls(None) + reports = self.assertReports(check, fake_pkg) + + 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) + + +class TestPathVariablesCheck(misc.ReportTestCase): + + check_kls = codingstyle.PathVariablesCheck + check = check_kls(None) + + 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: + fake_src = ["src_install() {\n"] + for x in range(lines): + fake_src.append(f' rm "${{{path_var}{suffix}}}"a/file{x} || die\n') + 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) + 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.lines == tuple(x + 2 for x in range(lines)) + assert path_var in str(r) + + def _unfound(self, cls, suffix=''): + for path_var in codingstyle.PATH_VARIABLES: + fake_src = [ + "src_install() {\n", + f' local var="${{{path_var}}}_foo"\n', + f' rm "${{{path_var}}}"/a/random/file || die\n', + "}\n", + "\n", + ] + 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) + self.assertNoReport(self.check, fake_pkg) + + def test_missing_found(self): + self._found(codingstyle.MissingSlash) + + def test_missing_unfound(self): + self._unfound(codingstyle.MissingSlash) + + def test_unnecessary_found(self): + self._found(codingstyle.UnnecessarySlashStrip, suffix='%/') + + def test_unnecessary_unfound(self): + self._unfound(codingstyle.UnnecessarySlashStrip, suffix='%/') + + def test_double_prefix_found(self): + fake_src = [ + 'src_install() {\n', + ' cp foo.py "${ED}$(python_get_sitedir)"\n', + # test non-match + ' cp foo.py "${D%/}$(python_get_sitedir)"\n', + # test slash-strip + ' cp foo.py "${ED%/}$(python_get_sitedir)"\n', + # test extra slash + ' cp foo.py "${ED}/$(python_get_sitedir)"\n', + # test variable variant + ' cp foo.py "${ED}${PYTHON_SITEDIR}"\n', + # test silly mistake + ' cp foo "${ED}${EPREFIX}/foo/bar"\n', + # function variants + ' insinto "$(python_get_sitedir)"\n', + ' exeinto "${EPREFIX}/foo/bar"\n', + ' fowners foo:bar "$(python_get_sitedir)/foo/bar.py"\n', + ' dodir /foo/bar "${EPREFIX}"/bar/baz\n', + # commented lines aren't flagged for double prefix usage + '# exeinto "${EPREFIX}/foo/bar"\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), + ('insinto "$(python_get_sitedir)', 8), + ('exeinto "${EPREFIX}', 9), + ('fowners foo:bar "$(python_get_sitedir)', 10), + ('dodir /foo/bar "${EPREFIX}', 11), + ) + assert len(r) == len(expected_results) + for res, exp in zip(r, expected_results): + assert isinstance(res, cls) + assert res.match == exp[0] + assert res.lines == (exp[1],) + assert exp[0] in str(res) + + def test_double_prefix_unfound(self): + fake_src = [ + 'src_install() {\n', + ' cp foo.py "${D}$(python_get_sitedir)"\n', + ' cp foo "${D}${EPREFIX}/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' + ] + fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src) + self.assertNoReport(self.check, fake_pkg) + + +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' + ] + 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' + ] + 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' + ] + + 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 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' + ] + + 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 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' + ] + 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' + ] + + 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 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' + ] + + 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 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' + ] + + 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 uri in str(r) + + +class TestRawEbuildCheck(misc.ReportTestCase): + + check_kls = codingstyle.RawEbuildCheck + + def mk_pkg(self, **kwargs): + return misc.FakePkg("dev-util/diffball-0.5", **kwargs) + + def test_single_line(self): + fake_src = ['HOMEPAGE="https://example.com/"\n', + 'SRC_URI="${HOMEPAGE}/${P}.tar.bz2"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + r = self.assertReport(self.check_kls(None), fake_pkg) + assert isinstance(r, codingstyle.HomepageInSrcUri) + assert '${HOMEPAGE} in SRC_URI' in str(r) + + def test_multi_line(self): + fake_src = ['HOMEPAGE="https://example.com/"\n', + 'SRC_URI="https://example.org/${P}-manpages.tar.bz2\n', + '\t${HOMEPAGE}/${P}.tar.bz2"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + r = self.assertReport(self.check_kls(None), fake_pkg) + assert isinstance(r, codingstyle.HomepageInSrcUri) + + def test_no_match(self): + fake_src = ['HOMEPAGE="https://example.com/"\n', + 'SRC_URI="https://example.com/${P}.tar.bz2"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + self.assertNoReport(self.check_kls(None), fake_pkg) + + def test_no_false_positive(self): + fake_src = ['HOMEPAGE="https://example.com/"\n', + 'SRC_URI="https://example.com/${P}.tar.bz2"\n', + '# ${HOMEPAGE} must not be used here\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + self.assertNoReport(self.check_kls(None), fake_pkg) + + def test_dynamic_src_uri(self): + fake_src = ['SRC_URI="https://example.com/${PV}/${P}.tar.bz2"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + self.assertNoReport(self.check_kls(None), fake_pkg) + + def test_static_package_src_uri(self): + fake_src = ['SRC_URI="https://example.com/diffball-0.5.tar.bz2"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + r = self.assertReport(self.check_kls(None), fake_pkg) + assert isinstance(r, codingstyle.StaticSrcUri) + assert r.static_str == 'diffball-0.5.tar.bz2' + + def test_static_package_version_src_uri(self): + fake_src = ['SRC_URI="https://example.com/0.5/${P}.tar.bz2"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + r = self.assertReport(self.check_kls(None), fake_pkg) + assert isinstance(r, codingstyle.StaticSrcUri) + assert r.static_str == '0.5' + + def test_multi_static_src_uri(self): + fake_src = ['SRC_URI="https://example.com/0.5/diffball-0.5.tar.bz2"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + for r in self.assertReports(self.check_kls(None), fake_pkg): + assert isinstance(r, codingstyle.StaticSrcUri) + + def test_single_homepage_variable(self): + fake_src = ['HOMEPAGE="https://example.com/${PN}"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + r = self.assertReport(self.check_kls(None), fake_pkg) + assert isinstance(r, codingstyle.VariableInHomepage) + assert r.variables == ('${PN}',) + assert '${PN}' in str(r) + + def test_multiple_homepage_variables(self): + fake_src = ['HOMEPAGE="https://example.com/${PN}/${FOO}"\n'] + fake_pkg = self.mk_pkg(lines=fake_src) + r = self.assertReport(self.check_kls(None), fake_pkg) + assert isinstance(r, codingstyle.VariableInHomepage) + assert r.variables == ('${PN}', '${FOO}') + assert '${PN}, ${FOO}' in str(r) |