diff options
Diffstat (limited to 'tests')
184 files changed, 2916 insertions, 0 deletions
diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..55f0c9e --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,20 @@ +#!/usr/bin/make -f + +# enable or disable tests here: +#TESTS := test301 test302 test303 test304 test305 test306 testpb01 testpb02 testpb03 testpb04 testpb05 testpb06 testpb07 testa01 testa02 +TESTS := test301 test302 test303 test304 test305 test306 + +all: $(TESTS) + +test%: + make -C t$* run + make -C t$* check + +clean-test%: + make -C t$* clean + +clean: $(TESTS:%=clean-%) + rm -f *\.dsc *\.tar\.gz *\.build *\.changes *\.deb *\.buildinfo + @find . -prune -name '*.egg-info' -exec rm -rf '{}' ';' || true + +.PHONY: clean diff --git a/tests/common.mk b/tests/common.mk new file mode 100644 index 0000000..b4d4f02 --- /dev/null +++ b/tests/common.mk @@ -0,0 +1,19 @@ +#!/usr/bin/make -f + +export DEBPYTHON3_DEFAULT ?= $(shell python3 ../../dhpython/_defaults.py default cpython3) +export DEBPYTHON3_SUPPORTED ?= $(shell python3 ../../dhpython/_defaults.py supported cpython3) +export DEB_HOST_MULTIARCH=my_multiarch-triplet +export DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +export DH_INTERNAL_OPTIONS= + +all: run check + +run: clean + @echo ============================================================ + @echo ==== TEST: `basename $$PWD` + dpkg-buildpackage -b -us -uc \ + --no-check-builddeps \ + --check-command="../test-package-show-info" + +clean-common: + ./debian/rules clean diff --git a/tests/common.py b/tests/common.py new file mode 100644 index 0000000..7e974fc --- /dev/null +++ b/tests/common.py @@ -0,0 +1,18 @@ +class FakeOptions: + def __init__(self, **kwargs): + opts = { + 'depends': (), + 'depends_section': (), + 'guess_deps': False, + 'no_ext_rename': False, + 'recommends': (), + 'recommends_section': (), + 'requires': (), + 'suggests': (), + 'suggests_section': (), + 'vrange': None, + 'accept_upstream_versions': False, + } + opts.update(kwargs) + for k, v in opts.items(): + setattr(self, k, v) diff --git a/tests/t301/Makefile b/tests/t301/Makefile new file mode 100644 index 0000000..4be460f --- /dev/null +++ b/tests/t301/Makefile @@ -0,0 +1,15 @@ +#!/usr/bin/make -f +include ../common.mk + +check: + grep -qe "Depends: .*python3\(:any\)\? (<< 3.9)" debian/python3-foo/DEBIAN/control + grep -q "Recommends: .*python3-mako" debian/python3-foo/DEBIAN/control + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py + test ! -f debian/python3-foo/usr/lib/python3/dist-packages/foo/spam.py + grep -q 'py3compile -p python3-foo -V 3\.1-3\.9' debian/python3-foo/DEBIAN/postinst + grep -q 'pypy3compile -p python3-foo -V 3\.1-3\.9' debian/python3-foo/DEBIAN/postinst + grep -q 'py3clean -p python3-foo\s*$$' debian/python3-foo/DEBIAN/prerm + +clean: + ./debian/rules clean + rm -rf lib/Foo.egg-info diff --git a/tests/t301/debian/changelog b/tests/t301/debian/changelog new file mode 100644 index 0000000..0f9a168 --- /dev/null +++ b/tests/t301/debian/changelog @@ -0,0 +1,5 @@ +foo (0.1.1) unstable; urgency=low + + * Initial release + + -- Piotr Ożarowski <piotr@debian.org> Sat, 27 Feb 2010 20:42:17 +0100 diff --git a/tests/t301/debian/compat b/tests/t301/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/tests/t301/debian/compat @@ -0,0 +1 @@ +9 diff --git a/tests/t301/debian/control b/tests/t301/debian/control new file mode 100644 index 0000000..fc18d76 --- /dev/null +++ b/tests/t301/debian/control @@ -0,0 +1,18 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper (>= 7.0.50~), python3-all +Standards-Version: 3.9.0 +X-Python3-Version: >= 3.1, << 3.9 + +Architecture: all +Package: python3-foo +Depends: ${python3:Depends}, ${misc:Depends} +Recommends: ${python3:Recommends} +Suggests: ${python3:Suggests} +Enhances: ${python3:Enhances} +Breaks: ${python3:Breaks} +Provides: ${python3:Provides} +Description: foo to rule them all + example package #1 diff --git a/tests/t301/debian/copyright b/tests/t301/debian/copyright new file mode 100644 index 0000000..6382944 --- /dev/null +++ b/tests/t301/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2010, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/t301/debian/py3dist-overrides b/tests/t301/debian/py3dist-overrides new file mode 100644 index 0000000..ab3ccb8 --- /dev/null +++ b/tests/t301/debian/py3dist-overrides @@ -0,0 +1,5 @@ +Mako python3-mako (>= 0.2) +SQLAlchemy python3-sqlalchemy (>= 0.6) +Foo python3-foo +Bar python3-bar +Baz
\ No newline at end of file diff --git a/tests/t301/debian/python3-foo.pydist b/tests/t301/debian/python3-foo.pydist new file mode 100644 index 0000000..82849da --- /dev/null +++ b/tests/t301/debian/python3-foo.pydist @@ -0,0 +1 @@ +SQLAlchemy 3.2- python3-sqlalchemy; PEP386 s/^/1:/ diff --git a/tests/t301/debian/rules b/tests/t301/debian/rules new file mode 100755 index 0000000..9c1bdff --- /dev/null +++ b/tests/t301/debian/rules @@ -0,0 +1,25 @@ +#!/usr/bin/make -f +%: + dh $@ --buildsystem=python_distutils + +override_dh_auto_install: + python3 setup.py install --root=debian/python3-foo/ + +override_dh_install: + dh_install + find debian/ -name jquery.js -exec \ + ln -fs /usr/share/javascript/jquery/jquery.js '{}' \; + DH_VERBOSE=1 ../../dh_python3\ + --depends 'SQLAlchemy >= 0.6.1'\ + --recommends Mako\ + --suggests 'Foo >= 0.1'\ + --suggests 'bar >= 1.0' + +clean: + rm -rf build + dh clean + +override_dh_auto_build: + +override_dh_auto_clean: + #python3 setup.py clean diff --git a/tests/t301/debian/source/format b/tests/t301/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/t301/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/t301/lib/foo/__init__.py b/tests/t301/lib/foo/__init__.py new file mode 100644 index 0000000..9df03f8 --- /dev/null +++ b/tests/t301/lib/foo/__init__.py @@ -0,0 +1 @@ +print("you just imported foo from %s" % __file__) diff --git a/tests/t301/lib/foo/bar/__init__.py b/tests/t301/lib/foo/bar/__init__.py new file mode 100644 index 0000000..669df66 --- /dev/null +++ b/tests/t301/lib/foo/bar/__init__.py @@ -0,0 +1 @@ +print("you just imported foo.bar from %s" % __file__) diff --git a/tests/t301/lib/foo/baz.py b/tests/t301/lib/foo/baz.py new file mode 100644 index 0000000..934dcfe --- /dev/null +++ b/tests/t301/lib/foo/baz.py @@ -0,0 +1 @@ +print("you just imported foo.baz from %s" % __file__) diff --git a/tests/t301/lib/foo/jquery.js b/tests/t301/lib/foo/jquery.js new file mode 120000 index 0000000..b77fd86 --- /dev/null +++ b/tests/t301/lib/foo/jquery.js @@ -0,0 +1 @@ +/usr/share/javascript/jquery/jquery.js
\ No newline at end of file diff --git a/tests/t301/setup.py b/tests/t301/setup.py new file mode 100644 index 0000000..bb7f37d --- /dev/null +++ b/tests/t301/setup.py @@ -0,0 +1,17 @@ +#! /usr/bin/python3 +from distutils.core import setup + +setup(name='Foo', + version='0.2', + description="package with public modules only", + long_description="TODO", + keywords='foo bar baz', + author='Piotr Ożarowski', + author_email='piotr@debian.org', + url='http://www.debian.org/', + license='MIT', + packages=['foo'], + package_dir={'foo': 'lib/foo'}, + package_data={'foo': ['jquery.js']}, + zip_safe=False, +) diff --git a/tests/t302/Makefile b/tests/t302/Makefile new file mode 100644 index 0000000..2fc6b11 --- /dev/null +++ b/tests/t302/Makefile @@ -0,0 +1,18 @@ +#!/usr/bin/make -f +include ../common.mk + +check: + grep -q "py3compile -p python3-foo:$(DEB_HOST_ARCH) /usr/lib/python3-foo"\ + debian/python3-foo/DEBIAN/postinst + grep -q "pypy3compile -p python3-foo:$(DEB_HOST_ARCH) /usr/lib/python3-foo"\ + debian/python3-foo/DEBIAN/postinst + grep -q "py3clean -p python3-foo:$(DEB_HOST_ARCH)" debian/python3-foo/DEBIAN/prerm + [ "`find debian/python3-foo/usr/lib/python3/dist-packages/foo -name 'bar.cpython-*.so'`" != "" ] + test -e debian/python3-foo/usr/lib/python3-foo/empty-private-dir + test ! -e debian/python3-foo/usr/lib/python3/dist-packages/empty-public-dir + # test if moved from include/python3.X/ to include/python3.Xm/ (for Python << 3.8) + #test -f debian/python3-foo/usr/include/python$(DEBPYTHON3_DEFAULT)m/foo.h + +clean: + ./debian/rules clean + rm -rf lib/Foo.egg-info build diff --git a/tests/t302/debian/changelog b/tests/t302/debian/changelog new file mode 100644 index 0000000..d91e7a7 --- /dev/null +++ b/tests/t302/debian/changelog @@ -0,0 +1,5 @@ +foo (0.1.1) unstable; urgency=low + + * Initial release + + -- Piotr Ożarowski <piotr@debian.org> Sun, 19 Dec 2010 19:40:33 +0100 diff --git a/tests/t302/debian/compat b/tests/t302/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/tests/t302/debian/compat @@ -0,0 +1 @@ +9 diff --git a/tests/t302/debian/control b/tests/t302/debian/control new file mode 100644 index 0000000..01a7656 --- /dev/null +++ b/tests/t302/debian/control @@ -0,0 +1,18 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper (>= 7.0.50~), python3-all-dev +Standards-Version: 3.9.1 +X-Python3-Version: >= 3.2 + +Package: python3-foo +Architecture: any +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Recommends: ${python3:Recommends} +Suggests: ${python3:Suggests} +Enhances: ${python3:Enhances} +Breaks: ${python3:Breaks} +Provides: ${python3:Provides} +Description: package with public and private Python 3 extension + example package #3 - Python extensions diff --git a/tests/t302/debian/copyright b/tests/t302/debian/copyright new file mode 100644 index 0000000..6382944 --- /dev/null +++ b/tests/t302/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2010, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/t302/debian/install b/tests/t302/debian/install new file mode 100644 index 0000000..61f42c3 --- /dev/null +++ b/tests/t302/debian/install @@ -0,0 +1,2 @@ +# private module in architecture dependent dir +lib/foo.py /usr/lib/python3-foo/ diff --git a/tests/t302/debian/rules b/tests/t302/debian/rules new file mode 100755 index 0000000..a85d729 --- /dev/null +++ b/tests/t302/debian/rules @@ -0,0 +1,30 @@ +#!/usr/bin/make -f + +%: + dh $@ --buildsystem=python_distutils + +override_dh_install: + dh_install + # install also as private extension + dh_install debian/python3-foo/usr/local/lib/python3*/dist-packages/foo/bar*.so \ + /usr/lib/python3-foo/ + mkdir -p debian/python3-foo/usr/lib/python3/dist-packages/empty-public-dir + mkdir -p debian/python3-foo/usr/lib/python3-foo/empty-private-dir + DH_VERBOSE=1 ../../dh_python3 + +comma:=, +empty:= +space:= $(empty) $(empty) +PYTHONS=$(subst $(comma),$(space),$(DEBPYTHON3_SUPPORTED)) +override_dh_auto_build: + for ver in $(PYTHONS); do\ + python$$ver setup.py build; done + +override_dh_auto_install: + for ver in $(PYTHONS); do\ + python$$ver setup.py install --root=debian/python3-foo;\ + done + mkdir -p debian/python3-foo/usr/include/python$(DEBPYTHON3_DEFAULT)/ + touch debian/python3-foo/usr/include/python$(DEBPYTHON3_DEFAULT)/foo.h + +override_dh_auto_clean: diff --git a/tests/t302/debian/source/format b/tests/t302/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/t302/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/t302/lib/__init__.py b/tests/t302/lib/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/t302/lib/__init__.py diff --git a/tests/t302/lib/bar.c b/tests/t302/lib/bar.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/t302/lib/bar.c diff --git a/tests/t302/lib/foo.py b/tests/t302/lib/foo.py new file mode 100644 index 0000000..9dd52e6 --- /dev/null +++ b/tests/t302/lib/foo.py @@ -0,0 +1,6 @@ +import foo.bar + + +class Foo(object): + def __init__(self): + foo.bar diff --git a/tests/t302/setup.py b/tests/t302/setup.py new file mode 100755 index 0000000..1208046 --- /dev/null +++ b/tests/t302/setup.py @@ -0,0 +1,13 @@ +#! /usr/bin/python3 +from distutils.core import setup, Extension + +setup(name='Foo', + version='0.1', + description="package with Python extension", + author='Piotr Ożarowski', + author_email='piotr@debian.org', + url='http://www.debian.org/', + ext_modules=[Extension('foo/bar', ['lib/bar.c'])], + #py_modules=['package'], + packages=['foo'], + package_dir={'foo': 'lib'}) diff --git a/tests/t303/Makefile b/tests/t303/Makefile new file mode 100644 index 0000000..9f2c71b --- /dev/null +++ b/tests/t303/Makefile @@ -0,0 +1,12 @@ +#!/usr/bin/make -f +include ../common.mk + +check: + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo.py + test ! -d debian/python3-foo/usr/lib/python3.*/site-packages + grep -q 'py3compile -p python3-foo\s*$$' debian/python3-foo/DEBIAN/postinst + grep -q 'pypy3compile -p python3-foo\s*||\s*true$$' debian/python3-foo/DEBIAN/postinst + grep -q 'py3clean -p python3-foo\s*$$' debian/python3-foo/DEBIAN/prerm + +clean: + ./debian/rules clean diff --git a/tests/t303/debian/changelog b/tests/t303/debian/changelog new file mode 100644 index 0000000..1a796a1 --- /dev/null +++ b/tests/t303/debian/changelog @@ -0,0 +1,5 @@ +foo (0.1.1) unstable; urgency=low + + * Initial release + + -- Piotr Ożarowski <piotr@debian.org> Thu, 06 Jan 2011 17:23:23 +0100 diff --git a/tests/t303/debian/compat b/tests/t303/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/tests/t303/debian/compat @@ -0,0 +1 @@ +9 diff --git a/tests/t303/debian/control b/tests/t303/debian/control new file mode 100644 index 0000000..beb1372 --- /dev/null +++ b/tests/t303/debian/control @@ -0,0 +1,12 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper (>= 7.0.50~), python3-all-dev +Standards-Version: 3.9.1 + +Package: python3-foo +Architecture: all +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public Python 3 modules + example package #4 - fix_locations test diff --git a/tests/t303/debian/copyright b/tests/t303/debian/copyright new file mode 100644 index 0000000..69cea75 --- /dev/null +++ b/tests/t303/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2011, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/t303/debian/rules b/tests/t303/debian/rules new file mode 100755 index 0000000..8f0c8be --- /dev/null +++ b/tests/t303/debian/rules @@ -0,0 +1,23 @@ +#!/usr/bin/make -f + +%: + dh $@ + +override_dh_install: + dh_install + DH_VERBOSE=1 ../../dh_python3 + +override_dh_auto_build: +override_dh_auto_test: + +comma:=, +empty:= +space:= $(empty) $(empty) +PYTHONS=$(subst $(comma),$(space),$(DEBPYTHON3_SUPPORTED)) +override_dh_auto_install: + set -e; for ver in $(PYTHONS); do\ + mkdir -p debian/python3-foo/usr/lib/python$$ver/site-packages/;\ + echo "print('foo')" > debian/python3-foo/usr/lib/python$$ver/site-packages/foo.py;\ + done + +override_dh_auto_clean: diff --git a/tests/t303/debian/source/format b/tests/t303/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/t303/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/t304/Makefile b/tests/t304/Makefile new file mode 100644 index 0000000..d69cdc9 --- /dev/null +++ b/tests/t304/Makefile @@ -0,0 +1,23 @@ +#!/usr/bin/make -f + +include ../common.mk +clean: clean-common + +check: + # python3.2 hardcoded via `dh_python3 --shebang ...python3.2` + grep -q '#! /usr/bin/python3.2 -OO' debian/foo/usr/share/baz32/baz.py + # python3.4 hardcoded via shebang + grep -q '/usr/share/foo \-V 3.4' debian/foo/DEBIAN/postinst + # /env removed from shebang + grep -q '#! /usr/bin/python3' debian/foo/usr/share/bar/bar.py + # /local removed from shebang + grep -q '#! /usr/bin/python3' debian/foo/usr/share/foo/baz.py + grep -q '#! /usr/bin/python3.4' debian/foo/usr/share/foo/foo.py + # make sure /usr/share/doc/ is ignored + grep -q -v "py3compile -p foo /usr/share/doc"\ + debian/foo/DEBIAN/postinst + # -X made it into the postinst + grep -qF "/usr/share/bar -X 'spam.py'" debian/foo/DEBIAN/postinst + # Check argument parsing order + grep -q '#! /usr/bin/python3-dbg' debian/overrides/usr/share/overrides1/foo.py + grep -q '#! /usr/bin/python3-dbg' debian/overrides/usr/share/overrides2/foo.py diff --git a/tests/t304/bar.py b/tests/t304/bar.py new file mode 100755 index 0000000..edecee7 --- /dev/null +++ b/tests/t304/bar.py @@ -0,0 +1,2 @@ +#!/usr/bin/env python3 +"env in shebang" diff --git a/tests/t304/baz.py b/tests/t304/baz.py new file mode 100755 index 0000000..eff389f --- /dev/null +++ b/tests/t304/baz.py @@ -0,0 +1,2 @@ +#!/usr/local/bin/python3 +"/usr/local in shebang" diff --git a/tests/t304/debian/changelog b/tests/t304/debian/changelog new file mode 100644 index 0000000..c1ed13c --- /dev/null +++ b/tests/t304/debian/changelog @@ -0,0 +1,5 @@ +foo (1.0) unstable; urgency=low + + * Initial release + + -- Piotr Ożarowski <piotr@debian.org> Sun, 10 Jun 2012 14:09:45 +0200 diff --git a/tests/t304/debian/compat b/tests/t304/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/tests/t304/debian/compat @@ -0,0 +1 @@ +9 diff --git a/tests/t304/debian/control b/tests/t304/debian/control new file mode 100644 index 0000000..4dd38b0 --- /dev/null +++ b/tests/t304/debian/control @@ -0,0 +1,19 @@ +Source: foo +Section: misc +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper (>= 7.0.50~) +Build-Depends-Indep: python3 +Standards-Version: 3.9.3 + +Package: foo +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: example 4 - shebangs + example package #4 - shebang related tests + +Package: overrides +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: example 4 - command line parsing + example package #4 - command line argument parsing diff --git a/tests/t304/debian/copyright b/tests/t304/debian/copyright new file mode 100644 index 0000000..bf78fd0 --- /dev/null +++ b/tests/t304/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2012, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/t304/debian/examples b/tests/t304/debian/examples new file mode 100644 index 0000000..fe8826b --- /dev/null +++ b/tests/t304/debian/examples @@ -0,0 +1 @@ +foo.py diff --git a/tests/t304/debian/install b/tests/t304/debian/install new file mode 100644 index 0000000..a106b6e --- /dev/null +++ b/tests/t304/debian/install @@ -0,0 +1,7 @@ +foo.py /usr/share/foo/ +baz.py /usr/share/foo/ +spam.py /usr/share/foo/ +bar.py /usr/share/bar/ +spam.py /usr/share/bar/ +baz.py /usr/share/baz32/ +spam.py /usr/share/baz32/ diff --git a/tests/t304/debian/overrides.install b/tests/t304/debian/overrides.install new file mode 100644 index 0000000..23e1322 --- /dev/null +++ b/tests/t304/debian/overrides.install @@ -0,0 +1,2 @@ +foo.py /usr/share/overrides1/ +foo.py /usr/share/overrides2/ diff --git a/tests/t304/debian/rules b/tests/t304/debian/rules new file mode 100755 index 0000000..5de6e3d --- /dev/null +++ b/tests/t304/debian/rules @@ -0,0 +1,26 @@ +#!/usr/bin/make -f +%: + dh $@ --buildsystem=python_distutils + +override_dh_auto_build: +override_dh_auto_install: + +override_dh_install: + dh_install + DH_VERBOSE=1 ../../dh_python3 -p foo + DH_VERBOSE=1 ../../dh_python3 -p foo /usr/share/bar -X spam.py + DH_VERBOSE=1 ../../dh_python3 -p foo /usr/share/baz32 --shebang '/usr/bin/python3.2 -OO' + + # Argument priority: -O > regular args > DH_OPTIONS + DH_VERBOSE=1 DH_OPTIONS=--shebang=/usr/bin/python3.0 \ + ../../dh_python3 -p overrides \ + --shebang=/usr/bin/python3-dbg \ + /usr/share/overrides1 + DH_VERBOSE=1 ../../dh_python3 -p overrides \ + --shebang=/usr/bin/python3.0 \ + -O=--shebang=/usr/bin/python3-dbg \ + -O=--foo=bar \ + /usr/share/overrides2 + +clean: + dh_clean diff --git a/tests/t304/debian/source/format b/tests/t304/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/t304/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/t304/foo.py b/tests/t304/foo.py new file mode 100755 index 0000000..fef29a7 --- /dev/null +++ b/tests/t304/foo.py @@ -0,0 +1,2 @@ +#!/usr/local/bin/python3.4 +"/usr/local/bin/python3.4 hardcoded in shebang" diff --git a/tests/t304/setup.py b/tests/t304/setup.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/t304/setup.py diff --git a/tests/t304/spam.py b/tests/t304/spam.py new file mode 100644 index 0000000..c8b0fd9 --- /dev/null +++ b/tests/t304/spam.py @@ -0,0 +1 @@ +print('spam') diff --git a/tests/t305/Makefile b/tests/t305/Makefile new file mode 100644 index 0000000..1ee30fc --- /dev/null +++ b/tests/t305/Makefile @@ -0,0 +1,14 @@ +#!/usr/bin/make -f + +include ../common.mk +clean: clean-common + +check: + grep -qe "Depends: .*python3\(:any\)\?" debian/foo5a/DEBIAN/control + grep -qe "Depends: .*python3\(:any\)\?" debian/foo5b/DEBIAN/control + grep -qe "Depends: .*python3\(:any\)\?" debian/foo5c/DEBIAN/control + grep -qe "Depends: .*python3\(:any\)\?" debian/foo5d/DEBIAN/control + grep -qe "Depends: .*python3\(:any\)\?" debian/foo5e/DEBIAN/control + grep -qe "Depends: .*python3\(:any\)\?" debian/foo5f/DEBIAN/control + grep -Fxq dh_python3 debian/foo5a.debhelper.log.end_dh_install + grep -Fxc dh_python3 debian/foo5a.debhelper.log.end_dh_install | grep -Fxq 1 diff --git a/tests/t305/debian/changelog b/tests/t305/debian/changelog new file mode 100644 index 0000000..d30d06c --- /dev/null +++ b/tests/t305/debian/changelog @@ -0,0 +1,5 @@ +foo (1.0) unstable; urgency=low + + * Initial release + + -- Maximilian Engelhardt <maxi@daemonizer.de> Fri, 02 Apr 2021 14:30:25 +0200 diff --git a/tests/t305/debian/compat b/tests/t305/debian/compat new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/tests/t305/debian/compat @@ -0,0 +1 @@ +12 diff --git a/tests/t305/debian/control b/tests/t305/debian/control new file mode 100644 index 0000000..8eafc3e --- /dev/null +++ b/tests/t305/debian/control @@ -0,0 +1,43 @@ +Source: foo +Section: misc +Priority: optional +Maintainer: Maximilian Engelhardt <maxi@daemonizer.de> +Build-Depends: debhelper (>= 12.9) +Build-Depends-Indep: python3 +Standards-Version: 4.5.1 + +Package: foo5a +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: example 5a - private shebangs + example package #5 - shebang related tests in private dirs + +Package: foo5b +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: example 5b - private shebangs + example package #5 - shebang related tests in private dirs + +Package: foo5c +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: example 5c - private shebangs + example package #5 - shebang related tests in private dirs + +Package: foo5d +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: example 5d - private shebangs + example package #5 - shebang related tests in private dirs + +Package: foo5e +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: example 5e - private shebangs + example package #5 - shebang related tests in private dirs + +Package: foo5f +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: example 5f - private shebangs + example package #5 - shebang related tests in private dirs diff --git a/tests/t305/debian/copyright b/tests/t305/debian/copyright new file mode 100644 index 0000000..32bbc0d --- /dev/null +++ b/tests/t305/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2021, Maximilian Engelhardt <maxi@daemonizer.de> and +is licensed under the MIT License. diff --git a/tests/t305/debian/foo5a.install b/tests/t305/debian/foo5a.install new file mode 100644 index 0000000..38009bc --- /dev/null +++ b/tests/t305/debian/foo5a.install @@ -0,0 +1 @@ +foo5a /usr/share/foo/ diff --git a/tests/t305/debian/foo5b.install b/tests/t305/debian/foo5b.install new file mode 100644 index 0000000..0fd0869 --- /dev/null +++ b/tests/t305/debian/foo5b.install @@ -0,0 +1 @@ +foo5b /usr/share/foo/ diff --git a/tests/t305/debian/foo5c.install b/tests/t305/debian/foo5c.install new file mode 100644 index 0000000..a40b010 --- /dev/null +++ b/tests/t305/debian/foo5c.install @@ -0,0 +1 @@ +foo5c /usr/share/foo/ diff --git a/tests/t305/debian/foo5d.install b/tests/t305/debian/foo5d.install new file mode 100644 index 0000000..e6e2aea --- /dev/null +++ b/tests/t305/debian/foo5d.install @@ -0,0 +1 @@ +foo5d /usr/share/foo/ diff --git a/tests/t305/debian/rules b/tests/t305/debian/rules new file mode 100755 index 0000000..c43eaae --- /dev/null +++ b/tests/t305/debian/rules @@ -0,0 +1,22 @@ +#!/usr/bin/make -f +%: + dh $@ --buildsystem=none + +override_dh_auto_install: + dh_auto_install + mkdir -p debian/foo5e/usr/share/foo/ + echo "#! /usr/bin/env $(shell py3versions -d)\n\"/usr/bin/env DEFAULT_PYTHON shebang\"" > debian/foo5e/usr/share/foo/foo5e + chmod +x debian/foo5e/usr/share/foo/foo5e + mkdir -p debian/foo5f/usr/share/foo/ + echo "#! /usr/bin/$(shell py3versions -d)\n\"/usr/bin/DEFAULT_PYTHON shebang\"" > debian/foo5f/usr/share/foo/foo5f + chmod +x debian/foo5f/usr/share/foo/foo5f + +override_dh_install: + dh_install + DH_VERBOSE=1 ../../dh_python3 -p foo5a /usr/share/foo + DH_VERBOSE=1 ../../dh_python3 --remaining-packages /usr/share/foo + cp debian/foo5a.debhelper.log debian/foo5a.debhelper.log.end_dh_install + +clean: + rm -f debian/foo5a.debhelper.log.end_dh_install + dh_clean diff --git a/tests/t305/debian/source/format b/tests/t305/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/t305/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/t305/foo5a b/tests/t305/foo5a new file mode 100755 index 0000000..3045ad0 --- /dev/null +++ b/tests/t305/foo5a @@ -0,0 +1,2 @@ +#! /usr/bin/python3 +"/usr/bin/python3 shebang" diff --git a/tests/t305/foo5b b/tests/t305/foo5b new file mode 100755 index 0000000..49352f5 --- /dev/null +++ b/tests/t305/foo5b @@ -0,0 +1,2 @@ +#! /usr/bin/python +"/usr/bin/python shebang" diff --git a/tests/t305/foo5c b/tests/t305/foo5c new file mode 100755 index 0000000..2ee0891 --- /dev/null +++ b/tests/t305/foo5c @@ -0,0 +1,2 @@ +#! /usr/bin/env python3 +"/usr/bin/env python3 shebang" diff --git a/tests/t305/foo5d b/tests/t305/foo5d new file mode 100755 index 0000000..b698372 --- /dev/null +++ b/tests/t305/foo5d @@ -0,0 +1,2 @@ +#! /usr/bin/env python +"/usr/bin/env python shebang" diff --git a/tests/t306/Makefile b/tests/t306/Makefile new file mode 100644 index 0000000..9dbf8c4 --- /dev/null +++ b/tests/t306/Makefile @@ -0,0 +1,17 @@ +#!/usr/bin/make -f +include ../common.mk + +all: run check + +run: clean + dpkg-buildpackage -b -us -uc + +check: + grep -qe "^Depends: .*python3\(:any\)\? (<< 3\.[0-9]\+)" \ + debian/foo/DEBIAN/control + grep -qe "^Depends: .*python3\(:any\)\? (>= 3\.[0-9]\+~)" \ + debian/foo/DEBIAN/control + +clean: + ./debian/rules clean + rm -rf lib/Foo.egg-info build diff --git a/tests/t306/debian/changelog b/tests/t306/debian/changelog new file mode 100644 index 0000000..874dc1d --- /dev/null +++ b/tests/t306/debian/changelog @@ -0,0 +1,5 @@ +foo (0.1) unstable; urgency=low + + * Initial release + + -- Maximilian Engelhardt <maxi@daemonizer.de> Sun, 04 Apr 2021 13:09:48 +0200 diff --git a/tests/t306/debian/compat b/tests/t306/debian/compat new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/tests/t306/debian/compat @@ -0,0 +1 @@ +12 diff --git a/tests/t306/debian/control b/tests/t306/debian/control new file mode 100644 index 0000000..79446f3 --- /dev/null +++ b/tests/t306/debian/control @@ -0,0 +1,13 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Maximilian Engelhardt <maxi@daemonizer.de> +Build-Depends: debhelper (>= 12.9), python3-all-dev:any +Standards-Version: 4.5.1 + +Package: foo +Architecture: any +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with python3-all-dev dependency using :any + example package #6 - private Python extensions and python3-all-dev:any + dependency diff --git a/tests/t306/debian/copyright b/tests/t306/debian/copyright new file mode 100644 index 0000000..32bbc0d --- /dev/null +++ b/tests/t306/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2021, Maximilian Engelhardt <maxi@daemonizer.de> and +is licensed under the MIT License. diff --git a/tests/t306/debian/rules b/tests/t306/debian/rules new file mode 100755 index 0000000..d1ffc6a --- /dev/null +++ b/tests/t306/debian/rules @@ -0,0 +1,14 @@ +#!/usr/bin/make -f + +%: + dh $@ --buildsystem=none + +override_dh_install: + dh_install + DH_VERBOSE=1 ../../dh_python3 + +override_dh_auto_build: + python3 setup.py build + +override_dh_auto_install: + python3 setup.py install --root=debian/foo/ --install-lib=/usr/share/foo/python diff --git a/tests/t306/debian/source/format b/tests/t306/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/t306/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/t306/lib/__init__.py b/tests/t306/lib/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/t306/lib/__init__.py diff --git a/tests/t306/lib/bar.c b/tests/t306/lib/bar.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/t306/lib/bar.c diff --git a/tests/t306/lib/foo.py b/tests/t306/lib/foo.py new file mode 100644 index 0000000..9dd52e6 --- /dev/null +++ b/tests/t306/lib/foo.py @@ -0,0 +1,6 @@ +import foo.bar + + +class Foo(object): + def __init__(self): + foo.bar diff --git a/tests/t306/setup.py b/tests/t306/setup.py new file mode 100755 index 0000000..25727f2 --- /dev/null +++ b/tests/t306/setup.py @@ -0,0 +1,12 @@ +#! /usr/bin/python3 +from distutils.core import setup, Extension + +setup(name='Foo', + version='0.1', + description="package with private Python extension", + author='Maximilian Engelhardt', + author_email='maxi@daemonizer.de', + url='http://www.debian.org/', + ext_modules=[Extension('foo/bar', ['lib/bar.c'])], + packages=['foo'], + package_dir={'foo': 'lib'}) diff --git a/tests/ta01/Makefile b/tests/ta01/Makefile new file mode 100644 index 0000000..65c9796 --- /dev/null +++ b/tests/ta01/Makefile @@ -0,0 +1,39 @@ +all: run check + +run: + @echo No build needed +ifeq ($(AUTOPKGTEST_TMP),) + @echo NOTE this test uses the system pybuild-autopkgtest, not the working directory +endif + +check: pass fail + +pass: + @echo "==============================================================" + @echo "= pybuild-autopkgtest passes when tests pass =" + @echo "==============================================================" + @echo + pybuild-autopkgtest + test -f marker-before-pybuild-autopkgtest + test -f marker-after-pybuild-autopkgtest + grep '^1$$' marker-PYBUILD_AUTOPKGTEST + @echo '------------------------------' + @echo "OK: pybuild-autopkgtest passed" + @echo '------------------------------' + @echo + +fail: + @echo "==============================================================" + @echo "= pybuild-autopkgtest fails when tests fail =" + @echo "==============================================================" + @echo + ! FAILS=1 pybuild-autopkgtest + @echo '------------------------------' + @echo "OK: pybuild-autopkgtest failed" + @echo '------------------------------' + @echo + +clean: +ifneq ($(AUTOPKGTEST_TMP),) + rm -r $(AUTOPKGTEST_TMP)/* +endif diff --git a/tests/ta01/debian/changelog b/tests/ta01/debian/changelog new file mode 100644 index 0000000..322011c --- /dev/null +++ b/tests/ta01/debian/changelog @@ -0,0 +1,5 @@ +foo (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/ta01/debian/control b/tests/ta01/debian/control new file mode 100644 index 0000000..f8922fc --- /dev/null +++ b/tests/ta01/debian/control @@ -0,0 +1,15 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , pybuild-plugin-pyproject + , python3-all + , python3-setuptools +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: any +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #8 diff --git a/tests/ta01/debian/rules b/tests/ta01/debian/rules new file mode 100755 index 0000000..e53f0aa --- /dev/null +++ b/tests/ta01/debian/rules @@ -0,0 +1,33 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild --build --verbose + +override_dh_auto_install: + ../../pybuild --install + +override_dh_auto_test: + ../../pybuild --test + +override_dh_auto_clean: + ../../pybuild --clean --verbose + rm -rf .pybuild foo.egg-info + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 + +before-pybuild-autopkgtest: + echo $(PYBUILD_AUTOPKGTEST) > marker-PYBUILD_AUTOPKGTEST + touch marker-before-pybuild-autopkgtest + +after-pybuild-autopkgtest: + touch marker-after-pybuild-autopkgtest diff --git a/tests/ta01/foo/__init__.py b/tests/ta01/foo/__init__.py new file mode 100644 index 0000000..92d9a9a --- /dev/null +++ b/tests/ta01/foo/__init__.py @@ -0,0 +1 @@ +"Nothing here" diff --git a/tests/ta01/pyproject.toml b/tests/ta01/pyproject.toml new file mode 100644 index 0000000..9787c3b --- /dev/null +++ b/tests/ta01/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/tests/ta01/setup.cfg b/tests/ta01/setup.cfg new file mode 100644 index 0000000..877dcf7 --- /dev/null +++ b/tests/ta01/setup.cfg @@ -0,0 +1,10 @@ +[metadata] +name = foo +version = 0.1 +description = My package description +long_description = My long description +license = Expat + +[options] +zip_safe = False +packages = find: diff --git a/tests/ta01/tests/__init__.py b/tests/ta01/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/ta01/tests/__init__.py diff --git a/tests/ta01/tests/test_foo.py b/tests/ta01/tests/test_foo.py new file mode 100644 index 0000000..263a9fb --- /dev/null +++ b/tests/ta01/tests/test_foo.py @@ -0,0 +1,7 @@ +import os +import unittest + +class TestPybuildAutopkgtest(unittest.TestCase): + + def test_pass_or_fails(self): + self.assertIsNone(os.environ.get("FAILS")) diff --git a/tests/ta02/Makefile b/tests/ta02/Makefile new file mode 100644 index 0000000..f6c26ed --- /dev/null +++ b/tests/ta02/Makefile @@ -0,0 +1,17 @@ +all: run check + +run: + @echo No build needed +ifeq ($(AUTOPKGTEST_TMP),) + @echo NOTE this test uses the system pybuild-autopkgtest, not the working directory +endif + +check: + DH_VERBOSE=1 pybuild-autopkgtest + test -e custom-test-executed + +clean: + ./debian/rules clean +ifneq ($(AUTOPKGTEST_TMP),) + rm -r $(AUTOPKGTEST_TMP)/* +endif diff --git a/tests/ta02/debian/changelog b/tests/ta02/debian/changelog new file mode 100644 index 0000000..322011c --- /dev/null +++ b/tests/ta02/debian/changelog @@ -0,0 +1,5 @@ +foo (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/ta02/debian/control b/tests/ta02/debian/control new file mode 100644 index 0000000..648c259 --- /dev/null +++ b/tests/ta02/debian/control @@ -0,0 +1,16 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , pybuild-plugin-pyproject + , python3-all + , python3-pytest + , python3-setuptools +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: any +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #8 diff --git a/tests/ta02/debian/rules b/tests/ta02/debian/rules new file mode 100755 index 0000000..b612080 --- /dev/null +++ b/tests/ta02/debian/rules @@ -0,0 +1,28 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo +export PYBUILD_TEST_CUSTOM=1 +export PYBUILD_TEST_ARGS=touch {dir}/custom-test-executed + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild --build --verbose + +override_dh_auto_install: + ../../pybuild --install + +override_dh_auto_test: + ../../pybuild --test + +override_dh_auto_clean: + ../../pybuild --clean --verbose + rm -rf custom-test-executed foo.egg-info + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 diff --git a/tests/ta02/foo/__init__.py b/tests/ta02/foo/__init__.py new file mode 100644 index 0000000..92d9a9a --- /dev/null +++ b/tests/ta02/foo/__init__.py @@ -0,0 +1 @@ +"Nothing here" diff --git a/tests/ta02/pyproject.toml b/tests/ta02/pyproject.toml new file mode 100644 index 0000000..9787c3b --- /dev/null +++ b/tests/ta02/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/tests/ta02/setup.cfg b/tests/ta02/setup.cfg new file mode 100644 index 0000000..877dcf7 --- /dev/null +++ b/tests/ta02/setup.cfg @@ -0,0 +1,10 @@ +[metadata] +name = foo +version = 0.1 +description = My package description +long_description = My long description +license = Expat + +[options] +zip_safe = False +packages = find: diff --git a/tests/ta02/tests/__init__.py b/tests/ta02/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/ta02/tests/__init__.py diff --git a/tests/ta02/tests/test_foo.py b/tests/ta02/tests/test_foo.py new file mode 100644 index 0000000..2cac2b2 --- /dev/null +++ b/tests/ta02/tests/test_foo.py @@ -0,0 +1,7 @@ +import unittest + +class TestThatWeDontRunTheseTests(unittest.TestCase): + + def test_fail(self): + # We want the custom test runner to run, not this test suite + self.assertTrue(False) diff --git a/tests/test-package-show-info b/tests/test-package-show-info new file mode 100755 index 0000000..bdea2b4 --- /dev/null +++ b/tests/test-package-show-info @@ -0,0 +1,16 @@ +#!/bin/sh + +set -ue + +changes=$1 +testname=$(basename $PWD) +basedir=$(dirname $changes) + +echo "--------------------------------------------------" +echo "Test $testname has created the following packages:" +for deb in $(sed -nr 's/.* ([^ ]*\.deb)$/\1/p' $changes | sort -u); do + echo "--------------------------------------------------" + echo "PACKAGE $deb:" + dpkg-deb --info "$basedir/$deb" +done +echo "--------------------------------------------------" diff --git a/tests/test_debhelper.py b/tests/test_debhelper.py new file mode 100644 index 0000000..285440c --- /dev/null +++ b/tests/test_debhelper.py @@ -0,0 +1,192 @@ +from tempfile import TemporaryDirectory +import unittest +import os + +from dhpython.debhelper import DebHelper, build_options + + +class DebHelperTestCase(unittest.TestCase): + impl = 'cpython3' + control = [] + options = {} + parse_control = True + + def build_options(self): + return build_options(**self.options) + + def setUp(self): + self.tempdir = TemporaryDirectory() + self.addCleanup(self.tempdir.cleanup) + + old_wd = os.getcwd() + os.chdir(self.tempdir.name) + self.addCleanup(os.chdir, old_wd) + + os.mkdir('debian') + with open('debian/control', 'w') as f: + f.write('\n'.join(self.control)) + if self.parse_control: + self.dh = DebHelper(self.build_options(), impl=self.impl) + + +CONTROL = [ + 'Source: foo-src', + 'Build-Depends: python3-all,', + ' python-all,', + ' bar (<< 2) [amd64],', + ' baz (>= 1.0)', + 'X-Python3-Version: >= 3.1, << 3.10', + '', + 'Architecture: all', + 'Package: python3-foo', + 'Depends: ${python3:Depends}', + '', + 'Package: python3-foo-ext', + 'Architecture: any', + 'Depends: ${python3:Depends}, ' + '# COMMENT', + ' ${shlibs:Depends},', + '', + 'Package: python-foo', + 'Architecture: all', + 'Depends: ${python:Depends}', + '', + '', + 'Package: foo', + 'Architecture: all', + 'Depends: ${python3:Depends}', + '', + '', + 'Package: recfoo', + 'Architecture: all', + 'Recommends: ${python3:Depends}', + '', + '', +] + +class TestControlBlockParsing(DebHelperTestCase): + control = CONTROL + + def test_parses_source(self): + self.assertEqual(self.dh.source_name, 'foo-src') + + def test_parses_build_depends(self): + self.assertEqual(self.dh.build_depends, { + 'python3-all': {None: None}, + 'python-all': {None: None}, + 'bar': {'amd64': '<< 2'}, + 'baz': {None: '>= 1.0'}, + }) + + def test_parses_XPV(self): + self.assertEqual(self.dh.python_version, '>= 3.1, << 3.10') + + def test_parses_packages(self): + self.assertEqual(list(self.dh.packages.keys()), + ['python3-foo', 'python3-foo-ext', 'foo', 'recfoo']) + + def test_parses_arch(self): + self.assertEqual(self.dh.packages['python3-foo-ext']['arch'], 'any') + + def test_parses_arch_all(self): + self.assertEqual(self.dh.packages['python3-foo']['arch'], 'all') + + +class TestControlSkipIndep(DebHelperTestCase): + control = CONTROL + options = { + 'arch': True, + } + + def test_skip_indep(self): + self.assertEqual(list(self.dh.packages.keys()), ['python3-foo-ext']) + + +class TestControlSkipArch(DebHelperTestCase): + control = CONTROL + options = { + 'arch': False, + } + + def test_skip_arch(self): + self.assertEqual(list(self.dh.packages.keys()), + ['python3-foo', 'foo', 'recfoo']) + + +class TestControlSinglePkg(DebHelperTestCase): + control = CONTROL + options = { + 'package': ['python3-foo'], + } + + def test_parses_packages(self): + self.assertEqual(list(self.dh.packages.keys()), ['python3-foo']) + + +class TestControlSkipSinglePkg(DebHelperTestCase): + control = CONTROL + options = { + 'no_package': ['python3-foo'], + } + + def test_parses_packages(self): + self.assertEqual(list(self.dh.packages.keys()), + ['python3-foo-ext', 'foo', 'recfoo']) + + +class TestControlBlockParsingPy2(DebHelperTestCase): + control = CONTROL + impl = 'cpython2' + + def test_parses_packages(self): + self.assertEqual(list(self.dh.packages.keys()), ['python-foo']) + + +class TestControlNoBinaryPackages(DebHelperTestCase): + control = [ + 'Source: foo-src', + 'Build-Depends: python3-all', + '', + ] + parse_control = False + + def test_throws_error(self): + msg = ('Unable to parse debian/control, found less than 2 paragraphs') + with self.assertRaisesRegex(Exception, msg): + DebHelper(self.build_options()) + + +class TestControlMissingPackage(DebHelperTestCase): + control = [ + 'Source: foo-src', + 'Build-Depends: python3-all', + '', + 'Architecture: all', + ] + parse_control = False + + def test_parses_packages(self): + msg = ('Unable to parse debian/control, paragraph 2 missing Package ' + 'field') + with self.assertRaisesRegex(Exception, msg): + DebHelper(self.build_options()) + + +class TestRemainingPackages(DebHelperTestCase): + control = CONTROL + options = { + 'remaining_packages': True, + } + parse_control = False + + def setUp(self): + super().setUp() + with open('debian/python3-foo.debhelper.log', 'w') as f: + f.write('dh_python3\n') + with open('debian/python3-foo-ext.debhelper.log', 'w') as f: + f.write('dh_foobar\n') + self.dh = DebHelper(self.build_options(), impl=self.impl) + + def test_skips_logged_packages(self): + self.assertEqual(list(self.dh.packages.keys()), + ['python3-foo-ext', 'foo', 'recfoo']) diff --git a/tests/test_depends.py b/tests/test_depends.py new file mode 100644 index 0000000..d208438 --- /dev/null +++ b/tests/test_depends.py @@ -0,0 +1,726 @@ +import os +import logging +import platform +import unittest +from copy import deepcopy +from pickle import dumps +from tempfile import TemporaryDirectory + +from dhpython.depends import Dependencies +from dhpython.version import Version + +from tests.common import FakeOptions + + +def pep386(d): + """Mark all pydist entries as being PEP386""" + for k, v in d.items(): + if isinstance(v, str): + d[k] = {'dependency': v} + d[k].setdefault('standard', 'PEP386') + return d + + +def py27(d): + """Mark all pydist entries as being for Python 2.7""" + for k, v in d.items(): + if isinstance(v, str): + d[k] = {'dependency': v} + d[k].setdefault('versions', {Version('2.7')}) + return d + + +def prime_pydist(impl, pydist): + """Fake the pydist data for impl. Returns a cleanup function""" + from dhpython.pydist import load + + for name, entries in pydist.items(): + if not isinstance(entries, list): + pydist[name] = entries = [entries] + for i, entry in enumerate(entries): + if isinstance(entry, str): + entries[i] = entry = {'dependency': entry} + entry.setdefault('name', name) + entry.setdefault('standard', '') + entry.setdefault('rules', []) + entry.setdefault('versions', set()) + + key = dumps(((impl,), {})) + load.cache[key] = pydist + return lambda: load.cache.pop(key) + + +class DependenciesTestCase(unittest.TestCase): + pkg = 'foo' + impl = 'cpython3' + pydist = {} + stats = { + 'compile': False, + 'dist-info': set(), + 'egg-info': set(), + 'ext_no_version': set(), + 'ext_vers': set(), + 'nsp.txt': set(), + 'private_dirs': {}, + 'public_vers': set(), + 'requires.txt': set(), + 'shebangs': set(), + } + requires = {} + dist_info_metadata = {} + options = FakeOptions() + parse = True + + def setUp(self): + self.d = Dependencies(self.pkg, self.impl) + + stats = deepcopy(self.stats) + write_files = {} + if self.requires: + for fn, lines in self.requires.items(): + write_files[fn] = lines + stats['requires.txt'].add(fn) + + if self.dist_info_metadata: + for fn, lines in self.dist_info_metadata.items(): + write_files[fn] = lines + stats['dist-info'].add(fn) + + if write_files: + self.tempdir = TemporaryDirectory() + self.addCleanup(self.tempdir.cleanup) + old_wd = os.getcwd() + os.chdir(self.tempdir.name) + self.addCleanup(os.chdir, old_wd) + + for fn, lines in write_files.items(): + os.makedirs(os.path.dirname(fn)) + with open(fn, 'w') as f: + f.write('\n'.join(lines)) + + cleanup = prime_pydist(self.impl, self.pydist) + self.addCleanup(cleanup) + + if self.parse: + self.d.parse(stats, self.options) + else: + self.prepared_stats = stats + + def assertNotInDepends(self, pkg): + """Assert that pkg doesn't appear *anywhere* in self.d.depends""" + for dep in self.d.depends: + for alt in dep.split('|'): + alt = alt.strip().split('(', 1)[0].strip() + if pkg == alt: + raise AssertionError(f'{pkg} appears in {alt}') + + +class TestRequiresCPython3(DependenciesTestCase): + options = FakeOptions(guess_deps=True) + pydist = { + 'bar': 'python3-bar', + 'baz': {'dependency': 'python3-baz', 'standard': 'PEP386'}, + 'quux': {'dependency': 'python3-quux', 'standard': 'PEP386'}, + } + requires = { + 'debian/foo/usr/lib/python3/dist-packages/foo.egg-info/requires.txt': ( + 'bar', + 'baz >= 1.0', + 'quux', + ), + } + + def test_depends_on_bar(self): + self.assertIn('python3-bar', self.d.depends) + + def test_depends_on_baz(self): + self.assertIn('python3-baz (>= 1.0)', self.d.depends) + + +class TestRequiresPyPy(DependenciesTestCase): + impl = 'pypy' + options = FakeOptions(guess_deps=True) + pydist = { + 'bar': 'pypy-bar', + 'baz': {'dependency': 'pypy-baz', 'standard': 'PEP386'}, + 'quux': {'dependency': 'pypy-quux', 'standard': 'PEP386'}, + } + requires = { + 'debian/foo/usr/lib/pypy/dist-packages/foo.egg-info/requires.txt': ( + 'bar', + 'baz >= 1.0', + 'quux', + ) + } + + def test_depends_on_bar(self): + self.assertIn('pypy-bar', self.d.depends) + + def test_depends_on_baz(self): + self.assertIn('pypy-baz (>= 1.0)', self.d.depends) + + +class TestRequiresCompatible(DependenciesTestCase): + options = FakeOptions(guess_deps=True) + pydist = { + 'bar': 'python3-bar', + 'baz': {'dependency': 'python3-baz', 'standard': 'PEP386'}, + 'qux': {'dependency': 'python3-qux', 'standard': 'PEP386'}, + 'quux': {'dependency': 'python3-quux', 'standard': 'PEP386'}, + } + requires = { + 'debian/foo/usr/lib/python3/dist-packages/foo.egg-info/requires.txt': ( + 'bar', + 'baz ~= 1.1', + 'qux == 1.*', + 'quux', + ), + } + + def test_depends_on_bar(self): + self.assertIn('python3-bar', self.d.depends) + + def test_depends_on_baz(self): + self.assertIn('python3-baz (>= 1.1), python3-baz (<< 2)', self.d.depends) + + def test_depends_on_qux(self): + self.assertIn('python3-qux (>= 1.0), python3-qux (<< 2)', self.d.depends) + + +class TestRequiresDistPython3(DependenciesTestCase): + options = FakeOptions(guess_deps=True) + pydist = { + 'bar': 'python3-bar', + 'baz': {'dependency': 'python3-baz', 'standard': 'PEP386'}, + 'qux': {'dependency': 'python3-qux', 'standard': 'PEP386'}, + 'quux': {'dependency': 'python3-quux', 'standard': 'PEP386'}, + } + dist_info_metadata = { + 'debian/foo/usr/lib/python3/dist-packages/foo.dist-info/METADATA': ( + 'Requires-Dist: bar', + 'Requires-Dist: baz >= 1.0', + 'Requires-Dist: qux == 1.*', + 'Requires-Dist: quux ~= 1.1', + ), + } + + def test_depends_on_bar(self): + self.assertIn('python3-bar', self.d.depends) + + def test_depends_on_baz(self): + self.assertIn('python3-baz (>= 1.0)', self.d.depends) + + def test_depends_on_qux(self): + self.assertIn('python3-qux (>= 1.0), python3-qux (<< 2)', + self.d.depends) + + def test_depends_on_quux(self): + self.assertIn('python3-quux (>= 1.1), python3-quux (<< 2)', + self.d.depends) + + +class TestEnvironmentMarkersDistInfo(DependenciesTestCase): + options = FakeOptions(guess_deps=True, depends_section=['feature']) + pydist = pep386({ + 'no_markers': 'python3-no-markers', + 'os_posix': 'python3-os-posix', + 'os_java': 'python3-os-java', + 'sys_platform_linux': 'python3-sys-platform-linux', + 'sys_platform_darwin': 'python3-sys-platform-darwin', + 'platform_machine_x86_64': 'python3-platform-machine-x86-64', + 'platform_machine_mips64': 'python3-platform-machine-mips64', + 'platform_python_implementation_cpython': + 'python3-platform-python-implementation-cpython', + 'platform_python_implementation_jython': + 'python3-platform-python-implementation-jython', + 'platform_release_lt2': 'python3-platform-release-lt2', + 'platform_release_ge2': 'python3-platform-release-ge2', + 'platform_system_linux': 'python3-platform-system-linux', + 'platform_system_windows': 'python3-platform-system-windows', + 'platform_version_lt1': 'python3-platform-version-lt1', + 'platform_version_ge1': 'python3-platform-version-ge1', + 'python_version_ge3': 'python3-python-version-ge3', + 'python_version_gt3': 'python3-python-version-gt3', + 'python_version_lt3': 'python3-python-version-lt3', + 'python_version_lt30': 'python3-python-version-lt30', + 'python_version_lt35': 'python3-python-version-lt35', + 'python_version_le35': 'python3-python-version-le35', + 'python_version_ge27': 'python3-python-version-ge27', + 'python_version_ge35': 'python3-python-version-ge35', + 'python_version_gt35': 'python3-python-version-gt35', + 'python_version_eq35': 'python3-python-version-eq35', + 'python_version_ne35': 'python3-python-version-ne35', + 'python_version_aeq35': 'python3-python-version-aeq35', + 'python_version_ceq35': 'python3-python-version-ceq35', + 'python_version_weq35': 'python3-python-version-weq35', + 'python_version_full_lt300': 'python3-python-version-full-lt300', + 'python_version_full_lt351': 'python3-python-version-full-lt351', + 'python_version_full_le351': 'python3-python-version-full-le351', + 'python_version_full_ge351': 'python3-python-version-full-ge351', + 'python_version_full_ge351a1': 'python3-python-version-full-ge351a1', + 'python_version_full_ge351b1post1': + 'python3-python-version-full-ge351b1post1', + 'python_version_full_gt351': 'python3-python-version-full-gt351', + 'python_version_full_eq351': 'python3-python-version-full-eq351', + 'python_version_full_ne351': 'python3-python-version-full-ne351', + 'python_version_full_aeq351': 'python3-python-version-full-aeq351', + 'python_version_full_ceq351': 'python3-python-version-full-ceq351', + 'python_version_full_weq35': 'python3-python-version-full-weq35', + 'implementation_name_cpython': 'python3-implementation-name-cpython', + 'implementation_name_pypy': 'python3-implementation-name-pypy', + 'implementation_version_lt35': 'python3-implementation-version-lt35', + 'implementation_version_ge35': 'python3-implementation-version-ge35', + 'invalid_marker': 'python3-invalid-marker', + 'extra_feature': 'python3-extra-feature', + 'extra_test': 'python3-extra-test', + 'complex_marker': 'python3-complex-marker', + 'complex_marker_2': 'python3-complex-marker-2', + 'no_markers_2': 'python3-no-markers-2', + }) + dist_info_metadata = { + 'debian/foo/usr/lib/python3/dist-packages/foo.dist-info/METADATA': ( + "Requires-Dist: no_markers", + "Requires-Dist: os_posix; (os_name == 'posix')", + 'Requires-Dist: os_java; os_name == "java"', + "Requires-Dist: sys_platform_linux ; sys_platform == 'linux'", + "Requires-Dist: sys_platform_darwin;sys_platform == 'darwin'", + "Requires-Dist: platform_machine_x86_64; " + "platform_machine == 'x86_64'", + "Requires-Dist: platform_machine_mips64; " + "platform_machine == 'mips64'", + "Requires-Dist: platform_python_implementation_cpython; " + "platform_python_implementation == 'CPython'", + "Requires-Dist: platform_python_implementation_jython; " + "platform_python_implementation == 'Jython'", + "Requires-Dist: platform_release_lt2; platform_release < '2.0'", + "Requires-Dist: platform_release_ge2; platform_release >= '2.0'", + "Requires-Dist: platform_system_linux; platform_system == 'Linux'", + "Requires-Dist: platform_system_windows; " + "platform_system == 'Windows'", + "Requires-Dist: platform_version_lt1; platform_version < '1'", + "Requires-Dist: platform_version_ge1; platform_version >= '1'", + "Requires-Dist: python_version_ge3; python_version >= '3'", + "Requires-Dist: python_version_gt3; python_version > '3'", + "Requires-Dist: python_version_lt3; python_version < '3'", + "Requires-Dist: python_version_lt30; python_version < '3.0'", + "Requires-Dist: python_version_lt35; python_version < '3.5'", + "Requires-Dist: python_version_le35; python_version <= '3.5'", + "Requires-Dist: python_version_gt35; python_version > '3.5'", + "Requires-Dist: python_version_ge27; python_version >= '2.7'", + "Requires-Dist: python_version_ge35; python_version >= '3.5'", + "Requires-Dist: python_version_eq35; python_version == '3.5'", + "Requires-Dist: python_version_ne35; python_version != '3.5'", + "Requires-Dist: python_version_aeq35; python_version === '3.5'", + "Requires-Dist: python_version_ceq35; python_version ~= '3.5'", + "Requires-Dist: python_version_weq35; python_version == '3.5.*'", + "Requires-Dist: python_version_full_lt300; " + "python_full_version < '3.0.0'", + "Requires-Dist: python_version_full_lt351; " + "python_full_version < '3.5.1'", + "Requires-Dist: python_version_full_le351; " + "python_full_version <= '3.5.1'", + "Requires-Dist: python_version_full_gt351; " + "python_full_version > '3.5.1'", + "Requires-Dist: python_version_full_ge351; " + "python_full_version >= '3.5.1'", + "Requires-Dist: python_version_full_ge351a1; " + "python_full_version >= '3.5.1a1'", + "Requires-Dist: python_version_full_ge351b1post1; " + "python_full_version >= '3.5.1b1.post1'", + "Requires-Dist: python_version_full_eq351; " + "python_full_version == '3.5.1'", + "Requires-Dist: python_version_full_ne351; " + "python_full_version != '3.5.1'", + "Requires-Dist: python_version_full_aeq351; " + "python_full_version === '3.5.1'", + "Requires-Dist: python_version_full_ceq351; " + "python_full_version ~= '3.5.1'", + "Requires-Dist: python_version_full_weq35; " + "python_full_version == '3.5.*'", + "Requires-Dist: implementation_name_cpython; " + "implementation_name == 'cpython'", + "Requires-Dist: implementation_name_pypy; " + "implementation_name == 'pypy'", + "Requires-Dist: implementation_version_lt35; " + "implementation_version < '3.5'", + "Requires-Dist: implementation_version_ge35; " + "implementation_version >= '3.5'", + "Requires-Dist: invalid_marker; invalid_marker > '1'", + "Requires-Dist: extra_feature; extra == 'feature'", + "Requires-Dist: extra_test; extra == 'test'", + "Requires-Dist: complex_marker; os_name != 'windows' " + "and implementation_name == 'cpython'", + "Requires-Dist: complex_marker_2; (python_version > \"3.4\") " + "and extra == 'test'", + "Requires-Dist: no_markers_2", + ), + } + + def test_depends_on_unmarked_packages(self): + self.assertIn('python3-no-markers', self.d.depends) + + def test_depends_on_posix_packages(self): + self.assertIn('python3-os-posix', self.d.depends) + + def test_skips_non_posix_packages(self): + self.assertNotInDepends('python3-os-java') + + def test_depends_on_linux_packages(self): + self.assertIn('python3-sys-platform-linux', self.d.depends) + + def test_skips_darwin_packages(self): + self.assertNotInDepends('python3-sys-platform-darwin') + + def test_depends_on_x86_64_packages_on_x86_64(self): + if platform.machine() == 'x86_64': + self.assertIn('python3-platform-machine-x86-64', self.d.depends) + else: + self.assertNotInDepends('python3-platform-machine-x86-64') + + def test_depends_on_mips64_packages_on_mips64(self): + if platform.machine() == 'mips64': + self.assertIn('python3-platform-machine-mips64', self.d.depends) + else: + self.assertNotInDepends('python3-platform-machine-mips64') + + def test_depends_on_plat_cpython_packages(self): + self.assertIn('python3-platform-python-implementation-cpython', + self.d.depends) + + def test_skips_plat_jython_packages(self): + self.assertNotInDepends('python3-platform-python-implementation-jython') + + def test_skips_release_lt_2_packages(self): + self.assertNotInDepends('python3-platform-release-lt2') + + def test_skips_release_gt_2_packages(self): + self.assertNotInDepends('python3-platform-release-ge2') + + def test_depends_on_platform_linux_packages(self): + self.assertIn('python3-platform-system-linux', self.d.depends) + + def test_skips_platform_windows_packages(self): + self.assertNotInDepends('python3-platform-system-windows') + + def test_skips_platfrom_version_lt_1_packages(self): + self.assertNotInDepends('python3-platform-version-lt1') + + def test_skips_platform_version_ge_1_packages(self): + self.assertNotInDepends('python3-platform-version-ge1') + + def test_skips_py_version_lt_3_packages(self): + self.assertNotInDepends('python3-python-version-lt3') + + def test_elides_py_version_ge_3(self): + self.assertIn('python3-python-version-ge3', self.d.depends) + + def test_elides_py_version_gt_3(self): + self.assertIn('python3-python-version-gt3', self.d.depends) + + def test_skips_py_version_lt_30_packages(self): + self.assertNotInDepends('python3-python-version-lt30') + + def test_depends_on_py_version_lt_35_packages(self): + self.assertIn('python3-python-version-lt35 | python3 (>> 3.5)', + self.d.depends) + + def test_depends_on_py_version_le_35_packages(self): + self.assertIn('python3-python-version-le35 | python3 (>> 3.6)', + self.d.depends) + + def test_depends_on_py_version_ge_27_packages(self): + self.assertIn('python3-python-version-ge27', + self.d.depends) + + def test_depends_on_py_version_ge_35_packages(self): + self.assertIn('python3-python-version-ge35 | python3 (<< 3.5)', + self.d.depends) + + def test_depends_on_py_version_gt_35_packages(self): + self.assertIn('python3-python-version-gt35 | python3 (<< 3.6)', + self.d.depends) + + def test_depends_on_py_version_eq_35_packages(self): + self.assertIn('python3-python-version-eq35 | python3 (<< 3.5) ' + '| python3 (>> 3.6)', self.d.depends) + + def test_depends_on_py_version_ne_35_packages(self): + # Can't be represented in Debian depends + self.assertIn('python3-python-version-ne35', self.d.depends) + + def test_depends_on_py_version_aeq_35_packages(self): + self.assertIn('python3-python-version-aeq35 | python3 (<< 3.5) ' + '| python3 (>> 3.6)', self.d.depends) + + def test_depends_on_py_version_ceq_35_packages(self): + self.assertIn('python3-python-version-ceq35 | python3 (<< 3.5) ' + '| python3 (>> 3.6)', self.d.depends) + + def test_depends_on_py_version_weq_35_packages(self): + self.assertIn('python3-python-version-weq35 | python3 (<< 3.5) ' + '| python3 (>> 3.6)', self.d.depends) + + def test_skips_py_version_full_lt_300_packages(self): + self.assertNotInDepends('python3-python-version-full-lt300') + + def test_depends_on_py_version_full_lt_351_packages(self): + self.assertIn('python3-python-version-full-lt351 | python3 (>> 3.5.1)', + self.d.depends) + + def test_depends_on_py_version_full_le_351_packages(self): + self.assertIn('python3-python-version-full-le351 | python3 (>> 3.5.2)', + self.d.depends) + + def test_depends_on_py_version_full_ge_351_packages(self): + self.assertIn('python3-python-version-full-ge351 | python3 (<< 3.5.1)', + self.d.depends) + + def test_depends_on_py_version_full_ge_351a1_packages(self): + # With full PEP-440 parsing this should be (<< 3.5.1~a1) + self.assertIn( + 'python3-python-version-full-ge351a1 | python3 (<< 3.5.0)', + self.d.depends) + + def test_depends_on_py_version_full_ge_351b1post1_packages(self): + # With full PEP-440 parsing this should be (<< 3.5.1~b1.post1) + self.assertIn('python3-python-version-full-ge351a1 ' + '| python3 (<< 3.5.0)', + self.d.depends) + + def test_depends_on_py_version_full_gt_351_packages(self): + self.assertIn('python3-python-version-full-gt351 | python3 (<< 3.5.2)', + self.d.depends) + + def test_depends_on_py_version_full_eq_351_packages(self): + self.assertIn('python3-python-version-full-eq351 | python3 (<< 3.5.1) ' + '| python3 (>> 3.5.2)', self.d.depends) + + def test_depends_on_py_version_full_ne_351_packages(self): + # Can't be represented in Debian depends + self.assertIn('python3-python-version-full-ne351', self.d.depends) + + def test_skips_py_version_full_aeq_351_packages(self): + # Can't be represented in Debian depends + self.assertNotInDepends('python3-python-version-full-aeq351') + + def test_depends_on_py_version_full_ceq_351_packages(self): + self.assertIn('python3-python-version-full-ceq351 | python3 (<< 3.5.1) ' + '| python3 (>> 3.6)', self.d.depends) + + def test_depends_on_py_version_full_weq_35_packages(self): + self.assertIn('python3-python-version-full-weq35 | python3 (<< 3.5) ' + '| python3 (>> 3.6)', self.d.depends) + + def test_depends_on_sys_cpython_packages(self): + self.assertIn('python3-implementation-name-cpython', self.d.depends) + + def test_depends_on_sys_pypy_packages(self): + self.assertIn('python3-implementation-name-pypy', self.d.depends) + + def test_depends_on_sys_implementation_lt35_packages(self): + self.assertIn('python3-implementation-version-lt35 | python3 (>> 3.5)', + self.d.depends) + + def test_depends_on_sys_implementation_ge35_packages(self): + self.assertIn('python3-implementation-version-ge35 | python3 (<< 3.5)', + self.d.depends) + + def test_ignores_invalid_marker(self): + self.assertNotInDepends('python3-invalid-marker') + + def test_depends_on_extra_feature_packages(self): + self.assertIn('python3-extra-feature', self.d.depends) + + def test_skips_extra_test_packages(self): + self.assertNotInDepends('python3-extra-test') + + def test_ignores_complex_environment_markers(self): + self.assertNotInDepends('python3-complex-marker') + self.assertNotInDepends('python3-complex-marker-2') + + def test_depends_on_un_marked_dependency_after_extra(self): + self.assertIn('python3-no-markers-2', self.d.depends) + + +class TestEnvironmentMarkersEggInfo(TestEnvironmentMarkersDistInfo): + dist_info_metadata = None + requires = { + 'debian/foo/usr/lib/python3/dist-packages/foo.egg-info/requires.txt': ( + "no_markers", + "[:(os_name == 'posix')]", + "os_posix", + '[:os_name == "java"]', + "os_java", + "[:sys_platform == 'linux']", + "sys_platform_linux", + "[:sys_platform == 'darwin']", + "sys_platform_darwin", + "[:platform_machine == 'x86_64']", + "platform_machine_x86_64", + "[:platform_machine == 'mips64']", + "platform_machine_mips64", + "[:platform_python_implementation == 'CPython']", + "platform_python_implementation_cpython", + "[:platform_python_implementation == 'Jython']", + "platform_python_implementation_jython", + "[:platform_release < '2.0']", + "platform_release_lt2", + "[:platform_release >= '2.0']", + "platform_release_ge2", + "[:platform_system == 'Linux']", + "platform_system_linux", + "[:platform_system == 'Windows']", + "platform_system_windows", + "[:platform_version < '1']", + "platform_version_lt1", + "[:platform_version >= '1']", + "platform_version_ge1", + "[:python_version >= '3']", + "python_version_ge3", + "[:python_version > '3']", + "python_version_gt3", + "[:python_version < '3']", + "python_version_lt3", + "[:python_version < '3.0']", + "python_version_lt30", + "[:python_version < '3.5']", + "python_version_lt35", + "[:python_version <= '3.5']", + "python_version_le35", + "[:python_version > '3.5']", + "python_version_gt35", + "[:python_version >= '2.7']", + "python_version_ge27", + "[:python_version >= '3.5']", + "python_version_ge35", + "[:python_version == '3.5']", + "python_version_eq35", + "[:python_version != '3.5']", + "python_version_ne35", + "[:python_version === '3.5']", + "python_version_aeq35", + "[:python_version ~= '3.5']", + "python_version_ceq35", + "[:python_version == '3.5.*']", + "python_version_weq35", + "[:python_full_version < '3.0.0']", + "python_version_full_lt300", + "[:python_full_version < '3.5.1']", + "python_version_full_lt351", + "[:python_full_version <= '3.5.1']", + "python_version_full_le351", + "[:python_full_version > '3.5.1']", + "python_version_full_gt351", + "[:python_full_version >= '3.5.1']", + "python_version_full_ge351", + "[:python_full_version >= '3.5.1a1']", + "python_version_full_ge351a1", + "[:python_full_version >= '3.5.1b1.post1']", + "python_version_full_ge351b1post1", + "[:python_full_version == '3.5.1']", + "python_version_full_eq351", + "[:python_full_version != '3.5.1']", + "python_version_full_ne351", + "[:python_full_version === '3.5.1']", + "python_version_full_aeq351", + "[:python_full_version ~= '3.5.1']", + "python_version_full_ceq351", + "[:python_full_version == '3.5.*']", + "python_version_full_weq35", + "[:implementation_name == 'cpython']", + "implementation_name_cpython", + "[:implementation_name == 'pypy']", + "implementation_name_pypy", + "[:implementation_version < '3.5']", + "implementation_version_lt35", + "[:implementation_version >= '3.5']", + "implementation_version_ge35", + "[:invalid_marker > '1']", + "invalid_marker", + "[feature]", + "extra_feature", + "[test]", + "extra_test", + "[:os_name != 'windows' and implementation_name == 'cpython']", + "complex_marker", + "[test:(os_name != 'windows')]", + "complex_marker_2", + ), + } + + def test_depends_on_un_marked_dependency_after_extra(self): + raise unittest.SkipTest('Not possible in requires.txt') + + +class TestEnvironmentMarkers27EggInfo(DependenciesTestCase): + options = FakeOptions(guess_deps=True) + impl = 'cpython2' + requires = { + 'debian/foo/usr/lib/python2.7/dist-packages/foo.egg-info/requires.txt': ( + "no_markers", + "[:os_name == 'posix']", + "os_posix", + "[:python_version >= '2.6']", + "python_version_ge26", + ) + } + pydist = py27({ + 'no_markers': 'python-no-markers', + 'os_posix': 'python-os-posix', + 'python_version_ge26': 'python-python-version-ge26', + }) + + def test_depends_on_unmarked_packages(self): + self.assertIn('python-no-markers', self.d.depends) + + def test_ignores_posix_packages(self): + self.assertNotInDepends('python-os-posix') + + def test_ignores_pyversion_packages(self): + self.assertNotInDepends('python-python-version-ge26') + + +class TestIgnoresUnusedModulesDistInfo(DependenciesTestCase): + options = FakeOptions(guess_deps=True, depends_section=['feature']) + dist_info_metadata = { + 'debian/foo/usr/lib/python3/dist-packages/foo.dist-info/METADATA': ( + "Requires-Dist: unusued-complex-module ; " + "(sys_platform == \"darwin\") and extra == 'nativelib'", + "Requires-Dist: unused-win-module ; (sys_platform == \"win32\")", + "Requires-Dist: unused-extra-module ; extra == 'unused'", + ), + } + parse = False + + def test_ignores_unused_dependencies(self): + if not hasattr(self, 'assertLogs'): + raise unittest.SkipTest("Requires Python >= 3.4") + with self.assertLogs(logger='dhpython', level=logging.INFO) as logs: + self.d.parse(self.prepared_stats, self.options) + for line in logs.output: + self.assertTrue( + line.startswith( + 'INFO:dhpython:Ignoring complex environment marker'), + 'Expecting only complex environment marker messages, but ' + 'got: {}'.format(line)) + + +class TestIgnoresUnusedModulesEggInfo(DependenciesTestCase): + options = FakeOptions(guess_deps=True, depends_section=['feature']) + requires = { + 'debian/foo/usr/lib/python3/dist-packages/foo.egg-info/requires.txt': ( + "[nativelib:(sys_platform == 'darwin')]", + "unusued-complex-module", + "[:sys_platform == 'win32']", + "unused-win-module", + "[unused]", + "unused-extra-module", + ) + } + parse = False + + def test_ignores_unused_dependencies(self): + if not hasattr(self, 'assertNoLogs'): + raise unittest.SkipTest("Requires Python >= 3.10") + with self.assertNoLogs(logger='dhpython', level=logging.INFO): + self.d.parse(self.prepared_stats, self.options) diff --git a/tests/test_fs.py b/tests/test_fs.py new file mode 100644 index 0000000..c458fe8 --- /dev/null +++ b/tests/test_fs.py @@ -0,0 +1,145 @@ +from tempfile import TemporaryDirectory +from pathlib import Path +from unittest import TestCase + +from dhpython.interpreter import Interpreter +from dhpython.fs import ( + fix_merged_RECORD, merge_RECORD, merge_WHEEL, missing_lines, share_files) + +from tests.common import FakeOptions + + +class MergeWheelTestCase(TestCase): + files = {} + def setUp(self): + self.tempdir = TemporaryDirectory() + self.addCleanup(self.tempdir.cleanup) + temp_path = Path(self.tempdir.name) + for fn, contents in self.files.items(): + path = temp_path / fn + setattr(self, path.name, path) + path.parent.mkdir(parents=True, exist_ok=True) + with path.open('w') as f: + f.write('\n'.join(contents)) + f.write('\n') + + def assertFileContents(self, path, contents): + """Assert that the contents of path is contents + + Contents may be specified as a list of strings, one per line, without + line-breaks. + """ + if isinstance(contents, (list, tuple)): + contents = '\n'.join(contents) + '\n' + with path.open('r') as f: + self.assertMultiLineEqual(contents, f.read()) + + +class SimpleCombinationTest(MergeWheelTestCase): + files = { + 'a': ('abc', 'def'), + 'b': ('abc', 'ghi'), + } + def test_missing_lines(self): + r = missing_lines(self.a, self.b) + self.assertEqual(r, ['def\n']) + + def test_merge_record(self): + merge_RECORD(self.a, self.b) + self.assertFileContents(self.b, ('abc', 'ghi', 'def')) + + +class MergeTagsTest(MergeWheelTestCase): + files = { + 'a': ('foo', 'Tag: A'), + 'b': ('foo', 'Tag: B'), + } + + def test_merge_wheel(self): + merge_WHEEL(self.a, self.b) + self.assertFileContents(self.b, ('foo', 'Tag: B', 'Tag: A')) + + +class UpdateRecordTest(MergeWheelTestCase): + files = { + 'dist-info/RECORD': ('dist-info/FOO,sha256=b5bb9d8014a0f9b1d61e21e796d7' + '8dccdf1352f23cd32812f4850b878ae4944c,4',), + 'dist-info/WHEEL': ('foo'), + } + + def test_fix_merged_record(self): + fix_merged_RECORD(self.RECORD.parent) + self.assertFileContents(self.RECORD, ( + 'dist-info/FOO,sha256=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32' + '812f4850b878ae4944c,4', + 'dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53eac85d' + '1844f5940f51c1fcba725,6', + )) + + +class ShareFilesTestCase(MergeWheelTestCase): + impl = 'cpython3' + options = {} + + def setUp(self): + super().setUp() + self.destdir = TemporaryDirectory() + self.addCleanup(self.destdir.cleanup) + share_files(self.tempdir.name, self.destdir.name, + Interpreter(self.impl), + FakeOptions(**self.options)) + + def destPath(self, name): + return Path(self.destdir.name) / name + + +class HatchlingLicenseTest(ShareFilesTestCase): + files = { + 'foo.dist-info/license_files/LICENSE.txt': ('foo'), + 'foo.dist-info/licenses/COPYING': ('foo'), + 'foo.dist-info/RECORD': ( + 'foo.dist-info/license_files/LICENSE.txt,sha256=2c26b46b68ffc68ff99' + 'b453c1d30413413422d706483bfa0f98a5e886266e7ae,4', + 'foo.dist-info/licenses/COPYING,sha256=2c26b46b68ffc68ff99b453c1d30' + '413413422d706483bfa0f98a5e886266e7ae,4', + 'foo.dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53ea' + 'c85d1844f5940f51c1fcba725,6'), + 'foo.dist-info/WHEEL': ('foo'), + } + + def test_removes_license_files(self): + self.assertFalse( + self.destPath('foo.dist-info/license_files/LICENSE.txt').exists()) + self.assertFalse( + self.destPath('foo.dist-info/licenses/COPYING').exists()) + + def test_removes_license_files_from_record(self): + print("Checking", self.destPath('foo.dist-info/RECORD')) + self.assertFileContents(self.destPath('foo.dist-info/RECORD'), + 'foo.dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53ea' + 'c85d1844f5940f51c1fcba725,6\n') + + +class FlitLicenseTest(ShareFilesTestCase): + files = { + 'foo.dist-info/COPYING': ('foo'), + 'foo.dist-info/COPYING.LESSER': ('foo'), + 'foo.dist-info/RECORD': ( + 'foo.dist-info/COPYING,sha256=2c26b46b68ffc68ff99b453c1d30413413422' + 'd706483bfa0f98a5e886266e7ae,4', + 'foo.dist-info/COPYING.LESSER,sha256=2c26b46b68ffc68ff99b453c1d3041' + '3413422d706483bfa0f98a5e886266e7ae,4', + 'foo.dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53ea' + 'c85d1844f5940f51c1fcba725,6'), + 'foo.dist-info/WHEEL': ('foo'), + } + + def test_removes_license_files(self): + self.assertFalse(self.destPath('foo.dist-info/COPYING.LESSER').exists()) + self.assertFalse(self.destPath('foo.dist-info/COPYING').exists()) + + def test_removes_license_files_from_record(self): + print("Checking", self.destPath('foo.dist-info/RECORD')) + self.assertFileContents(self.destPath('foo.dist-info/RECORD'), + 'foo.dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53ea' + 'c85d1844f5940f51c1fcba725,6\n') diff --git a/tests/test_interpreter.py b/tests/test_interpreter.py new file mode 100644 index 0000000..ff9bdd2 --- /dev/null +++ b/tests/test_interpreter.py @@ -0,0 +1,250 @@ +import unittest +from os import environ +from os.path import exists +from dhpython.interpreter import Interpreter + + +class TestInterpreter(unittest.TestCase): + def setUp(self): + self._triplet = environ.get('DEB_HOST_MULTIARCH') + environ['DEB_HOST_MULTIARCH'] = 'MYARCH' + + def tearDown(self): + if self._triplet: + environ['DEB_HOST_MULTIARCH'] = self._triplet + + @unittest.skipUnless(exists('/usr/bin/pypy'), 'pypy is not installed') + def test_pypy(self): + sorted(Interpreter.parse('pypy').items()) == \ + [('debug', None), ('name', 'pypy'), ('options', ()), ('path', ''), ('version', None)] + sorted(Interpreter.parse('#! /usr/bin/pypy --foo').items()) == \ + [('debug', None), ('name', 'pypy'), ('options', ('--foo',)), ('path', '/usr/bin/'), ('version', None)] + Interpreter('pypy').sitedir(version='2.0') == '/usr/lib/pypy/dist-packages/' + + @unittest.skipUnless(exists('/usr/bin/python2.6'), 'python2.6 is not installed') + def test_python26(self): + i = Interpreter('python2.6') + self.assertEqual(i.soabi(), '') + self.assertIsNone(i.check_extname('foo.so')) + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertIsNone(i.check_extname('foo/bar/bazmodule.so')) + + @unittest.skipUnless(exists('/usr/bin/python2.6-dbg'), 'python2.6-dbg is not installed') + def test_python26dbg(self): + i = Interpreter('python2.6-dbg') + self.assertEqual(i.soabi(), '') + self.assertIsNone(i.check_extname('foo_d.so')) + self.assertEqual(i.check_extname('foo.so'), 'foo_d.so') + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), 'foo/bar/bazmodule_d.so') + + @unittest.skipUnless(exists('/usr/bin/python2.7'), 'python2.7 is not installed') + def test_python27(self): + i = Interpreter('python2.7') + self.assertEqual(i.soabi(), '') + self.assertEqual(i.check_extname('foo.so'), 'foo.MYARCH.so') + self.assertIsNone(i.check_extname('foo.MYARCH_d.so')) + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertIsNone(i.check_extname('foo.OTHER.so')) # different architecture + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), 'foo/bar/baz.MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python2.7-dbg'), 'python2.7-dbg is not installed') + def test_python27dbg(self): + i = Interpreter('python2.7-dbg') + self.assertEqual(i.soabi(), '') + self.assertEqual(i.check_extname('foo.so'), 'foo.MYARCH_d.so') + self.assertEqual(i.check_extname('foo_d.so'), 'foo.MYARCH_d.so') + self.assertIsNone(i.check_extname('foo.MYARCH_d.so')) + self.assertIsNone(i.check_extname('foo.OTHER_d.so')) # different architecture + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), 'foo/bar/baz.MYARCH_d.so') + + @unittest.skipUnless(exists('/usr/bin/python3.1'), 'python3.1 is not installed') + def test_python31(self): + i = Interpreter('python3.1') + self.assertEqual(i.soabi(), '') + self.assertIsNone(i.check_extname('foo.so')) + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertIsNone(i.check_extname('foo/bar/bazmodule.so')) + + @unittest.skipUnless(exists('/usr/bin/python3.1-dbg'), 'python3.1-dbg is not installed') + def test_python31dbg(self): + i = Interpreter('python3.1-dbg') + self.assertEqual(i.soabi(), '') + self.assertIsNone(i.check_extname('foo.so')) + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertIsNone(i.check_extname('foo/bar/bazmodule.so')) + + @unittest.skipUnless(exists('/usr/bin/python3.2'), 'python3.2 is not installed') + def test_python32(self): + i = Interpreter('python3.2') + self.assertEqual(i.soabi(), 'cpython-32mu') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-32mu.so') + self.assertIsNone(i.check_extname('foo.cpython-33m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-32mu-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/bazmodule.cpython-32mu.so') + + @unittest.skipUnless(exists('/usr/bin/python3.2-dbg'), 'python3.2-dbg is not installed') + def test_python32dbg(self): + i = Interpreter('python3.2-dbg') + self.assertEqual(i.soabi(), 'cpython-32dmu') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-32dmu.so') + self.assertIsNone(i.check_extname('foo.cpython-33m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-32dmu-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/bazmodule.cpython-32dmu.so') + + @unittest.skipUnless(exists('/usr/bin/python3.4'), 'python3.4 is not installed') + def test_python34(self): + i = Interpreter('python3.4') + self.assertEqual(i.soabi(), 'cpython-34m') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-34m-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-34m-OTHER.so')) # different architecture + self.assertEqual(i.check_extname('foo.cpython-34m.so'), r'foo.cpython-34m-MYARCH.so') + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-34m-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.4-dbg'), 'python3.4-dbg is not installed') + def test_python34dbg(self): + i = Interpreter('python3.4-dbg') + self.assertEqual(i.soabi(), 'cpython-34dm') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-34dm-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-34m-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-34dm-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.5'), 'python3.5 is not installed') + def test_python35(self): + i = Interpreter('python3.5') + self.assertEqual(i.soabi(), 'cpython-35m') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-35m-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-35m-OTHER.so')) # different architecture + self.assertEqual(i.check_extname('foo.cpython-35m.so'), r'foo.cpython-35m-MYARCH.so') + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-35m-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.5-dbg'), 'python3.5-dbg is not installed') + def test_python35dbg(self): + i = Interpreter('python3.5-dbg') + self.assertEqual(i.soabi(), 'cpython-35dm') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-35dm-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-35m-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-35dm-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.6'), 'python3.6 is not installed') + def test_python36(self): + i = Interpreter('python3.6') + self.assertEqual(i.soabi(), 'cpython-36m') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-36m-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-36m-OTHER.so')) # different architecture + self.assertEqual(i.check_extname('foo.cpython-36m.so'), r'foo.cpython-36m-MYARCH.so') + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-36m-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.6-dbg'), 'python3.6-dbg is not installed') + def test_python36dbg(self): + i = Interpreter('python3.6-dbg') + self.assertEqual(i.soabi(), 'cpython-36dm') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-36dm-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-36m-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-36dm-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.7'), 'python3.7 is not installed') + def test_python37(self): + i = Interpreter('python3.7') + self.assertEqual(i.soabi(), 'cpython-37m') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-37m-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-37m-OTHER.so')) # different architecture + self.assertEqual(i.check_extname('foo.cpython-37m.so'), r'foo.cpython-37m-MYARCH.so') + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-37m-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.7-dbg'), 'python3.7-dbg is not installed') + def test_python37dbg(self): + i = Interpreter('python3.7-dbg') + self.assertEqual(i.soabi(), 'cpython-37dm') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-37dm-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-37m-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-37dm-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.8'), 'python3.8 is not installed') + def test_python38(self): + i = Interpreter('python3.8') + self.assertEqual(i.soabi(), 'cpython-38') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-38-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-38-OTHER.so')) # different architecture + self.assertEqual(i.check_extname('foo.cpython-38.so'), r'foo.cpython-38-MYARCH.so') + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-38-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.8-dbg'), 'python3.8-dbg is not installed') + def test_python38dbg(self): + i = Interpreter('python3.8-dbg') + self.assertEqual(i.soabi(), 'cpython-38d') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-38d-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-38-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-38d-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.9'), 'python3.9 is not installed') + def test_python39(self): + i = Interpreter('python3.9') + self.assertEqual(i.soabi(), 'cpython-39') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-39-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-39-OTHER.so')) # different architecture + self.assertEqual(i.check_extname('foo.cpython-39.so'), r'foo.cpython-39-MYARCH.so') + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-39-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.9-dbg'), 'python3.9-dbg is not installed') + def test_python39dbg(self): + i = Interpreter('python3.9-dbg') + self.assertEqual(i.soabi(), 'cpython-39d') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-39d-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-39-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-39d-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.10'), 'python3.10 is not installed') + def test_python310(self): + i = Interpreter('python3.10') + self.assertEqual(i.soabi(), 'cpython-310') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-310-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-310-OTHER.so')) # different architecture + self.assertEqual(i.check_extname('foo.cpython-310.so'), r'foo.cpython-310-MYARCH.so') + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-310-MYARCH.so') + + @unittest.skipUnless(exists('/usr/bin/python3.10-dbg'), 'python3.10-dbg is not installed') + def test_python310dbg(self): + i = Interpreter('python3.10-dbg') + self.assertEqual(i.soabi(), 'cpython-310d') + self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-310d-MYARCH.so') + self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version + self.assertIsNone(i.check_extname('foo.cpython-310-OTHER.so')) # different architecture + self.assertIsNone(i.check_extname('foo.abi3.so')) + self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-310d-MYARCH.so') + + + def test_version(self): + i = Interpreter(impl='cpython2') + self.assertEqual(str(i), 'python') + self.assertEqual(i.binary('2.7'), '/usr/bin/python2.7') + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_tools.py b/tests/test_tools.py new file mode 100644 index 0000000..55097e8 --- /dev/null +++ b/tests/test_tools.py @@ -0,0 +1,44 @@ +from tempfile import TemporaryDirectory +import os +import unittest + +from dhpython.tools import relpath, move_matching_files + + +class TestRelpath(unittest.TestCase): + def test_common_parent_dir(self): + r = relpath('/usr/share/python-foo/foo.py', '/usr/bin/foo') + self.assertEqual(r, '../share/python-foo/foo.py') + + def test_strips_common_prefix(self): + r = relpath('/usr/share/python-foo/foo.py', '/usr/share') + self.assertEqual(r, 'python-foo/foo.py') + + def test_trailing_slash_ignored(self): + r = relpath('/usr/share/python-foo/foo.py', '/usr/share/') + self.assertEqual(r, 'python-foo/foo.py') + + +class TestMoveMatchingFiles(unittest.TestCase): + def setUp(self): + self.tmpdir = TemporaryDirectory() + self.addCleanup(self.tmpdir.cleanup) + os.makedirs(self.tmppath('foo/bar/a/b/c/spam')) + for path in ('foo/bar/a/b/c/spam/file.so', + 'foo/bar/a/b/c/spam/file.py'): + open(self.tmppath(path), 'w').close() + + move_matching_files(self.tmppath('foo/bar/'), + self.tmppath('foo/baz/'), + 'spam/.*\.so$') + + def tmppath(self, *path): + return os.path.join(self.tmpdir.name, *path) + + def test_moved_matching_file(self): + self.assertTrue(os.path.exists( + self.tmppath('foo/baz/a/b/c/spam/file.so'))) + + def test_left_non_matching_file(self): + self.assertTrue(os.path.exists( + self.tmppath('foo/bar/a/b/c/spam/file.py'))) diff --git a/tests/tpb01/Makefile b/tests/tpb01/Makefile new file mode 100644 index 0000000..b33b698 --- /dev/null +++ b/tests/tpb01/Makefile @@ -0,0 +1,9 @@ +#!/usr/bin/make -f +include ../common.mk + +check: + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo.py + grep -q 'Depends:.*python3-tomli' debian/python3-foo/DEBIAN/control + +clean: + ./debian/rules clean diff --git a/tests/tpb01/debian/changelog b/tests/tpb01/debian/changelog new file mode 100644 index 0000000..322011c --- /dev/null +++ b/tests/tpb01/debian/changelog @@ -0,0 +1,5 @@ +foo (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/tpb01/debian/control b/tests/tpb01/debian/control new file mode 100644 index 0000000..8b2e05f --- /dev/null +++ b/tests/tpb01/debian/control @@ -0,0 +1,16 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , python3-all + , python3-setuptools + , python3-tomli +# , dh-python +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: all +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #1 diff --git a/tests/tpb01/debian/copyright b/tests/tpb01/debian/copyright new file mode 100644 index 0000000..f96adde --- /dev/null +++ b/tests/tpb01/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/tpb01/debian/rules b/tests/tpb01/debian/rules new file mode 100755 index 0000000..e8953b0 --- /dev/null +++ b/tests/tpb01/debian/rules @@ -0,0 +1,26 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild --build + +override_dh_auto_install: + ../../pybuild --install + +override_dh_auto_test: + ../../pybuild --test + +override_dh_auto_clean: + ../../pybuild --clean + rm -rf .pybuild foo.egg-info + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 diff --git a/tests/tpb01/debian/source/format b/tests/tpb01/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/tpb01/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/tpb01/foo.py b/tests/tpb01/foo.py new file mode 100644 index 0000000..810c96e --- /dev/null +++ b/tests/tpb01/foo.py @@ -0,0 +1 @@ +"foo" diff --git a/tests/tpb01/setup.cfg b/tests/tpb01/setup.cfg new file mode 100644 index 0000000..112fd6c --- /dev/null +++ b/tests/tpb01/setup.cfg @@ -0,0 +1,9 @@ +[metadata] +name = foo + +[options] +py_modules = foo +install_requires = + tomli + mock; python_version < '3.1' + docutils; python_version >= '3.0' diff --git a/tests/tpb01/setup.py b/tests/tpb01/setup.py new file mode 100644 index 0000000..6068493 --- /dev/null +++ b/tests/tpb01/setup.py @@ -0,0 +1,3 @@ +from setuptools import setup + +setup() diff --git a/tests/tpb02/Makefile b/tests/tpb02/Makefile new file mode 100644 index 0000000..3a86c66 --- /dev/null +++ b/tests/tpb02/Makefile @@ -0,0 +1,19 @@ +#!/usr/bin/make -f +include ../common.mk + +DI=debian/python3-foo/usr/lib/python3/dist-packages/foo-0.1.dist-info + +check: + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py + test -f debian/python3-foo/usr/bin/foo + grep -q ^foo/__init__.py, $(DI)/RECORD + test ! -f $(DI)/direct_url.json + grep -L ^foo-0.1.dist-info/direct_url.json, $(DI)/RECORD | grep -q RECORD + grep -q 'Depends:.*python3-tomli' debian/python3-foo/DEBIAN/control + grep -q 'Depends:.*python3-importlib-metadata \| python3 (>> 3\.5)' debian/python3-foo/DEBIAN/control + grep -L 'Depends:.*tox' debian/python3-foo/DEBIAN/control | grep -q control + find .pybuild -name test-executed | grep -q test-executed + test -f debian/python3-foo/usr/share/man/man1/foo.1.gz + +clean: + ./debian/rules clean diff --git a/tests/tpb02/data/share/man/man1/foo.1 b/tests/tpb02/data/share/man/man1/foo.1 new file mode 100644 index 0000000..3bf5dce --- /dev/null +++ b/tests/tpb02/data/share/man/man1/foo.1 @@ -0,0 +1,8 @@ +.TH foo 1 "December 5 2022" +.SH NAME +foo \- An example +.SH SYNOPSIS +.B foo +.SH DESCRIPTION +.B foo +says hi. diff --git a/tests/tpb02/debian/changelog b/tests/tpb02/debian/changelog new file mode 100644 index 0000000..322011c --- /dev/null +++ b/tests/tpb02/debian/changelog @@ -0,0 +1,5 @@ +foo (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/tpb02/debian/control b/tests/tpb02/debian/control new file mode 100644 index 0000000..c775ede --- /dev/null +++ b/tests/tpb02/debian/control @@ -0,0 +1,16 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , flit + , python3-all + , pybuild-plugin-pyproject +# , dh-python +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: all +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #1 diff --git a/tests/tpb02/debian/copyright b/tests/tpb02/debian/copyright new file mode 100644 index 0000000..f96adde --- /dev/null +++ b/tests/tpb02/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/tpb02/debian/pybuild.testfiles b/tests/tpb02/debian/pybuild.testfiles new file mode 100644 index 0000000..58c4d14 --- /dev/null +++ b/tests/tpb02/debian/pybuild.testfiles @@ -0,0 +1,3 @@ +testfile1.txt +nested/testfile2.txt +testdir diff --git a/tests/tpb02/debian/rules b/tests/tpb02/debian/rules new file mode 100755 index 0000000..e8953b0 --- /dev/null +++ b/tests/tpb02/debian/rules @@ -0,0 +1,26 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild --build + +override_dh_auto_install: + ../../pybuild --install + +override_dh_auto_test: + ../../pybuild --test + +override_dh_auto_clean: + ../../pybuild --clean + rm -rf .pybuild foo.egg-info + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 diff --git a/tests/tpb02/debian/source/format b/tests/tpb02/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/tpb02/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/tpb02/foo/__init__.py b/tests/tpb02/foo/__init__.py new file mode 100644 index 0000000..f29ed43 --- /dev/null +++ b/tests/tpb02/foo/__init__.py @@ -0,0 +1,6 @@ +"""An amazing sample package!""" + +__version__ = '0.1' + +def main(): + print("Hello There") diff --git a/tests/tpb02/foo/test_foo.py b/tests/tpb02/foo/test_foo.py new file mode 100644 index 0000000..174b86b --- /dev/null +++ b/tests/tpb02/foo/test_foo.py @@ -0,0 +1,11 @@ +from unittest import TestCase + + +class RequiredTest(TestCase): + def test_tests_are_executed(self): + open('test-executed', 'w').close() + + def test_testfiles_exist(self): + open('testfile1.txt').close() + open('testfile2.txt').close() + open('testdir/testfile3.txt').close() diff --git a/tests/tpb02/nested/testfile2.txt b/tests/tpb02/nested/testfile2.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tpb02/nested/testfile2.txt diff --git a/tests/tpb02/pyproject.toml b/tests/tpb02/pyproject.toml new file mode 100644 index 0000000..a20e0e7 --- /dev/null +++ b/tests/tpb02/pyproject.toml @@ -0,0 +1,22 @@ +[build-system] +requires = ["flit_core >=2,<4"] +build-backend = "flit_core.buildapi" + +[tool.flit.metadata] +module = "foo" +author = "Stefano Rivera" +requires = [ + "tomli", + "importlib-metadata ; python_version < '3.5'" +] + +[tool.flit.metadata.requires-extra] +test = [ + "tox", +] + +[tool.flit.scripts] +foo = "foo:main" + +[tool.flit.external-data] +directory = "data" diff --git a/tests/tpb02/testdir/testfile3.txt b/tests/tpb02/testdir/testfile3.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tpb02/testdir/testfile3.txt diff --git a/tests/tpb02/testfile1.txt b/tests/tpb02/testfile1.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tpb02/testfile1.txt diff --git a/tests/tpb03/Makefile b/tests/tpb03/Makefile new file mode 100644 index 0000000..5337be8 --- /dev/null +++ b/tests/tpb03/Makefile @@ -0,0 +1,10 @@ +#!/usr/bin/make -f +include ../common.mk + +check: + # FIXME: This used to be a 2.7 + 3.x test. It may not be useful any more, without 2.x + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo.py + grep -q 'Depends:.*python3-pkg-resources' debian/python3-foo/DEBIAN/control + +clean: + ./debian/rules clean diff --git a/tests/tpb03/debian/changelog b/tests/tpb03/debian/changelog new file mode 100644 index 0000000..322011c --- /dev/null +++ b/tests/tpb03/debian/changelog @@ -0,0 +1,5 @@ +foo (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/tpb03/debian/control b/tests/tpb03/debian/control new file mode 100644 index 0000000..e49d924 --- /dev/null +++ b/tests/tpb03/debian/control @@ -0,0 +1,15 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , python3-all + , python3-setuptools +# , dh-python +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: all +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #1 diff --git a/tests/tpb03/debian/copyright b/tests/tpb03/debian/copyright new file mode 100644 index 0000000..f96adde --- /dev/null +++ b/tests/tpb03/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/tpb03/debian/rules b/tests/tpb03/debian/rules new file mode 100755 index 0000000..e8953b0 --- /dev/null +++ b/tests/tpb03/debian/rules @@ -0,0 +1,26 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild --build + +override_dh_auto_install: + ../../pybuild --install + +override_dh_auto_test: + ../../pybuild --test + +override_dh_auto_clean: + ../../pybuild --clean + rm -rf .pybuild foo.egg-info + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 diff --git a/tests/tpb03/debian/source/format b/tests/tpb03/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/tpb03/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/tpb03/foo.py b/tests/tpb03/foo.py new file mode 100644 index 0000000..810c96e --- /dev/null +++ b/tests/tpb03/foo.py @@ -0,0 +1 @@ +"foo" diff --git a/tests/tpb03/setup.cfg b/tests/tpb03/setup.cfg new file mode 100644 index 0000000..e60fea3 --- /dev/null +++ b/tests/tpb03/setup.cfg @@ -0,0 +1,7 @@ +[metadata] +name = foo + +[options] +py_modules = foo +install_requires = + setuptools diff --git a/tests/tpb03/setup.py b/tests/tpb03/setup.py new file mode 100644 index 0000000..6068493 --- /dev/null +++ b/tests/tpb03/setup.py @@ -0,0 +1,3 @@ +from setuptools import setup + +setup() diff --git a/tests/tpb04/Makefile b/tests/tpb04/Makefile new file mode 100644 index 0000000..d1b6324 --- /dev/null +++ b/tests/tpb04/Makefile @@ -0,0 +1,10 @@ +#!/usr/bin/make -f +include ../common.mk + +check: + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo.py + test -f debian/python3-foo-ext/usr/lib/python3/dist-packages/_foo.abi3.so + test -e test-executed + +clean: + ./debian/rules clean diff --git a/tests/tpb04/_foo.c b/tests/tpb04/_foo.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tpb04/_foo.c diff --git a/tests/tpb04/debian/changelog b/tests/tpb04/debian/changelog new file mode 100644 index 0000000..322011c --- /dev/null +++ b/tests/tpb04/debian/changelog @@ -0,0 +1,5 @@ +foo (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/tpb04/debian/control b/tests/tpb04/debian/control new file mode 100644 index 0000000..f0643cf --- /dev/null +++ b/tests/tpb04/debian/control @@ -0,0 +1,23 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , python3-all-dev + , python3-setuptools + , python3-tomli + , tox +# , dh-python +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: all +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #1 + +Package: python3-foo-ext +Architecture: any +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython extensions + example package #2 diff --git a/tests/tpb04/debian/copyright b/tests/tpb04/debian/copyright new file mode 100644 index 0000000..f96adde --- /dev/null +++ b/tests/tpb04/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/tpb04/debian/rules b/tests/tpb04/debian/rules new file mode 100755 index 0000000..1a4e00b --- /dev/null +++ b/tests/tpb04/debian/rules @@ -0,0 +1,27 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo +export PYBUILD_EXT_DESTDIR_python3=debian/python3-foo-ext + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild --build + +override_dh_auto_install: + ../../pybuild --install + +override_dh_auto_test: + ../../pybuild --test --test-tox --test-args=-v + +override_dh_auto_clean: + ../../pybuild --clean + rm -rf .pybuild .tox foo.egg-info test-executed + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 diff --git a/tests/tpb04/debian/source/format b/tests/tpb04/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/tpb04/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/tpb04/foo.py b/tests/tpb04/foo.py new file mode 100644 index 0000000..810c96e --- /dev/null +++ b/tests/tpb04/foo.py @@ -0,0 +1 @@ +"foo" diff --git a/tests/tpb04/setup.cfg b/tests/tpb04/setup.cfg new file mode 100644 index 0000000..3ff1e35 --- /dev/null +++ b/tests/tpb04/setup.cfg @@ -0,0 +1,5 @@ +[metadata] +name = foo + +[options] +py_modules = foo diff --git a/tests/tpb04/setup.py b/tests/tpb04/setup.py new file mode 100644 index 0000000..e922974 --- /dev/null +++ b/tests/tpb04/setup.py @@ -0,0 +1,9 @@ +from setuptools import setup, Extension + +setup(ext_modules=[ + Extension( + '_foo', + ['_foo.c'], + py_limited_api = True, + ) +]) diff --git a/tests/tpb04/test_foo.py b/tests/tpb04/test_foo.py new file mode 100644 index 0000000..bbe6954 --- /dev/null +++ b/tests/tpb04/test_foo.py @@ -0,0 +1,6 @@ +from unittest import TestCase + + +class RequiredTest(TestCase): + def test_tests_are_executed(self): + open('test-executed', 'w').close() diff --git a/tests/tpb04/tox.ini b/tests/tpb04/tox.ini new file mode 100644 index 0000000..08858b5 --- /dev/null +++ b/tests/tpb04/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist = py39 + +[testenv] +deps = tomli +commands = python -m unittest discover diff --git a/tests/tpb05/LICENSE b/tests/tpb05/LICENSE new file mode 100644 index 0000000..5996299 --- /dev/null +++ b/tests/tpb05/LICENSE @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/tests/tpb05/Makefile b/tests/tpb05/Makefile new file mode 100644 index 0000000..b9bc2a5 --- /dev/null +++ b/tests/tpb05/Makefile @@ -0,0 +1,19 @@ +#!/usr/bin/make -f +include ../common.mk + +DI=debian/python3-foo/usr/lib/python3/dist-packages/foo-0.1.dist-info + +check: + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py + grep -q ^foo/__init__.py, $(DI)/RECORD + test ! -f $(DI)/direct_url.json + grep -L ^foo-0.1.dist-info/direct_url.json, $(DI)/RECORD | grep -q RECORD + grep -q 'Depends:.*python3-tomli' debian/python3-foo/DEBIAN/control + grep -q 'Depends:.*python3-importlib-metadata \| python3 (>> 3\.5)' debian/python3-foo/DEBIAN/control + grep -L 'Depends:.*tox' debian/python3-foo/DEBIAN/control | grep -q control + find .pybuild -name test-executed | grep -q test-executed + grep -q usr/bin/python3$$ debian/python3-foo/usr/bin/foo + find debian/python3-foo/usr/lib/python3/dist-packages/ -name LICENSE | { ! grep -q LICENSE; } + +clean: + ./debian/rules clean diff --git a/tests/tpb05/debian/changelog b/tests/tpb05/debian/changelog new file mode 100644 index 0000000..322011c --- /dev/null +++ b/tests/tpb05/debian/changelog @@ -0,0 +1,5 @@ +foo (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/tpb05/debian/control b/tests/tpb05/debian/control new file mode 100644 index 0000000..76f5dbd --- /dev/null +++ b/tests/tpb05/debian/control @@ -0,0 +1,16 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , python3-all + , python3-poetry-core + , python3-pytest + , pybuild-plugin-pyproject +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: all +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #1 diff --git a/tests/tpb05/debian/copyright b/tests/tpb05/debian/copyright new file mode 100644 index 0000000..f96adde --- /dev/null +++ b/tests/tpb05/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/tpb05/debian/rules b/tests/tpb05/debian/rules new file mode 100755 index 0000000..4923534 --- /dev/null +++ b/tests/tpb05/debian/rules @@ -0,0 +1,28 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild --build --verbose + ../../pybuild --build --verbose + +override_dh_auto_install: + ../../pybuild --install + ../../pybuild --install + +override_dh_auto_test: + ../../pybuild --test --test-pytest + +override_dh_auto_clean: + ../../pybuild --clean --verbose + rm -rf .pybuild foo.egg-info + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 diff --git a/tests/tpb05/debian/source/format b/tests/tpb05/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/tpb05/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/tpb05/foo/__init__.py b/tests/tpb05/foo/__init__.py new file mode 100644 index 0000000..b3b7945 --- /dev/null +++ b/tests/tpb05/foo/__init__.py @@ -0,0 +1,4 @@ +"""An amazing sample package!""" + +def main(): + print("Hello") diff --git a/tests/tpb05/foo/test_foo.py b/tests/tpb05/foo/test_foo.py new file mode 100644 index 0000000..bbe6954 --- /dev/null +++ b/tests/tpb05/foo/test_foo.py @@ -0,0 +1,6 @@ +from unittest import TestCase + + +class RequiredTest(TestCase): + def test_tests_are_executed(self): + open('test-executed', 'w').close() diff --git a/tests/tpb05/pyproject.toml b/tests/tpb05/pyproject.toml new file mode 100644 index 0000000..cb6ebaa --- /dev/null +++ b/tests/tpb05/pyproject.toml @@ -0,0 +1,17 @@ +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "foo" +description = "an example module" +version = "0.1" +authors = ["Stefano Rivera <stefanor@debian.org>"] +license = "Expat" + +[tool.poetry.dependencies] +tomli = "^1.0.0" +importlib-metadata = { version="*", python = "<3.5" } + +[tool.poetry.scripts] +foo = 'foo:main' diff --git a/tests/tpb05/setup.py b/tests/tpb05/setup.py new file mode 100644 index 0000000..6593127 --- /dev/null +++ b/tests/tpb05/setup.py @@ -0,0 +1,5 @@ +#!/usr/bin/python3 +import sys + +sys.stderr.write('setup.py was called. Use pep517 instead.\n') +sys.exit(1) diff --git a/tests/tpb06/LICENSE b/tests/tpb06/LICENSE new file mode 100644 index 0000000..5996299 --- /dev/null +++ b/tests/tpb06/LICENSE @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/tests/tpb06/Makefile b/tests/tpb06/Makefile new file mode 100644 index 0000000..285fe83 --- /dev/null +++ b/tests/tpb06/Makefile @@ -0,0 +1,20 @@ +#!/usr/bin/make -f +include ../common.mk + +DI=debian/python3-foo/usr/lib/python3/dist-packages/foo-0.1.dist-info + +check: + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py + grep -q ^foo/__init__.py, $(DI)/RECORD + test ! -f $(DI)/direct_url.json + grep -L ^foo-0.1.dist-info/direct_url.json, $(DI)/RECORD | grep -q RECORD + grep -q 'Depends:.*python3-tomli' debian/python3-foo/DEBIAN/control + grep -q 'Depends:.*python3-importlib-metadata \| python3 (>> 3\.5)' debian/python3-foo/DEBIAN/control + grep -L 'Depends:.*tox' debian/python3-foo/DEBIAN/control | grep -q control + find .pybuild -name test-executed | grep -q test-executed + grep -q usr/bin/python3$$ debian/python3-foo/usr/bin/foo + find debian/python3-foo/usr/lib/python3/dist-packages/ -name LICENSE | { ! grep -q LICENSE; } + test -f debian/python3-foo/usr/share/man/man1/foo.1.gz + +clean: + ./debian/rules clean diff --git a/tests/tpb06/debian/changelog b/tests/tpb06/debian/changelog new file mode 100644 index 0000000..322011c --- /dev/null +++ b/tests/tpb06/debian/changelog @@ -0,0 +1,5 @@ +foo (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/tpb06/debian/control b/tests/tpb06/debian/control new file mode 100644 index 0000000..dec1e1f --- /dev/null +++ b/tests/tpb06/debian/control @@ -0,0 +1,15 @@ +Source: foo +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , python3-all + , python3-setuptools + , pybuild-plugin-pyproject +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: any +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #1 diff --git a/tests/tpb06/debian/copyright b/tests/tpb06/debian/copyright new file mode 100644 index 0000000..f96adde --- /dev/null +++ b/tests/tpb06/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/tpb06/debian/rules b/tests/tpb06/debian/rules new file mode 100755 index 0000000..db68934 --- /dev/null +++ b/tests/tpb06/debian/rules @@ -0,0 +1,26 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild --build --verbose + +override_dh_auto_install: + ../../pybuild --install + +override_dh_auto_test: + ../../pybuild --test + +override_dh_auto_clean: + ../../pybuild --clean --verbose + rm -rf .pybuild foo.egg-info + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 diff --git a/tests/tpb06/debian/source/format b/tests/tpb06/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/tpb06/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/tpb06/foo/__init__.py b/tests/tpb06/foo/__init__.py new file mode 100644 index 0000000..b3b7945 --- /dev/null +++ b/tests/tpb06/foo/__init__.py @@ -0,0 +1,4 @@ +"""An amazing sample package!""" + +def main(): + print("Hello") diff --git a/tests/tpb06/foo/ext.c b/tests/tpb06/foo/ext.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tpb06/foo/ext.c diff --git a/tests/tpb06/foo/test_foo.py b/tests/tpb06/foo/test_foo.py new file mode 100644 index 0000000..926af30 --- /dev/null +++ b/tests/tpb06/foo/test_foo.py @@ -0,0 +1,13 @@ +import os +from unittest import TestCase +import subprocess + + +class RequiredTest(TestCase): + def test_tests_are_executed(self): + open('test-executed', 'w').close() + + def test_entry_point_executed(self): + path, _, __ = os.environ['PATH'].partition(":") + assert path.endswith("/scripts") + subprocess.run('foo', check=True) diff --git a/tests/tpb06/man/foo.1 b/tests/tpb06/man/foo.1 new file mode 100644 index 0000000..3bf5dce --- /dev/null +++ b/tests/tpb06/man/foo.1 @@ -0,0 +1,8 @@ +.TH foo 1 "December 5 2022" +.SH NAME +foo \- An example +.SH SYNOPSIS +.B foo +.SH DESCRIPTION +.B foo +says hi. diff --git a/tests/tpb06/pyproject.toml b/tests/tpb06/pyproject.toml new file mode 100644 index 0000000..9787c3b --- /dev/null +++ b/tests/tpb06/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/tests/tpb06/setup.cfg b/tests/tpb06/setup.cfg new file mode 100644 index 0000000..fbd051b --- /dev/null +++ b/tests/tpb06/setup.cfg @@ -0,0 +1,21 @@ +[metadata] +name = foo +version = 0.1 +description = My package description +long_description = My long description +license = Expat + +[options] +zip_safe = False +packages = find: +install_requires = + tomli + importlib-metadata; python_version<'3.5' + +[options.entry_points] +console_scripts = + foo = foo:main + +[options.data_files] +share/man/man1 = + man/foo.1 diff --git a/tests/tpb06/setup.py b/tests/tpb06/setup.py new file mode 100644 index 0000000..de0d34b --- /dev/null +++ b/tests/tpb06/setup.py @@ -0,0 +1,12 @@ +from setuptools import setup, Extension + +setup_args = dict( + ext_modules = [ + Extension( + 'foo.ext', + ['foo/ext.c'], + py_limited_api = True, + ) + ] +) +setup(**setup_args) diff --git a/tests/tpb07/Makefile b/tests/tpb07/Makefile new file mode 100644 index 0000000..5eb4f00 --- /dev/null +++ b/tests/tpb07/Makefile @@ -0,0 +1,11 @@ +#!/usr/bin/make -f +include ../common.mk + +check: + test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py + test -f debian/python3-bar/usr/lib/python3/dist-packages/bar/__init__.py + test -f debian/python3-foo/usr/bin/foo + test -f debian/python3-bar/usr/bin/bar + +clean: + ./debian/rules clean diff --git a/tests/tpb07/bar/LICENSE b/tests/tpb07/bar/LICENSE new file mode 100644 index 0000000..5996299 --- /dev/null +++ b/tests/tpb07/bar/LICENSE @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/tests/tpb07/bar/bar/__init__.py b/tests/tpb07/bar/bar/__init__.py new file mode 100644 index 0000000..717b184 --- /dev/null +++ b/tests/tpb07/bar/bar/__init__.py @@ -0,0 +1,4 @@ +"""An amazing sample package!""" + +def main(): + print("Hello I am bar") diff --git a/tests/tpb07/bar/pyproject.toml b/tests/tpb07/bar/pyproject.toml new file mode 100644 index 0000000..9787c3b --- /dev/null +++ b/tests/tpb07/bar/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/tests/tpb07/bar/setup.cfg b/tests/tpb07/bar/setup.cfg new file mode 100644 index 0000000..296c419 --- /dev/null +++ b/tests/tpb07/bar/setup.cfg @@ -0,0 +1,17 @@ +[metadata] +name = bar +version = 0.1 +description = My package description +long_description = My long description +license = Expat + +[options] +zip_safe = False +packages = find: +install_requires = + tomli + importlib-metadata; python_version<'3.5' + +[options.entry_points] +console_scripts = + bar = bar:main diff --git a/tests/tpb07/debian/changelog b/tests/tpb07/debian/changelog new file mode 100644 index 0000000..fa1a4b0 --- /dev/null +++ b/tests/tpb07/debian/changelog @@ -0,0 +1,5 @@ +foobar (1.2.3) unstable; urgency=low + + * Initial release + + -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200 diff --git a/tests/tpb07/debian/control b/tests/tpb07/debian/control new file mode 100644 index 0000000..6631581 --- /dev/null +++ b/tests/tpb07/debian/control @@ -0,0 +1,21 @@ +Source: foobar +Section: python +Priority: optional +Maintainer: Piotr Ożarowski <piotr@debian.org> +Build-Depends: debhelper-compat (= 12) + , python3-all + , python3-setuptools + , pybuild-plugin-pyproject +Standards-Version: 3.9.4 + +Package: python3-foo +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #1 + +Package: python3-bar +Architecture: all +Depends: ${python3:Depends}, ${misc:Depends} +Description: package with public CPython modules + example package #2 diff --git a/tests/tpb07/debian/copyright b/tests/tpb07/debian/copyright new file mode 100644 index 0000000..f96adde --- /dev/null +++ b/tests/tpb07/debian/copyright @@ -0,0 +1,2 @@ +The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and +is licensed under the MIT License. diff --git a/tests/tpb07/debian/rules b/tests/tpb07/debian/rules new file mode 100755 index 0000000..b93abef --- /dev/null +++ b/tests/tpb07/debian/rules @@ -0,0 +1,30 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=foo + +%: + dh $@ + +override_dh_auto_build: + ../../pybuild -d foo --build --verbose --name=foo + ../../pybuild -d bar --build --verbose --name=bar + +override_dh_auto_install: + ../../pybuild -d foo --install --name=foo + ../../pybuild -d bar --install --name=bar + +override_dh_auto_test: + ../../pybuild -d foo --test --name=foo + ../../pybuild -d bar --test --name=bar + +override_dh_auto_clean: + ../../pybuild -d foo --clean --verbose --name=foo + ../../pybuild -d bar --clean --verbose --name=bar + rm -rf .pybuild foo/foo.egg-info bar/bar.egg-info + +override_dh_installinit: + DH_VERBOSE=1 ../../dh_python3 + dh_installinit + +override_dh_python3: + # ignore any system dh_python3 diff --git a/tests/tpb07/debian/source/format b/tests/tpb07/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/tests/tpb07/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/tests/tpb07/foo/LICENSE b/tests/tpb07/foo/LICENSE new file mode 100644 index 0000000..5996299 --- /dev/null +++ b/tests/tpb07/foo/LICENSE @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/tests/tpb07/foo/foo/__init__.py b/tests/tpb07/foo/foo/__init__.py new file mode 100644 index 0000000..1421a55 --- /dev/null +++ b/tests/tpb07/foo/foo/__init__.py @@ -0,0 +1,4 @@ +"""An amazing sample package!""" + +def main(): + print("Hello I am foo") diff --git a/tests/tpb07/foo/pyproject.toml b/tests/tpb07/foo/pyproject.toml new file mode 100644 index 0000000..9787c3b --- /dev/null +++ b/tests/tpb07/foo/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/tests/tpb07/foo/setup.cfg b/tests/tpb07/foo/setup.cfg new file mode 100644 index 0000000..3447fdc --- /dev/null +++ b/tests/tpb07/foo/setup.cfg @@ -0,0 +1,17 @@ +[metadata] +name = foo +version = 0.1 +description = My package description +long_description = My long description +license = Expat + +[options] +zip_safe = False +packages = find: +install_requires = + tomli + importlib-metadata; python_version<'3.5' + +[options.entry_points] +console_scripts = + foo = foo:main |