Tue Dec 17 08:17:07 UTC 2024 I: starting to build git-ubuntu/unstable/arm64 on jenkins on '2024-12-17 08:16' Tue Dec 17 08:17:07 UTC 2024 I: The jenkins build log is/was available at https://jenkins.debian.net/userContent/reproducible/debian/build_service/arm64_10/50334/console.log Tue Dec 17 08:17:07 UTC 2024 I: Downloading source for unstable/git-ubuntu=1.1-2 --2024-12-17 08:17:07-- http://deb.debian.org/debian/pool/main/g/git-ubuntu/git-ubuntu_1.1-2.dsc Connecting to 46.16.76.132:3128... connected. Proxy request sent, awaiting response... 200 OK Length: 2280 (2.2K) [text/prs.lines.tag] Saving to: ‘git-ubuntu_1.1-2.dsc’ 0K .. 100% 215M=0s 2024-12-17 08:17:07 (215 MB/s) - ‘git-ubuntu_1.1-2.dsc’ saved [2280/2280] Tue Dec 17 08:17:07 UTC 2024 I: git-ubuntu_1.1-2.dsc -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Format: 3.0 (quilt) Source: git-ubuntu Binary: git-ubuntu Architecture: all Version: 1.1-2 Maintainer: Debian Python Team Uploaders: Benjamin Drung Homepage: https://launchpad.net/git-ubuntu Standards-Version: 4.7.0 Vcs-Browser: https://salsa.debian.org/python-team/packages/git-ubuntu Vcs-Git: https://salsa.debian.org/python-team/packages/git-ubuntu.git Testsuite: autopkgtest Build-Depends: bash-completion, debhelper-compat (= 13), debian-archive-keyring, dh-exec, dh-python, git, git-buildpackage, pristine-tar, python3 (>= 3.6), python3-cachetools, python3-keyring, python3-keyrings.alt, python3-pygit2, python3-pytest, python3-setuptools, python3-systemd, python3-tenacity, python3-ubuntutools, python3-zmq, quilt, ubuntu-dev-tools, ubuntu-keyring Package-List: git-ubuntu deb devel optional arch=all Checksums-Sha1: e5bf928666e1f67bb4ec8701434ee03d12872879 179268 git-ubuntu_1.1.orig.tar.xz e40f7bd1eaaaa92b44b32cbc34b7696261c31ad3 7328 git-ubuntu_1.1-2.debian.tar.xz Checksums-Sha256: 9de2950a5a3a16db8517966b7590de31483f4d3786c8ba455bb412ade0e53106 179268 git-ubuntu_1.1.orig.tar.xz 5ca82a988f70a0dc6a3d4d1787097c822d535024a4fd55bd366857c4c69e70fd 7328 git-ubuntu_1.1-2.debian.tar.xz Files: ea902a0087f7a52b86767e02f4013027 179268 git-ubuntu_1.1.orig.tar.xz 1fb36725e74d60382e4e6c9155cb9e33 7328 git-ubuntu_1.1-2.debian.tar.xz -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEpi0s+9ULm1vzYNVLFZ61xO/Id0wFAmdgAc0ACgkQFZ61xO/I d0ze7Q//XXvglZLUw13oVfNOov0fFevA7yQ7FdKL1gQgmLb6IXTIYbEN8wOZapin 7DCYTWHsWTYPW4B4O9Cc64kEECu4FheU1oZC+guw3G0V0nM7/F3nwVRd/Na3xzE4 9PA0T55OpTc++Go0y2U+XoV31/gMYVemw4uC1qPO74j0vTZXcKyA7qTJKKyBdUll LGCy4x0/xxmxz7xiRf7cDwCnT+NMo+7yj2shnnKqDk60AWhqxcL151G5UATE5QBz 1EdyF+cFKaC5qiFLgqaM9kPJiZpOk+yWsvWdY/Kvxd0k9cN36BqinEBv+T8b+RDU nrLVZy3kYko3wbEwY72zFLdTj1iCD4OziJER59lZwZrO5J8wUgmPi9lsGX+7eB17 nqmmW661+CS5ZK7Ok5NB3vFqdcTrqNZPnuDzYXXbAswJQ7ehlEN9pyJpEdfygXgV uAnYVcP4eNbNw4q++Mq82ojibFK5/YxrNyZBB/W9R2lSa1ZXYOq8ohsRrYfxEbXR tdgdPW/uYcmvMAJzsfKJVGDFADT+y3KyGEaUTNVPrQR5rVFWhwFEjXYRO9Bo3ns1 6tFPboQ9YumQzbyTUVYL/FOIENSPT7635rbfhCe2f/AT0QjYYsx/gJTEuRruomGG z8+IxvfNpSMcSzUWGwXsmiJL+2BMJ3fnNV27Q6QXDq9aDMu/ymc= =oHk8 -----END PGP SIGNATURE----- Tue Dec 17 08:17:07 UTC 2024 I: Checking whether the package is not for us Tue Dec 17 08:17:07 UTC 2024 I: Starting 1st build on remote node codethink04-arm64.debian.net. Tue Dec 17 08:17:07 UTC 2024 I: Preparing to do remote build '1' on codethink04-arm64.debian.net. Tue Dec 17 08:20:49 UTC 2024 I: Deleting $TMPDIR on codethink04-arm64.debian.net. I: pbuilder: network access will be disabled during build I: Current time: Mon Dec 16 20:17:09 -12 2024 I: pbuilder-time-stamp: 1734423429 I: Building the build Environment I: extracting base tarball [/var/cache/pbuilder/unstable-reproducible-base.tgz] I: copying local configuration W: --override-config is not set; not updating apt.conf Read the manpage for details. I: mounting /proc filesystem I: mounting /sys filesystem I: creating /{dev,run}/shm I: mounting /dev/pts filesystem I: redirecting /dev/ptmx to /dev/pts/ptmx I: policy-rc.d already exists I: Copying source file I: copying [git-ubuntu_1.1-2.dsc] I: copying [./git-ubuntu_1.1.orig.tar.xz] I: copying [./git-ubuntu_1.1-2.debian.tar.xz] I: Extracting source gpgv: Signature made Mon Dec 16 10:32:45 2024 gpgv: using RSA key A62D2CFBD50B9B5BF360D54B159EB5C4EFC8774C gpgv: Can't check signature: No public key dpkg-source: warning: cannot verify inline signature for ./git-ubuntu_1.1-2.dsc: no acceptable signature found dpkg-source: info: extracting git-ubuntu in git-ubuntu-1.1 dpkg-source: info: unpacking git-ubuntu_1.1.orig.tar.xz dpkg-source: info: unpacking git-ubuntu_1.1-2.debian.tar.xz dpkg-source: info: using patch list from debian/patches/series dpkg-source: info: applying Drop-unused-petname.patch dpkg-source: info: applying man-Fix-bad-whatis-entries.patch dpkg-source: info: applying test-call-dch-with-vendor-Ubuntu-in-reconstruct-changelog.patch dpkg-source: info: applying submit-fix-setting-commitish_string.patch dpkg-source: info: applying test-Always-set-ENTRY_POINT_DIR.patch dpkg-source: info: applying use-pygit2-objecttype.patch dpkg-source: info: applying Fix-spelling-mistake-of-repository.patch I: Not using root during the build. I: Installing the build-deps I: user script /srv/workspace/pbuilder/2498186/tmp/hooks/D02_print_environment starting I: set BUILDDIR='/build/reproducible-path' BUILDUSERGECOS='first user,first room,first work-phone,first home-phone,first other' BUILDUSERNAME='pbuilder1' BUILD_ARCH='arm64' DEBIAN_FRONTEND='noninteractive' DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all parallel=12 ' DISTRIBUTION='unstable' HOME='/root' HOST_ARCH='arm64' IFS=' ' INVOCATION_ID='1b9beced7f644c0c951ad29348a41b78' LANG='C' LANGUAGE='en_US:en' LC_ALL='C' MAIL='/var/mail/root' OPTIND='1' PATH='/usr/sbin:/usr/bin:/sbin:/bin:/usr/games' PBCURRENTCOMMANDLINEOPERATION='build' PBUILDER_OPERATION='build' PBUILDER_PKGDATADIR='/usr/share/pbuilder' PBUILDER_PKGLIBDIR='/usr/lib/pbuilder' PBUILDER_SYSCONFDIR='/etc' PPID='2498186' PS1='# ' PS2='> ' PS4='+ ' PWD='/' SHELL='/bin/bash' SHLVL='2' SUDO_COMMAND='/usr/bin/timeout -k 18.1h 18h /usr/bin/ionice -c 3 /usr/bin/nice /usr/sbin/pbuilder --build --configfile /srv/reproducible-results/rbuild-debian/r-b-build.vP7TdOEY/pbuilderrc_ENBP --distribution unstable --hookdir /etc/pbuilder/first-build-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/unstable-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/r-b-build.vP7TdOEY/b1 --logfile b1/build.log git-ubuntu_1.1-2.dsc' SUDO_GID='109' SUDO_UID='104' SUDO_USER='jenkins' TERM='unknown' TZ='/usr/share/zoneinfo/Etc/GMT+12' USER='root' _='/usr/bin/systemd-run' http_proxy='http://192.168.101.4:3128' I: uname -a Linux codethink04-arm64 6.1.0-28-cloud-arm64 #1 SMP Debian 6.1.119-1 (2024-11-22) aarch64 GNU/Linux I: ls -l /bin lrwxrwxrwx 1 root root 7 Nov 22 14:40 /bin -> usr/bin I: user script /srv/workspace/pbuilder/2498186/tmp/hooks/D02_print_environment finished -> Attempting to satisfy build-dependencies -> Creating pbuilder-satisfydepends-dummy package Package: pbuilder-satisfydepends-dummy Version: 0.invalid.0 Architecture: arm64 Maintainer: Debian Pbuilder Team Description: Dummy package to satisfy dependencies with aptitude - created by pbuilder This package was created automatically by pbuilder to satisfy the build-dependencies of the package being currently built. Depends: bash-completion, debhelper-compat (= 13), debian-archive-keyring, dh-exec, dh-python, git, git-buildpackage, pristine-tar, python3 (>= 3.6), python3-cachetools, python3-keyring, python3-keyrings.alt, python3-pygit2, python3-pytest, python3-setuptools, python3-systemd, python3-tenacity, python3-ubuntutools, python3-zmq, quilt, ubuntu-dev-tools, ubuntu-keyring dpkg-deb: building package 'pbuilder-satisfydepends-dummy' in '/tmp/satisfydepends-aptitude/pbuilder-satisfydepends-dummy.deb'. Selecting previously unselected package pbuilder-satisfydepends-dummy. (Reading database ... 20085 files and directories currently installed.) Preparing to unpack .../pbuilder-satisfydepends-dummy.deb ... Unpacking pbuilder-satisfydepends-dummy (0.invalid.0) ... dpkg: pbuilder-satisfydepends-dummy: dependency problems, but configuring anyway as you requested: pbuilder-satisfydepends-dummy depends on bash-completion; however: Package bash-completion is not installed. pbuilder-satisfydepends-dummy depends on debhelper-compat (= 13); however: Package debhelper-compat is not installed. pbuilder-satisfydepends-dummy depends on dh-exec; however: Package dh-exec is not installed. pbuilder-satisfydepends-dummy depends on dh-python; however: Package dh-python is not installed. pbuilder-satisfydepends-dummy depends on git; however: Package git is not installed. pbuilder-satisfydepends-dummy depends on git-buildpackage; however: Package git-buildpackage is not installed. pbuilder-satisfydepends-dummy depends on pristine-tar; however: Package pristine-tar is not installed. pbuilder-satisfydepends-dummy depends on python3 (>= 3.6); however: Package python3 is not installed. pbuilder-satisfydepends-dummy depends on python3-cachetools; however: Package python3-cachetools is not installed. pbuilder-satisfydepends-dummy depends on python3-keyring; however: Package python3-keyring is not installed. pbuilder-satisfydepends-dummy depends on python3-keyrings.alt; however: Package python3-keyrings.alt is not installed. pbuilder-satisfydepends-dummy depends on python3-pygit2; however: Package python3-pygit2 is not installed. pbuilder-satisfydepends-dummy depends on python3-pytest; however: Package python3-pytest is not installed. pbuilder-satisfydepends-dummy depends on python3-setuptools; however: Package python3-setuptools is not installed. pbuilder-satisfydepends-dummy depends on python3-systemd; however: Package python3-systemd is not installed. pbuilder-satisfydepends-dummy depends on python3-tenacity; however: Package python3-tenacity is not installed. pbuilder-satisfydepends-dummy depends on python3-ubuntutools; however: Package python3-ubuntutools is not installed. pbuilder-satisfydepends-dummy depends on python3-zmq; however: Package python3-zmq is not installed. pbuilder-satisfydepends-dummy depends on quilt; however: Package quilt is not installed. pbuilder-satisfydepends-dummy depends on ubuntu-dev-tools; however: Package ubuntu-dev-tools is not installed. pbuilder-satisfydepends-dummy depends on ubuntu-keyring; however: Package ubuntu-keyring is not installed. Setting up pbuilder-satisfydepends-dummy (0.invalid.0) ... Reading package lists... Building dependency tree... Reading state information... Initializing package states... Writing extended state information... Building tag database... pbuilder-satisfydepends-dummy is already installed at the requested version (0.invalid.0) pbuilder-satisfydepends-dummy is already installed at the requested version (0.invalid.0) The following NEW packages will be installed: autoconf{a} automake{a} autopoint{a} autotools-dev{a} bash-completion{a} bsdextrautils{a} ca-certificates{a} dctrl-tools{a} debhelper{a} devscripts{a} dh-autoreconf{a} dh-exec{a} dh-python{a} dh-strip-nondeterminism{a} diffstat{a} dirmngr{a} distro-info{a} distro-info-data{a} dput{a} dwz{a} ed{a} file{a} gettext{a} gettext-base{a} git{a} git-buildpackage{a} git-man{a} gnupg{a} gnupg-l10n{a} gpg{a} gpg-agent{a} gpgconf{a} gpgsm{a} groff-base{a} intltool-debian{a} libapparmor1{a} libarchive-zip-perl{a} libarchive13t64{a} libassuan9{a} libb-hooks-op-check-perl{a} libbrotli1{a} libclass-method-modifiers-perl{a} libclass-xsaccessor-perl{a} libclone-perl{a} libcom-err2{a} libcurl3t64-gnutls{a} libdebhelper-perl{a} libdevel-callchecker-perl{a} libdynaloader-functions-perl{a} libelf1t64{a} libencode-locale-perl{a} liberror-perl{a} libexpat1{a} libfile-dirlist-perl{a} libfile-homedir-perl{a} libfile-listing-perl{a} libfile-stripnondeterminism-perl{a} libfile-touch-perl{a} libfile-which-perl{a} libgit2-1.8{a} libglib2.0-0t64{a} libgpgme11t64{a} libgssapi-krb5-2{a} libhtml-parser-perl{a} libhtml-tagset-perl{a} libhtml-tree-perl{a} libhttp-cookies-perl{a} libhttp-date-perl{a} libhttp-message-perl{a} libhttp-negotiate-perl{a} libhttp-parser2.9{a} libicu72{a} libimport-into-perl{a} libio-html-perl{a} libio-pty-perl{a} libio-socket-ssl-perl{a} libipc-run-perl{a} libk5crypto3{a} libkeyutils1{a} libkrb5-3{a} libkrb5support0{a} libksba8{a} libldap-2.5-0{a} liblwp-mediatypes-perl{a} liblwp-protocol-https-perl{a} libmagic-mgc{a} libmagic1t64{a} libmbedcrypto16{a} libmbedtls21{a} libmbedx509-7{a} libmodule-runtime-perl{a} libmoo-perl{a} libnet-http-perl{a} libnet-ssleay-perl{a} libnghttp2-14{a} libnghttp3-9{a} libngtcp2-16{a} libngtcp2-crypto-gnutls8{a} libnorm1t64{a} libnpth0t64{a} libnsl2{a} libparams-classify-perl{a} libpgm-5.3-0t64{a} libpipeline1{a} libpsl5t64{a} libpython3-stdlib{a} libpython3.12-minimal{a} libpython3.12-stdlib{a} libreadline8t64{a} librole-tiny-perl{a} librtmp1{a} libsasl2-2{a} libsasl2-modules-db{a} libsodium23{a} libssh2-1t64{a} libsub-quote-perl{a} libsys-cpuaffinity-perl{a} libtimedate-perl{a} libtirpc-common{a} libtirpc3t64{a} libtool{a} libtry-tiny-perl{a} libuchardet0{a} liburi-perl{a} libwww-perl{a} libwww-robotrules-perl{a} libxdelta2t64{a} libxml2{a} libyaml-0-2{a} libzmq5{a} lsb-release{a} m4{a} man-db{a} media-types{a} netbase{a} openssl{a} patchutils{a} pbzip2{a} perl-openssl-defaults{a} pinentry-curses{a} pixz{a} po-debconf{a} pristine-tar{a} python-apt-common{a} python3{a} python3-apt{a} python3-autocommand{a} python3-bcrypt{a} python3-blinker{a} python3-cachetools{a} python3-certifi{a} python3-cffi-backend{a} python3-chardet{a} python3-charset-normalizer{a} python3-cryptography{a} python3-dateutil{a} python3-debian{a} python3-debianbts{a} python3-distro{a} python3-distro-info{a} python3-gpg{a} python3-httplib2{a} python3-idna{a} python3-importlib-metadata{a} python3-inflect{a} python3-iniconfig{a} python3-jaraco.classes{a} python3-jaraco.context{a} python3-jaraco.functools{a} python3-jaraco.text{a} python3-jeepney{a} python3-jwt{a} python3-keyring{a} python3-keyrings.alt{a} python3-launchpadlib{a} python3-launchpadlib-desktop{a} python3-lazr.restfulclient{a} python3-lazr.uri{a} python3-minimal{a} python3-more-itertools{a} python3-oauthlib{a} python3-packaging{a} python3-pkg-resources{a} python3-pluggy{a} python3-pycryptodome{a} python3-pygit2{a} python3-pyparsing{a} python3-pytest{a} python3-requests{a} python3-secretstorage{a} python3-setuptools{a} python3-systemd{a} python3-tenacity{a} python3-typeguard{a} python3-typing-extensions{a} python3-ubuntutools{a} python3-urllib3{a} python3-wadllib{a} python3-xdg{a} python3-yaml{a} python3-zipp{a} python3-zmq{a} python3.12{a} python3.12-minimal{a} quilt{a} readline-common{a} sensible-utils{a} sudo{a} tzdata{a} ubuntu-dev-tools{a} ubuntu-keyring{a} wdiff{a} xdelta{a} xdelta3{a} The following packages are RECOMMENDED but will NOT be installed: arch-test cowbuilder curl debian-keyring debootstrap equivs genisoimage gnupg-utils gpg-wks-client iso-codes krb5-locales less libarchive-cpio-perl libdata-dump-perl libdistro-info-perl libgit-wrapper-perl libgitlab-api-v4-perl libglib2.0-data libhtml-form-perl libhtml-format-perl libhttp-daemon-perl libio-compress-brotli-perl libjson-perl libldap-common liblist-compare-perl libltdl-dev libmail-sendmail-perl libmailtools-perl libnamespace-clean-perl libsasl2-modules libsoap-lite-perl libstring-shellquote-perl libxstring-perl licensecheck lintian lynx openssh-client pbuilder publicsuffix python3-dns python3-magic python3-pygments python3-unidiff reportbug sbuild shared-mime-info strace unzip wget xdg-user-dirs zstd 0 packages upgraded, 214 newly installed, 0 to remove and 0 not upgraded. Need to get 61.0 MB of archives. After unpacking 253 MB will be used. Writing extended state information... Get: 1 http://deb.debian.org/debian unstable/main arm64 libpython3.12-minimal arm64 3.12.8-3 [810 kB] Get: 2 http://deb.debian.org/debian unstable/main arm64 libexpat1 arm64 2.6.4-1 [90.7 kB] Get: 3 http://deb.debian.org/debian unstable/main arm64 python3.12-minimal arm64 3.12.8-3 [1941 kB] Get: 4 http://deb.debian.org/debian unstable/main arm64 python3-minimal arm64 3.12.7-1 [26.8 kB] Get: 5 http://deb.debian.org/debian unstable/main arm64 media-types all 10.1.0 [26.9 kB] Get: 6 http://deb.debian.org/debian unstable/main arm64 netbase all 6.4 [12.8 kB] Get: 7 http://deb.debian.org/debian unstable/main arm64 tzdata all 2024b-4 [256 kB] Get: 8 http://deb.debian.org/debian unstable/main arm64 libkrb5support0 arm64 1.21.3-3 [32.1 kB] Get: 9 http://deb.debian.org/debian unstable/main arm64 libcom-err2 arm64 1.47.2~rc1-2 [23.7 kB] Get: 10 http://deb.debian.org/debian unstable/main arm64 libk5crypto3 arm64 1.21.3-3 [80.8 kB] Get: 11 http://deb.debian.org/debian unstable/main arm64 libkeyutils1 arm64 1.6.3-4 [9352 B] Get: 12 http://deb.debian.org/debian unstable/main arm64 libkrb5-3 arm64 1.21.3-3 [310 kB] Get: 13 http://deb.debian.org/debian unstable/main arm64 libgssapi-krb5-2 arm64 1.21.3-3 [126 kB] Get: 14 http://deb.debian.org/debian unstable/main arm64 libtirpc-common all 1.3.4+ds-1.3 [10.9 kB] Get: 15 http://deb.debian.org/debian unstable/main arm64 libtirpc3t64 arm64 1.3.4+ds-1.3+b1 [78.7 kB] Get: 16 http://deb.debian.org/debian unstable/main arm64 libnsl2 arm64 1.3.0-3+b3 [37.9 kB] Get: 17 http://deb.debian.org/debian unstable/main arm64 readline-common all 8.2-6 [69.4 kB] Get: 18 http://deb.debian.org/debian unstable/main arm64 libreadline8t64 arm64 8.2-6 [159 kB] Get: 19 http://deb.debian.org/debian unstable/main arm64 libpython3.12-stdlib arm64 3.12.8-3 [1906 kB] Get: 20 http://deb.debian.org/debian unstable/main arm64 python3.12 arm64 3.12.8-3 [677 kB] Get: 21 http://deb.debian.org/debian unstable/main arm64 libpython3-stdlib arm64 3.12.7-1 [9708 B] Get: 22 http://deb.debian.org/debian unstable/main arm64 python3 arm64 3.12.7-1 [27.8 kB] Get: 23 http://deb.debian.org/debian unstable/main arm64 libapparmor1 arm64 3.1.7-1+b3 [41.8 kB] Get: 24 http://deb.debian.org/debian unstable/main arm64 sudo arm64 1.9.16p1-1 [1986 kB] Get: 25 http://deb.debian.org/debian unstable/main arm64 sensible-utils all 0.0.24 [24.8 kB] Get: 26 http://deb.debian.org/debian unstable/main arm64 bash-completion all 1:2.14.0-2 [310 kB] Get: 27 http://deb.debian.org/debian unstable/main arm64 openssl arm64 3.3.2-2 [1347 kB] Get: 28 http://deb.debian.org/debian unstable/main arm64 ca-certificates all 20240203 [158 kB] Get: 29 http://deb.debian.org/debian unstable/main arm64 libmagic-mgc arm64 1:5.45-3+b1 [314 kB] Get: 30 http://deb.debian.org/debian unstable/main arm64 libmagic1t64 arm64 1:5.45-3+b1 [102 kB] Get: 31 http://deb.debian.org/debian unstable/main arm64 file arm64 1:5.45-3+b1 [43.4 kB] Get: 32 http://deb.debian.org/debian unstable/main arm64 gettext-base arm64 0.22.5-3 [198 kB] Get: 33 http://deb.debian.org/debian unstable/main arm64 libuchardet0 arm64 0.0.8-1+b2 [69.2 kB] Get: 34 http://deb.debian.org/debian unstable/main arm64 groff-base arm64 1.23.0-6 [1130 kB] Get: 35 http://deb.debian.org/debian unstable/main arm64 bsdextrautils arm64 2.40.2-12 [91.4 kB] Get: 36 http://deb.debian.org/debian unstable/main arm64 libpipeline1 arm64 1.5.8-1 [40.2 kB] Get: 37 http://deb.debian.org/debian unstable/main arm64 man-db arm64 2.13.0-1 [1404 kB] Get: 38 http://deb.debian.org/debian unstable/main arm64 m4 arm64 1.4.19-4 [277 kB] Get: 39 http://deb.debian.org/debian unstable/main arm64 autoconf all 2.72-3 [493 kB] Get: 40 http://deb.debian.org/debian unstable/main arm64 autotools-dev all 20220109.1 [51.6 kB] Get: 41 http://deb.debian.org/debian unstable/main arm64 automake all 1:1.16.5-1.3 [823 kB] Get: 42 http://deb.debian.org/debian unstable/main arm64 autopoint all 0.22.5-3 [723 kB] Get: 43 http://deb.debian.org/debian unstable/main arm64 dctrl-tools arm64 2.24-3+b1 [125 kB] Get: 44 http://deb.debian.org/debian unstable/main arm64 libdebhelper-perl all 13.21 [88.9 kB] Get: 45 http://deb.debian.org/debian unstable/main arm64 libtool all 2.4.7-8 [517 kB] Get: 46 http://deb.debian.org/debian unstable/main arm64 dh-autoreconf all 20 [17.1 kB] Get: 47 http://deb.debian.org/debian unstable/main arm64 libarchive-zip-perl all 1.68-1 [104 kB] Get: 48 http://deb.debian.org/debian unstable/main arm64 libfile-stripnondeterminism-perl all 1.14.0-1 [19.5 kB] Get: 49 http://deb.debian.org/debian unstable/main arm64 dh-strip-nondeterminism all 1.14.0-1 [8448 B] Get: 50 http://deb.debian.org/debian unstable/main arm64 libelf1t64 arm64 0.192-4 [189 kB] Get: 51 http://deb.debian.org/debian unstable/main arm64 dwz arm64 0.15-1+b1 [102 kB] Get: 52 http://deb.debian.org/debian unstable/main arm64 libicu72 arm64 72.1-5+b1 [9239 kB] Get: 53 http://deb.debian.org/debian unstable/main arm64 libxml2 arm64 2.12.7+dfsg+really2.9.14-0.2+b1 [630 kB] Get: 54 http://deb.debian.org/debian unstable/main arm64 gettext arm64 0.22.5-3 [1532 kB] Get: 55 http://deb.debian.org/debian unstable/main arm64 intltool-debian all 0.35.0+20060710.6 [22.9 kB] Get: 56 http://deb.debian.org/debian unstable/main arm64 po-debconf all 1.0.21+nmu1 [248 kB] Get: 57 http://deb.debian.org/debian unstable/main arm64 debhelper all 13.21 [919 kB] Get: 58 http://deb.debian.org/debian unstable/main arm64 libassuan9 arm64 3.0.1-2 [58.1 kB] Get: 59 http://deb.debian.org/debian unstable/main arm64 gpgconf arm64 2.2.45-2 [114 kB] Get: 60 http://deb.debian.org/debian unstable/main arm64 libksba8 arm64 1.6.7-2+b1 [125 kB] Get: 61 http://deb.debian.org/debian unstable/main arm64 libsasl2-modules-db arm64 2.1.28+dfsg1-8 [20.0 kB] Get: 62 http://deb.debian.org/debian unstable/main arm64 libsasl2-2 arm64 2.1.28+dfsg1-8 [55.4 kB] Get: 63 http://deb.debian.org/debian unstable/main arm64 libldap-2.5-0 arm64 2.5.18+dfsg-3+b1 [175 kB] Get: 64 http://deb.debian.org/debian unstable/main arm64 libnpth0t64 arm64 1.8-2 [22.8 kB] Get: 65 http://deb.debian.org/debian unstable/main arm64 dirmngr arm64 2.2.45-2 [343 kB] Get: 66 http://deb.debian.org/debian unstable/main arm64 gnupg-l10n all 2.2.45-2 [705 kB] Get: 67 http://deb.debian.org/debian unstable/main arm64 gpg arm64 2.2.45-2 [481 kB] Get: 68 http://deb.debian.org/debian unstable/main arm64 pinentry-curses arm64 1.2.1-4+b1 [76.7 kB] Get: 69 http://deb.debian.org/debian unstable/main arm64 gpg-agent arm64 2.2.45-2 [230 kB] Get: 70 http://deb.debian.org/debian unstable/main arm64 gpgsm arm64 2.2.45-2 [232 kB] Get: 71 http://deb.debian.org/debian unstable/main arm64 gnupg all 2.2.45-2 [376 kB] Get: 72 http://deb.debian.org/debian unstable/main arm64 libfile-dirlist-perl all 0.05-3 [7600 B] Get: 73 http://deb.debian.org/debian unstable/main arm64 libfile-which-perl all 1.27-2 [15.1 kB] Get: 74 http://deb.debian.org/debian unstable/main arm64 libfile-homedir-perl all 1.006-2 [42.4 kB] Get: 75 http://deb.debian.org/debian unstable/main arm64 libfile-touch-perl all 0.12-2 [8816 B] Get: 76 http://deb.debian.org/debian unstable/main arm64 libio-pty-perl arm64 1:1.20-1+b2 [34.0 kB] Get: 77 http://deb.debian.org/debian unstable/main arm64 libipc-run-perl all 20231003.0-2 [101 kB] Get: 78 http://deb.debian.org/debian unstable/main arm64 libclass-method-modifiers-perl all 2.15-1 [18.0 kB] Get: 79 http://deb.debian.org/debian unstable/main arm64 libclass-xsaccessor-perl arm64 1.19-4+b4 [34.9 kB] Get: 80 http://deb.debian.org/debian unstable/main arm64 libb-hooks-op-check-perl arm64 0.22-3+b2 [10.6 kB] Get: 81 http://deb.debian.org/debian unstable/main arm64 libdynaloader-functions-perl all 0.004-1 [12.1 kB] Get: 82 http://deb.debian.org/debian unstable/main arm64 libdevel-callchecker-perl arm64 0.009-1+b1 [16.3 kB] Get: 83 http://deb.debian.org/debian unstable/main arm64 libparams-classify-perl arm64 0.015-2+b4 [22.3 kB] Get: 84 http://deb.debian.org/debian unstable/main arm64 libmodule-runtime-perl all 0.016-2 [19.6 kB] Get: 85 http://deb.debian.org/debian unstable/main arm64 libimport-into-perl all 1.002005-2 [11.3 kB] Get: 86 http://deb.debian.org/debian unstable/main arm64 librole-tiny-perl all 2.002004-1 [21.4 kB] Get: 87 http://deb.debian.org/debian unstable/main arm64 libsub-quote-perl all 2.006008-1 [21.8 kB] Get: 88 http://deb.debian.org/debian unstable/main arm64 libmoo-perl all 2.005005-1 [58.0 kB] Get: 89 http://deb.debian.org/debian unstable/main arm64 libencode-locale-perl all 1.05-3 [12.9 kB] Get: 90 http://deb.debian.org/debian unstable/main arm64 libtimedate-perl all 2.3300-2 [39.3 kB] Get: 91 http://deb.debian.org/debian unstable/main arm64 libhttp-date-perl all 6.06-1 [10.7 kB] Get: 92 http://deb.debian.org/debian unstable/main arm64 libfile-listing-perl all 6.16-1 [12.4 kB] Get: 93 http://deb.debian.org/debian unstable/main arm64 libhtml-tagset-perl all 3.24-1 [14.7 kB] Get: 94 http://deb.debian.org/debian unstable/main arm64 liburi-perl all 5.30-1 [105 kB] Get: 95 http://deb.debian.org/debian unstable/main arm64 libhtml-parser-perl arm64 3.83-1+b1 [97.5 kB] Get: 96 http://deb.debian.org/debian unstable/main arm64 libhtml-tree-perl all 5.07-3 [211 kB] Get: 97 http://deb.debian.org/debian unstable/main arm64 libclone-perl arm64 0.47-1+b1 [13.7 kB] Get: 98 http://deb.debian.org/debian unstable/main arm64 libio-html-perl all 1.004-3 [16.2 kB] Get: 99 http://deb.debian.org/debian unstable/main arm64 liblwp-mediatypes-perl all 6.04-2 [20.2 kB] Get: 100 http://deb.debian.org/debian unstable/main arm64 libhttp-message-perl all 7.00-2 [79.8 kB] Get: 101 http://deb.debian.org/debian unstable/main arm64 libhttp-cookies-perl all 6.11-1 [19.1 kB] Get: 102 http://deb.debian.org/debian unstable/main arm64 libhttp-negotiate-perl all 6.01-2 [13.1 kB] Get: 103 http://deb.debian.org/debian unstable/main arm64 perl-openssl-defaults arm64 7+b2 [6712 B] Get: 104 http://deb.debian.org/debian unstable/main arm64 libnet-ssleay-perl arm64 1.94-2 [323 kB] Get: 105 http://deb.debian.org/debian unstable/main arm64 libio-socket-ssl-perl all 2.089-1 [223 kB] Get: 106 http://deb.debian.org/debian unstable/main arm64 libnet-http-perl all 6.23-1 [23.9 kB] Get: 107 http://deb.debian.org/debian unstable/main arm64 liblwp-protocol-https-perl all 6.14-1 [10.8 kB] Get: 108 http://deb.debian.org/debian unstable/main arm64 libtry-tiny-perl all 0.32-1 [22.9 kB] Get: 109 http://deb.debian.org/debian unstable/main arm64 libwww-robotrules-perl all 6.02-1 [12.9 kB] Get: 110 http://deb.debian.org/debian unstable/main arm64 libwww-perl all 6.77-1 [183 kB] Get: 111 http://deb.debian.org/debian unstable/main arm64 patchutils arm64 0.4.2-1+b1 [71.3 kB] Get: 112 http://deb.debian.org/debian unstable/main arm64 wdiff arm64 1.2.2-6+b1 [119 kB] Get: 113 http://deb.debian.org/debian unstable/main arm64 devscripts all 2.24.7 [1081 kB] Get: 114 http://deb.debian.org/debian unstable/main arm64 dh-exec arm64 0.30+b1 [25.8 kB] Get: 115 http://deb.debian.org/debian unstable/main arm64 python3-autocommand all 2.2.2-3 [13.6 kB] Get: 116 http://deb.debian.org/debian unstable/main arm64 python3-more-itertools all 10.5.0-1 [63.8 kB] Get: 117 http://deb.debian.org/debian unstable/main arm64 python3-typing-extensions all 4.12.2-2 [73.0 kB] Get: 118 http://deb.debian.org/debian unstable/main arm64 python3-zipp all 3.21.0-1 [10.6 kB] Get: 119 http://deb.debian.org/debian unstable/main arm64 python3-importlib-metadata all 8.5.0-1 [21.0 kB] Get: 120 http://deb.debian.org/debian unstable/main arm64 python3-typeguard all 4.4.1-1 [37.0 kB] Get: 121 http://deb.debian.org/debian unstable/main arm64 python3-inflect all 7.3.1-2 [32.4 kB] Get: 122 http://deb.debian.org/debian unstable/main arm64 python3-jaraco.context all 6.0.0-1 [7984 B] Get: 123 http://deb.debian.org/debian unstable/main arm64 python3-jaraco.functools all 4.1.0-1 [12.0 kB] Get: 124 http://deb.debian.org/debian unstable/main arm64 python3-pkg-resources all 75.2.0-1 [213 kB] Get: 125 http://deb.debian.org/debian unstable/main arm64 python3-jaraco.text all 4.0.0-1 [11.4 kB] Get: 126 http://deb.debian.org/debian unstable/main arm64 python3-setuptools all 75.2.0-1 [731 kB] Get: 127 http://deb.debian.org/debian unstable/main arm64 dh-python all 6.20241024 [109 kB] Get: 128 http://deb.debian.org/debian unstable/main arm64 diffstat arm64 1.67-1 [32.6 kB] Get: 129 http://deb.debian.org/debian unstable/main arm64 distro-info-data all 0.63 [6408 B] Get: 130 http://deb.debian.org/debian unstable/main arm64 distro-info arm64 1.12 [18.4 kB] Get: 131 http://deb.debian.org/debian unstable/main arm64 python3-chardet all 5.2.0+dfsg-1 [107 kB] Get: 132 http://deb.debian.org/debian unstable/main arm64 python3-debian all 0.1.49 [115 kB] Get: 133 http://deb.debian.org/debian unstable/main arm64 libgpgme11t64 arm64 1.24.0-2 [328 kB] Get: 134 http://deb.debian.org/debian unstable/main arm64 python3-gpg arm64 1.24.0-2 [424 kB] Get: 135 http://deb.debian.org/debian unstable/main arm64 python3-xdg all 0.28-2 [40.5 kB] Get: 136 http://deb.debian.org/debian unstable/main arm64 dput all 1.2.4 [45.2 kB] Get: 137 http://deb.debian.org/debian unstable/main arm64 ed arm64 1.20.2-2+b1 [59.8 kB] Get: 138 http://deb.debian.org/debian unstable/main arm64 libbrotli1 arm64 1.1.0-2+b6 [297 kB] Get: 139 http://deb.debian.org/debian unstable/main arm64 libnghttp2-14 arm64 1.64.0-1 [71.3 kB] Get: 140 http://deb.debian.org/debian unstable/main arm64 libnghttp3-9 arm64 1.6.0-2 [60.5 kB] Get: 141 http://deb.debian.org/debian unstable/main arm64 libngtcp2-16 arm64 1.9.1-1 [109 kB] Get: 142 http://deb.debian.org/debian unstable/main arm64 libngtcp2-crypto-gnutls8 arm64 1.9.1-1 [17.3 kB] Get: 143 http://deb.debian.org/debian unstable/main arm64 libpsl5t64 arm64 0.21.2-1.1+b1 [57.1 kB] Get: 144 http://deb.debian.org/debian unstable/main arm64 librtmp1 arm64 2.4+20151223.gitfa8646d.1-2+b5 [56.8 kB] Get: 145 http://deb.debian.org/debian unstable/main arm64 libssh2-1t64 arm64 1.11.1-1 [235 kB] Get: 146 http://deb.debian.org/debian unstable/main arm64 libcurl3t64-gnutls arm64 8.11.1-1 [332 kB] Get: 147 http://deb.debian.org/debian unstable/main arm64 liberror-perl all 0.17029-2 [29.0 kB] Get: 148 http://deb.debian.org/debian unstable/main arm64 git-man all 1:2.45.2-1.2 [2159 kB] Get: 149 http://deb.debian.org/debian unstable/main arm64 git arm64 1:2.45.2-1.2 [8555 kB] Get: 150 http://deb.debian.org/debian unstable/main arm64 python3-dateutil all 2.9.0-3 [79.3 kB] Get: 151 http://deb.debian.org/debian unstable/main arm64 libyaml-0-2 arm64 0.2.5-1+b2 [49.3 kB] Get: 152 http://deb.debian.org/debian unstable/main arm64 python3-yaml arm64 6.0.2-1+b1 [148 kB] Get: 153 http://deb.debian.org/debian unstable/main arm64 git-buildpackage all 0.9.35 [812 kB] Get: 154 http://deb.debian.org/debian unstable/main arm64 libarchive13t64 arm64 3.7.4-1.1 [323 kB] Get: 155 http://deb.debian.org/debian unstable/main arm64 libhttp-parser2.9 arm64 2.9.4-6+b2 [20.2 kB] Get: 156 http://deb.debian.org/debian unstable/main arm64 libmbedcrypto16 arm64 3.6.2-3 [341 kB] Get: 157 http://deb.debian.org/debian unstable/main arm64 libmbedx509-7 arm64 3.6.2-3 [146 kB] Get: 158 http://deb.debian.org/debian unstable/main arm64 libmbedtls21 arm64 3.6.2-3 [222 kB] Get: 159 http://deb.debian.org/debian unstable/main arm64 libgit2-1.8 arm64 1.8.4+ds-3 [496 kB] Get: 160 http://deb.debian.org/debian unstable/main arm64 libglib2.0-0t64 arm64 2.82.4-1 [1411 kB] Get: 161 http://deb.debian.org/debian unstable/main arm64 libnorm1t64 arm64 1.5.9+dfsg-3.1+b1 [205 kB] Get: 162 http://deb.debian.org/debian unstable/main arm64 libpgm-5.3-0t64 arm64 5.3.128~dfsg-2.1+b1 [152 kB] Get: 163 http://deb.debian.org/debian unstable/main arm64 libsodium23 arm64 1.0.18-1+b2 [121 kB] Get: 164 http://deb.debian.org/debian unstable/main arm64 libsys-cpuaffinity-perl arm64 1.13~03-2+b4 [32.4 kB] Get: 165 http://deb.debian.org/debian unstable/main arm64 libxdelta2t64 arm64 1.1.3-10.7 [46.8 kB] Get: 166 http://deb.debian.org/debian unstable/main arm64 libzmq5 arm64 4.3.5-1+b3 [253 kB] Get: 167 http://deb.debian.org/debian unstable/main arm64 lsb-release all 12.1-1 [5912 B] Get: 168 http://deb.debian.org/debian unstable/main arm64 pbzip2 arm64 1.1.13-1+b1 [41.4 kB] Get: 169 http://deb.debian.org/debian unstable/main arm64 pixz arm64 1.0.7-3+b1 [20.3 kB] Get: 170 http://deb.debian.org/debian unstable/main arm64 xdelta arm64 1.1.3-10.7 [25.5 kB] Get: 171 http://deb.debian.org/debian unstable/main arm64 xdelta3 arm64 3.0.11-dfsg-1.2+b1 [67.3 kB] Get: 172 http://deb.debian.org/debian unstable/main arm64 pristine-tar arm64 1.50+nmu2+b1 [104 kB] Get: 173 http://deb.debian.org/debian unstable/main arm64 python-apt-common all 2.9.2 [67.8 kB] Get: 174 http://deb.debian.org/debian unstable/main arm64 python3-apt arm64 2.9.2 [176 kB] Get: 175 http://deb.debian.org/debian unstable/main arm64 python3-bcrypt arm64 4.2.0-2.1 [212 kB] Get: 176 http://deb.debian.org/debian unstable/main arm64 python3-blinker all 1.9.0-1 [12.6 kB] Get: 177 http://deb.debian.org/debian unstable/main arm64 python3-cachetools all 5.3.3-1 [13.2 kB] Get: 178 http://deb.debian.org/debian unstable/main arm64 python3-certifi all 2024.8.30+dfsg-1 [9576 B] Get: 179 http://deb.debian.org/debian unstable/main arm64 python3-cffi-backend arm64 1.17.1-2+b1 [94.8 kB] Get: 180 http://deb.debian.org/debian unstable/main arm64 python3-charset-normalizer arm64 3.4.0-1+b1 [129 kB] Get: 181 http://deb.debian.org/debian unstable/main arm64 python3-cryptography arm64 43.0.0-1 [835 kB] Get: 182 http://deb.debian.org/debian unstable/main arm64 python3-debianbts all 4.1.1 [12.4 kB] Get: 183 http://deb.debian.org/debian unstable/main arm64 python3-distro all 1.9.0-1 [20.3 kB] Get: 184 http://deb.debian.org/debian unstable/main arm64 python3-distro-info all 1.12 [7688 B] Get: 185 http://deb.debian.org/debian unstable/main arm64 python3-pyparsing all 3.1.2-1 [146 kB] Get: 186 http://deb.debian.org/debian unstable/main arm64 python3-httplib2 all 0.22.0-1 [36.1 kB] Get: 187 http://deb.debian.org/debian unstable/main arm64 python3-idna all 3.8-2 [41.6 kB] Get: 188 http://deb.debian.org/debian unstable/main arm64 python3-iniconfig all 1.1.1-2 [6396 B] Get: 189 http://deb.debian.org/debian unstable/main arm64 python3-jaraco.classes all 3.4.0-1 [7728 B] Get: 190 http://deb.debian.org/debian unstable/main arm64 python3-jeepney all 0.8.0-4 [32.6 kB] Get: 191 http://deb.debian.org/debian unstable/main arm64 python3-jwt all 2.7.0-1 [29.7 kB] Get: 192 http://deb.debian.org/debian unstable/main arm64 python3-secretstorage all 3.3.3-3 [16.1 kB] Get: 193 http://deb.debian.org/debian unstable/main arm64 python3-keyring all 25.4.1-1 [54.6 kB] Get: 194 http://deb.debian.org/debian unstable/main arm64 python3-pycryptodome arm64 3.20.0+dfsg-3 [1073 kB] Get: 195 http://deb.debian.org/debian unstable/main arm64 python3-keyrings.alt all 5.0.2-1 [17.7 kB] Get: 196 http://deb.debian.org/debian unstable/main arm64 python3-lazr.uri all 1.0.6-4 [13.8 kB] Get: 197 http://deb.debian.org/debian unstable/main arm64 python3-wadllib all 2.0.0-1 [37.9 kB] Get: 198 http://deb.debian.org/debian unstable/main arm64 python3-oauthlib all 3.2.2-2 [95.5 kB] Get: 199 http://deb.debian.org/debian unstable/main arm64 python3-lazr.restfulclient all 0.14.6-2 [50.7 kB] Get: 200 http://deb.debian.org/debian unstable/main arm64 python3-launchpadlib all 2.0.0-1 [136 kB] Get: 201 http://deb.debian.org/debian unstable/main arm64 python3-launchpadlib-desktop all 2.0.0-1 [8684 B] Get: 202 http://deb.debian.org/debian unstable/main arm64 python3-packaging all 24.2-1 [55.3 kB] Get: 203 http://deb.debian.org/debian unstable/main arm64 python3-pluggy all 1.5.0-1 [26.9 kB] Get: 204 http://deb.debian.org/debian unstable/main arm64 python3-pygit2 arm64 1.16.0-2 [183 kB] Get: 205 http://deb.debian.org/debian unstable/main arm64 python3-pytest all 8.3.4-1 [250 kB] Get: 206 http://deb.debian.org/debian unstable/main arm64 python3-urllib3 all 2.2.3-4 [112 kB] Get: 207 http://deb.debian.org/debian unstable/main arm64 python3-requests all 2.32.3+dfsg-1 [71.9 kB] Get: 208 http://deb.debian.org/debian unstable/main arm64 python3-systemd arm64 235-1+b6 [42.2 kB] Get: 209 http://deb.debian.org/debian unstable/main arm64 python3-tenacity all 8.4.2+really8.4.1-1 [46.0 kB] Get: 210 http://deb.debian.org/debian unstable/main arm64 python3-ubuntutools all 0.203 [66.6 kB] Get: 211 http://deb.debian.org/debian unstable/main arm64 python3-zmq arm64 26.2.0-1 [193 kB] Get: 212 http://deb.debian.org/debian unstable/main arm64 quilt all 0.68-1 [437 kB] Get: 213 http://deb.debian.org/debian unstable/main arm64 ubuntu-dev-tools all 0.203 [101 kB] Get: 214 http://deb.debian.org/debian unstable/main arm64 ubuntu-keyring all 2023.11.28.1-0.2 [14.1 kB] Fetched 61.0 MB in 1s (101 MB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package libpython3.12-minimal:arm64. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 20085 files and directories currently installed.) Preparing to unpack .../libpython3.12-minimal_3.12.8-3_arm64.deb ... Unpacking libpython3.12-minimal:arm64 (3.12.8-3) ... Selecting previously unselected package libexpat1:arm64. Preparing to unpack .../libexpat1_2.6.4-1_arm64.deb ... Unpacking libexpat1:arm64 (2.6.4-1) ... Selecting previously unselected package python3.12-minimal. Preparing to unpack .../python3.12-minimal_3.12.8-3_arm64.deb ... Unpacking python3.12-minimal (3.12.8-3) ... Setting up libpython3.12-minimal:arm64 (3.12.8-3) ... Setting up libexpat1:arm64 (2.6.4-1) ... Setting up python3.12-minimal (3.12.8-3) ... Selecting previously unselected package python3-minimal. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 20405 files and directories currently installed.) Preparing to unpack .../00-python3-minimal_3.12.7-1_arm64.deb ... Unpacking python3-minimal (3.12.7-1) ... Selecting previously unselected package media-types. Preparing to unpack .../01-media-types_10.1.0_all.deb ... Unpacking media-types (10.1.0) ... Selecting previously unselected package netbase. Preparing to unpack .../02-netbase_6.4_all.deb ... Unpacking netbase (6.4) ... Selecting previously unselected package tzdata. Preparing to unpack .../03-tzdata_2024b-4_all.deb ... Unpacking tzdata (2024b-4) ... Selecting previously unselected package libkrb5support0:arm64. Preparing to unpack .../04-libkrb5support0_1.21.3-3_arm64.deb ... Unpacking libkrb5support0:arm64 (1.21.3-3) ... Selecting previously unselected package libcom-err2:arm64. Preparing to unpack .../05-libcom-err2_1.47.2~rc1-2_arm64.deb ... Unpacking libcom-err2:arm64 (1.47.2~rc1-2) ... Selecting previously unselected package libk5crypto3:arm64. Preparing to unpack .../06-libk5crypto3_1.21.3-3_arm64.deb ... Unpacking libk5crypto3:arm64 (1.21.3-3) ... Selecting previously unselected package libkeyutils1:arm64. Preparing to unpack .../07-libkeyutils1_1.6.3-4_arm64.deb ... Unpacking libkeyutils1:arm64 (1.6.3-4) ... Selecting previously unselected package libkrb5-3:arm64. Preparing to unpack .../08-libkrb5-3_1.21.3-3_arm64.deb ... Unpacking libkrb5-3:arm64 (1.21.3-3) ... Selecting previously unselected package libgssapi-krb5-2:arm64. Preparing to unpack .../09-libgssapi-krb5-2_1.21.3-3_arm64.deb ... Unpacking libgssapi-krb5-2:arm64 (1.21.3-3) ... Selecting previously unselected package libtirpc-common. Preparing to unpack .../10-libtirpc-common_1.3.4+ds-1.3_all.deb ... Unpacking libtirpc-common (1.3.4+ds-1.3) ... Selecting previously unselected package libtirpc3t64:arm64. Preparing to unpack .../11-libtirpc3t64_1.3.4+ds-1.3+b1_arm64.deb ... Adding 'diversion of /lib/aarch64-linux-gnu/libtirpc.so.3 to /lib/aarch64-linux-gnu/libtirpc.so.3.usr-is-merged by libtirpc3t64' Adding 'diversion of /lib/aarch64-linux-gnu/libtirpc.so.3.0.0 to /lib/aarch64-linux-gnu/libtirpc.so.3.0.0.usr-is-merged by libtirpc3t64' Unpacking libtirpc3t64:arm64 (1.3.4+ds-1.3+b1) ... Selecting previously unselected package libnsl2:arm64. Preparing to unpack .../12-libnsl2_1.3.0-3+b3_arm64.deb ... Unpacking libnsl2:arm64 (1.3.0-3+b3) ... Selecting previously unselected package readline-common. Preparing to unpack .../13-readline-common_8.2-6_all.deb ... Unpacking readline-common (8.2-6) ... Selecting previously unselected package libreadline8t64:arm64. Preparing to unpack .../14-libreadline8t64_8.2-6_arm64.deb ... Adding 'diversion of /lib/aarch64-linux-gnu/libhistory.so.8 to /lib/aarch64-linux-gnu/libhistory.so.8.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/aarch64-linux-gnu/libhistory.so.8.2 to /lib/aarch64-linux-gnu/libhistory.so.8.2.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/aarch64-linux-gnu/libreadline.so.8 to /lib/aarch64-linux-gnu/libreadline.so.8.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/aarch64-linux-gnu/libreadline.so.8.2 to /lib/aarch64-linux-gnu/libreadline.so.8.2.usr-is-merged by libreadline8t64' Unpacking libreadline8t64:arm64 (8.2-6) ... Selecting previously unselected package libpython3.12-stdlib:arm64. Preparing to unpack .../15-libpython3.12-stdlib_3.12.8-3_arm64.deb ... Unpacking libpython3.12-stdlib:arm64 (3.12.8-3) ... Selecting previously unselected package python3.12. Preparing to unpack .../16-python3.12_3.12.8-3_arm64.deb ... Unpacking python3.12 (3.12.8-3) ... Selecting previously unselected package libpython3-stdlib:arm64. Preparing to unpack .../17-libpython3-stdlib_3.12.7-1_arm64.deb ... Unpacking libpython3-stdlib:arm64 (3.12.7-1) ... Setting up python3-minimal (3.12.7-1) ... Selecting previously unselected package python3. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 21468 files and directories currently installed.) Preparing to unpack .../000-python3_3.12.7-1_arm64.deb ... Unpacking python3 (3.12.7-1) ... Selecting previously unselected package libapparmor1:arm64. Preparing to unpack .../001-libapparmor1_3.1.7-1+b3_arm64.deb ... Unpacking libapparmor1:arm64 (3.1.7-1+b3) ... Selecting previously unselected package sudo. Preparing to unpack .../002-sudo_1.9.16p1-1_arm64.deb ... Unpacking sudo (1.9.16p1-1) ... Selecting previously unselected package sensible-utils. Preparing to unpack .../003-sensible-utils_0.0.24_all.deb ... Unpacking sensible-utils (0.0.24) ... Selecting previously unselected package bash-completion. Preparing to unpack .../004-bash-completion_1%3a2.14.0-2_all.deb ... Unpacking bash-completion (1:2.14.0-2) ... Selecting previously unselected package openssl. Preparing to unpack .../005-openssl_3.3.2-2_arm64.deb ... Unpacking openssl (3.3.2-2) ... Selecting previously unselected package ca-certificates. Preparing to unpack .../006-ca-certificates_20240203_all.deb ... Unpacking ca-certificates (20240203) ... Selecting previously unselected package libmagic-mgc. Preparing to unpack .../007-libmagic-mgc_1%3a5.45-3+b1_arm64.deb ... Unpacking libmagic-mgc (1:5.45-3+b1) ... Selecting previously unselected package libmagic1t64:arm64. Preparing to unpack .../008-libmagic1t64_1%3a5.45-3+b1_arm64.deb ... Unpacking libmagic1t64:arm64 (1:5.45-3+b1) ... Selecting previously unselected package file. Preparing to unpack .../009-file_1%3a5.45-3+b1_arm64.deb ... Unpacking file (1:5.45-3+b1) ... Selecting previously unselected package gettext-base. Preparing to unpack .../010-gettext-base_0.22.5-3_arm64.deb ... Unpacking gettext-base (0.22.5-3) ... Selecting previously unselected package libuchardet0:arm64. Preparing to unpack .../011-libuchardet0_0.0.8-1+b2_arm64.deb ... Unpacking libuchardet0:arm64 (0.0.8-1+b2) ... Selecting previously unselected package groff-base. Preparing to unpack .../012-groff-base_1.23.0-6_arm64.deb ... Unpacking groff-base (1.23.0-6) ... Selecting previously unselected package bsdextrautils. Preparing to unpack .../013-bsdextrautils_2.40.2-12_arm64.deb ... Unpacking bsdextrautils (2.40.2-12) ... Selecting previously unselected package libpipeline1:arm64. Preparing to unpack .../014-libpipeline1_1.5.8-1_arm64.deb ... Unpacking libpipeline1:arm64 (1.5.8-1) ... Selecting previously unselected package man-db. Preparing to unpack .../015-man-db_2.13.0-1_arm64.deb ... Unpacking man-db (2.13.0-1) ... Selecting previously unselected package m4. Preparing to unpack .../016-m4_1.4.19-4_arm64.deb ... Unpacking m4 (1.4.19-4) ... Selecting previously unselected package autoconf. Preparing to unpack .../017-autoconf_2.72-3_all.deb ... Unpacking autoconf (2.72-3) ... Selecting previously unselected package autotools-dev. Preparing to unpack .../018-autotools-dev_20220109.1_all.deb ... Unpacking autotools-dev (20220109.1) ... Selecting previously unselected package automake. Preparing to unpack .../019-automake_1%3a1.16.5-1.3_all.deb ... Unpacking automake (1:1.16.5-1.3) ... Selecting previously unselected package autopoint. Preparing to unpack .../020-autopoint_0.22.5-3_all.deb ... Unpacking autopoint (0.22.5-3) ... Selecting previously unselected package dctrl-tools. Preparing to unpack .../021-dctrl-tools_2.24-3+b1_arm64.deb ... Unpacking dctrl-tools (2.24-3+b1) ... Selecting previously unselected package libdebhelper-perl. Preparing to unpack .../022-libdebhelper-perl_13.21_all.deb ... Unpacking libdebhelper-perl (13.21) ... Selecting previously unselected package libtool. Preparing to unpack .../023-libtool_2.4.7-8_all.deb ... Unpacking libtool (2.4.7-8) ... Selecting previously unselected package dh-autoreconf. Preparing to unpack .../024-dh-autoreconf_20_all.deb ... Unpacking dh-autoreconf (20) ... Selecting previously unselected package libarchive-zip-perl. Preparing to unpack .../025-libarchive-zip-perl_1.68-1_all.deb ... Unpacking libarchive-zip-perl (1.68-1) ... Selecting previously unselected package libfile-stripnondeterminism-perl. Preparing to unpack .../026-libfile-stripnondeterminism-perl_1.14.0-1_all.deb ... Unpacking libfile-stripnondeterminism-perl (1.14.0-1) ... Selecting previously unselected package dh-strip-nondeterminism. Preparing to unpack .../027-dh-strip-nondeterminism_1.14.0-1_all.deb ... Unpacking dh-strip-nondeterminism (1.14.0-1) ... Selecting previously unselected package libelf1t64:arm64. Preparing to unpack .../028-libelf1t64_0.192-4_arm64.deb ... Unpacking libelf1t64:arm64 (0.192-4) ... Selecting previously unselected package dwz. Preparing to unpack .../029-dwz_0.15-1+b1_arm64.deb ... Unpacking dwz (0.15-1+b1) ... Selecting previously unselected package libicu72:arm64. Preparing to unpack .../030-libicu72_72.1-5+b1_arm64.deb ... Unpacking libicu72:arm64 (72.1-5+b1) ... Selecting previously unselected package libxml2:arm64. Preparing to unpack .../031-libxml2_2.12.7+dfsg+really2.9.14-0.2+b1_arm64.deb ... Unpacking libxml2:arm64 (2.12.7+dfsg+really2.9.14-0.2+b1) ... Selecting previously unselected package gettext. Preparing to unpack .../032-gettext_0.22.5-3_arm64.deb ... Unpacking gettext (0.22.5-3) ... Selecting previously unselected package intltool-debian. Preparing to unpack .../033-intltool-debian_0.35.0+20060710.6_all.deb ... Unpacking intltool-debian (0.35.0+20060710.6) ... Selecting previously unselected package po-debconf. Preparing to unpack .../034-po-debconf_1.0.21+nmu1_all.deb ... Unpacking po-debconf (1.0.21+nmu1) ... Selecting previously unselected package debhelper. Preparing to unpack .../035-debhelper_13.21_all.deb ... Unpacking debhelper (13.21) ... Selecting previously unselected package libassuan9:arm64. Preparing to unpack .../036-libassuan9_3.0.1-2_arm64.deb ... Unpacking libassuan9:arm64 (3.0.1-2) ... Selecting previously unselected package gpgconf. Preparing to unpack .../037-gpgconf_2.2.45-2_arm64.deb ... Unpacking gpgconf (2.2.45-2) ... Selecting previously unselected package libksba8:arm64. Preparing to unpack .../038-libksba8_1.6.7-2+b1_arm64.deb ... Unpacking libksba8:arm64 (1.6.7-2+b1) ... Selecting previously unselected package libsasl2-modules-db:arm64. Preparing to unpack .../039-libsasl2-modules-db_2.1.28+dfsg1-8_arm64.deb ... Unpacking libsasl2-modules-db:arm64 (2.1.28+dfsg1-8) ... Selecting previously unselected package libsasl2-2:arm64. Preparing to unpack .../040-libsasl2-2_2.1.28+dfsg1-8_arm64.deb ... Unpacking libsasl2-2:arm64 (2.1.28+dfsg1-8) ... Selecting previously unselected package libldap-2.5-0:arm64. Preparing to unpack .../041-libldap-2.5-0_2.5.18+dfsg-3+b1_arm64.deb ... Unpacking libldap-2.5-0:arm64 (2.5.18+dfsg-3+b1) ... Selecting previously unselected package libnpth0t64:arm64. Preparing to unpack .../042-libnpth0t64_1.8-2_arm64.deb ... Unpacking libnpth0t64:arm64 (1.8-2) ... Selecting previously unselected package dirmngr. Preparing to unpack .../043-dirmngr_2.2.45-2_arm64.deb ... Unpacking dirmngr (2.2.45-2) ... Selecting previously unselected package gnupg-l10n. Preparing to unpack .../044-gnupg-l10n_2.2.45-2_all.deb ... Unpacking gnupg-l10n (2.2.45-2) ... Selecting previously unselected package gpg. Preparing to unpack .../045-gpg_2.2.45-2_arm64.deb ... Unpacking gpg (2.2.45-2) ... Selecting previously unselected package pinentry-curses. Preparing to unpack .../046-pinentry-curses_1.2.1-4+b1_arm64.deb ... Unpacking pinentry-curses (1.2.1-4+b1) ... Selecting previously unselected package gpg-agent. Preparing to unpack .../047-gpg-agent_2.2.45-2_arm64.deb ... Unpacking gpg-agent (2.2.45-2) ... Selecting previously unselected package gpgsm. Preparing to unpack .../048-gpgsm_2.2.45-2_arm64.deb ... Unpacking gpgsm (2.2.45-2) ... Selecting previously unselected package gnupg. Preparing to unpack .../049-gnupg_2.2.45-2_all.deb ... Unpacking gnupg (2.2.45-2) ... Selecting previously unselected package libfile-dirlist-perl. Preparing to unpack .../050-libfile-dirlist-perl_0.05-3_all.deb ... Unpacking libfile-dirlist-perl (0.05-3) ... Selecting previously unselected package libfile-which-perl. Preparing to unpack .../051-libfile-which-perl_1.27-2_all.deb ... Unpacking libfile-which-perl (1.27-2) ... Selecting previously unselected package libfile-homedir-perl. Preparing to unpack .../052-libfile-homedir-perl_1.006-2_all.deb ... Unpacking libfile-homedir-perl (1.006-2) ... Selecting previously unselected package libfile-touch-perl. Preparing to unpack .../053-libfile-touch-perl_0.12-2_all.deb ... Unpacking libfile-touch-perl (0.12-2) ... Selecting previously unselected package libio-pty-perl. Preparing to unpack .../054-libio-pty-perl_1%3a1.20-1+b2_arm64.deb ... Unpacking libio-pty-perl (1:1.20-1+b2) ... Selecting previously unselected package libipc-run-perl. Preparing to unpack .../055-libipc-run-perl_20231003.0-2_all.deb ... Unpacking libipc-run-perl (20231003.0-2) ... Selecting previously unselected package libclass-method-modifiers-perl. Preparing to unpack .../056-libclass-method-modifiers-perl_2.15-1_all.deb ... Unpacking libclass-method-modifiers-perl (2.15-1) ... Selecting previously unselected package libclass-xsaccessor-perl. Preparing to unpack .../057-libclass-xsaccessor-perl_1.19-4+b4_arm64.deb ... Unpacking libclass-xsaccessor-perl (1.19-4+b4) ... Selecting previously unselected package libb-hooks-op-check-perl:arm64. Preparing to unpack .../058-libb-hooks-op-check-perl_0.22-3+b2_arm64.deb ... Unpacking libb-hooks-op-check-perl:arm64 (0.22-3+b2) ... Selecting previously unselected package libdynaloader-functions-perl. Preparing to unpack .../059-libdynaloader-functions-perl_0.004-1_all.deb ... Unpacking libdynaloader-functions-perl (0.004-1) ... Selecting previously unselected package libdevel-callchecker-perl:arm64. Preparing to unpack .../060-libdevel-callchecker-perl_0.009-1+b1_arm64.deb ... Unpacking libdevel-callchecker-perl:arm64 (0.009-1+b1) ... Selecting previously unselected package libparams-classify-perl:arm64. Preparing to unpack .../061-libparams-classify-perl_0.015-2+b4_arm64.deb ... Unpacking libparams-classify-perl:arm64 (0.015-2+b4) ... Selecting previously unselected package libmodule-runtime-perl. Preparing to unpack .../062-libmodule-runtime-perl_0.016-2_all.deb ... Unpacking libmodule-runtime-perl (0.016-2) ... Selecting previously unselected package libimport-into-perl. Preparing to unpack .../063-libimport-into-perl_1.002005-2_all.deb ... Unpacking libimport-into-perl (1.002005-2) ... Selecting previously unselected package librole-tiny-perl. Preparing to unpack .../064-librole-tiny-perl_2.002004-1_all.deb ... Unpacking librole-tiny-perl (2.002004-1) ... Selecting previously unselected package libsub-quote-perl. Preparing to unpack .../065-libsub-quote-perl_2.006008-1_all.deb ... Unpacking libsub-quote-perl (2.006008-1) ... Selecting previously unselected package libmoo-perl. Preparing to unpack .../066-libmoo-perl_2.005005-1_all.deb ... Unpacking libmoo-perl (2.005005-1) ... Selecting previously unselected package libencode-locale-perl. Preparing to unpack .../067-libencode-locale-perl_1.05-3_all.deb ... Unpacking libencode-locale-perl (1.05-3) ... Selecting previously unselected package libtimedate-perl. Preparing to unpack .../068-libtimedate-perl_2.3300-2_all.deb ... Unpacking libtimedate-perl (2.3300-2) ... Selecting previously unselected package libhttp-date-perl. Preparing to unpack .../069-libhttp-date-perl_6.06-1_all.deb ... Unpacking libhttp-date-perl (6.06-1) ... Selecting previously unselected package libfile-listing-perl. Preparing to unpack .../070-libfile-listing-perl_6.16-1_all.deb ... Unpacking libfile-listing-perl (6.16-1) ... Selecting previously unselected package libhtml-tagset-perl. Preparing to unpack .../071-libhtml-tagset-perl_3.24-1_all.deb ... Unpacking libhtml-tagset-perl (3.24-1) ... Selecting previously unselected package liburi-perl. Preparing to unpack .../072-liburi-perl_5.30-1_all.deb ... Unpacking liburi-perl (5.30-1) ... Selecting previously unselected package libhtml-parser-perl:arm64. Preparing to unpack .../073-libhtml-parser-perl_3.83-1+b1_arm64.deb ... Unpacking libhtml-parser-perl:arm64 (3.83-1+b1) ... Selecting previously unselected package libhtml-tree-perl. Preparing to unpack .../074-libhtml-tree-perl_5.07-3_all.deb ... Unpacking libhtml-tree-perl (5.07-3) ... Selecting previously unselected package libclone-perl:arm64. Preparing to unpack .../075-libclone-perl_0.47-1+b1_arm64.deb ... Unpacking libclone-perl:arm64 (0.47-1+b1) ... Selecting previously unselected package libio-html-perl. Preparing to unpack .../076-libio-html-perl_1.004-3_all.deb ... Unpacking libio-html-perl (1.004-3) ... Selecting previously unselected package liblwp-mediatypes-perl. Preparing to unpack .../077-liblwp-mediatypes-perl_6.04-2_all.deb ... Unpacking liblwp-mediatypes-perl (6.04-2) ... Selecting previously unselected package libhttp-message-perl. Preparing to unpack .../078-libhttp-message-perl_7.00-2_all.deb ... Unpacking libhttp-message-perl (7.00-2) ... Selecting previously unselected package libhttp-cookies-perl. Preparing to unpack .../079-libhttp-cookies-perl_6.11-1_all.deb ... Unpacking libhttp-cookies-perl (6.11-1) ... Selecting previously unselected package libhttp-negotiate-perl. Preparing to unpack .../080-libhttp-negotiate-perl_6.01-2_all.deb ... Unpacking libhttp-negotiate-perl (6.01-2) ... Selecting previously unselected package perl-openssl-defaults:arm64. Preparing to unpack .../081-perl-openssl-defaults_7+b2_arm64.deb ... Unpacking perl-openssl-defaults:arm64 (7+b2) ... Selecting previously unselected package libnet-ssleay-perl:arm64. Preparing to unpack .../082-libnet-ssleay-perl_1.94-2_arm64.deb ... Unpacking libnet-ssleay-perl:arm64 (1.94-2) ... Selecting previously unselected package libio-socket-ssl-perl. Preparing to unpack .../083-libio-socket-ssl-perl_2.089-1_all.deb ... Unpacking libio-socket-ssl-perl (2.089-1) ... Selecting previously unselected package libnet-http-perl. Preparing to unpack .../084-libnet-http-perl_6.23-1_all.deb ... Unpacking libnet-http-perl (6.23-1) ... Selecting previously unselected package liblwp-protocol-https-perl. Preparing to unpack .../085-liblwp-protocol-https-perl_6.14-1_all.deb ... Unpacking liblwp-protocol-https-perl (6.14-1) ... Selecting previously unselected package libtry-tiny-perl. Preparing to unpack .../086-libtry-tiny-perl_0.32-1_all.deb ... Unpacking libtry-tiny-perl (0.32-1) ... Selecting previously unselected package libwww-robotrules-perl. Preparing to unpack .../087-libwww-robotrules-perl_6.02-1_all.deb ... Unpacking libwww-robotrules-perl (6.02-1) ... Selecting previously unselected package libwww-perl. Preparing to unpack .../088-libwww-perl_6.77-1_all.deb ... Unpacking libwww-perl (6.77-1) ... Selecting previously unselected package patchutils. Preparing to unpack .../089-patchutils_0.4.2-1+b1_arm64.deb ... Unpacking patchutils (0.4.2-1+b1) ... Selecting previously unselected package wdiff. Preparing to unpack .../090-wdiff_1.2.2-6+b1_arm64.deb ... Unpacking wdiff (1.2.2-6+b1) ... Selecting previously unselected package devscripts. Preparing to unpack .../091-devscripts_2.24.7_all.deb ... Unpacking devscripts (2.24.7) ... Selecting previously unselected package dh-exec. Preparing to unpack .../092-dh-exec_0.30+b1_arm64.deb ... Unpacking dh-exec (0.30+b1) ... Selecting previously unselected package python3-autocommand. Preparing to unpack .../093-python3-autocommand_2.2.2-3_all.deb ... Unpacking python3-autocommand (2.2.2-3) ... Selecting previously unselected package python3-more-itertools. Preparing to unpack .../094-python3-more-itertools_10.5.0-1_all.deb ... Unpacking python3-more-itertools (10.5.0-1) ... Selecting previously unselected package python3-typing-extensions. Preparing to unpack .../095-python3-typing-extensions_4.12.2-2_all.deb ... Unpacking python3-typing-extensions (4.12.2-2) ... Selecting previously unselected package python3-zipp. Preparing to unpack .../096-python3-zipp_3.21.0-1_all.deb ... Unpacking python3-zipp (3.21.0-1) ... Selecting previously unselected package python3-importlib-metadata. Preparing to unpack .../097-python3-importlib-metadata_8.5.0-1_all.deb ... Unpacking python3-importlib-metadata (8.5.0-1) ... Selecting previously unselected package python3-typeguard. Preparing to unpack .../098-python3-typeguard_4.4.1-1_all.deb ... Unpacking python3-typeguard (4.4.1-1) ... Selecting previously unselected package python3-inflect. Preparing to unpack .../099-python3-inflect_7.3.1-2_all.deb ... Unpacking python3-inflect (7.3.1-2) ... Selecting previously unselected package python3-jaraco.context. Preparing to unpack .../100-python3-jaraco.context_6.0.0-1_all.deb ... Unpacking python3-jaraco.context (6.0.0-1) ... Selecting previously unselected package python3-jaraco.functools. Preparing to unpack .../101-python3-jaraco.functools_4.1.0-1_all.deb ... Unpacking python3-jaraco.functools (4.1.0-1) ... Selecting previously unselected package python3-pkg-resources. Preparing to unpack .../102-python3-pkg-resources_75.2.0-1_all.deb ... Unpacking python3-pkg-resources (75.2.0-1) ... Selecting previously unselected package python3-jaraco.text. Preparing to unpack .../103-python3-jaraco.text_4.0.0-1_all.deb ... Unpacking python3-jaraco.text (4.0.0-1) ... Selecting previously unselected package python3-setuptools. Preparing to unpack .../104-python3-setuptools_75.2.0-1_all.deb ... Unpacking python3-setuptools (75.2.0-1) ... Selecting previously unselected package dh-python. Preparing to unpack .../105-dh-python_6.20241024_all.deb ... Unpacking dh-python (6.20241024) ... Selecting previously unselected package diffstat. Preparing to unpack .../106-diffstat_1.67-1_arm64.deb ... Unpacking diffstat (1.67-1) ... Selecting previously unselected package distro-info-data. Preparing to unpack .../107-distro-info-data_0.63_all.deb ... Unpacking distro-info-data (0.63) ... Selecting previously unselected package distro-info. Preparing to unpack .../108-distro-info_1.12_arm64.deb ... Unpacking distro-info (1.12) ... Selecting previously unselected package python3-chardet. Preparing to unpack .../109-python3-chardet_5.2.0+dfsg-1_all.deb ... Unpacking python3-chardet (5.2.0+dfsg-1) ... Selecting previously unselected package python3-debian. Preparing to unpack .../110-python3-debian_0.1.49_all.deb ... Unpacking python3-debian (0.1.49) ... Selecting previously unselected package libgpgme11t64:arm64. Preparing to unpack .../111-libgpgme11t64_1.24.0-2_arm64.deb ... Unpacking libgpgme11t64:arm64 (1.24.0-2) ... Selecting previously unselected package python3-gpg. Preparing to unpack .../112-python3-gpg_1.24.0-2_arm64.deb ... Unpacking python3-gpg (1.24.0-2) ... Selecting previously unselected package python3-xdg. Preparing to unpack .../113-python3-xdg_0.28-2_all.deb ... Unpacking python3-xdg (0.28-2) ... Selecting previously unselected package dput. Preparing to unpack .../114-dput_1.2.4_all.deb ... Unpacking dput (1.2.4) ... Selecting previously unselected package ed. Preparing to unpack .../115-ed_1.20.2-2+b1_arm64.deb ... Unpacking ed (1.20.2-2+b1) ... Selecting previously unselected package libbrotli1:arm64. Preparing to unpack .../116-libbrotli1_1.1.0-2+b6_arm64.deb ... Unpacking libbrotli1:arm64 (1.1.0-2+b6) ... Selecting previously unselected package libnghttp2-14:arm64. Preparing to unpack .../117-libnghttp2-14_1.64.0-1_arm64.deb ... Unpacking libnghttp2-14:arm64 (1.64.0-1) ... Selecting previously unselected package libnghttp3-9:arm64. Preparing to unpack .../118-libnghttp3-9_1.6.0-2_arm64.deb ... Unpacking libnghttp3-9:arm64 (1.6.0-2) ... Selecting previously unselected package libngtcp2-16:arm64. Preparing to unpack .../119-libngtcp2-16_1.9.1-1_arm64.deb ... Unpacking libngtcp2-16:arm64 (1.9.1-1) ... Selecting previously unselected package libngtcp2-crypto-gnutls8:arm64. Preparing to unpack .../120-libngtcp2-crypto-gnutls8_1.9.1-1_arm64.deb ... Unpacking libngtcp2-crypto-gnutls8:arm64 (1.9.1-1) ... Selecting previously unselected package libpsl5t64:arm64. Preparing to unpack .../121-libpsl5t64_0.21.2-1.1+b1_arm64.deb ... Unpacking libpsl5t64:arm64 (0.21.2-1.1+b1) ... Selecting previously unselected package librtmp1:arm64. Preparing to unpack .../122-librtmp1_2.4+20151223.gitfa8646d.1-2+b5_arm64.deb ... Unpacking librtmp1:arm64 (2.4+20151223.gitfa8646d.1-2+b5) ... Selecting previously unselected package libssh2-1t64:arm64. Preparing to unpack .../123-libssh2-1t64_1.11.1-1_arm64.deb ... Unpacking libssh2-1t64:arm64 (1.11.1-1) ... Selecting previously unselected package libcurl3t64-gnutls:arm64. Preparing to unpack .../124-libcurl3t64-gnutls_8.11.1-1_arm64.deb ... Unpacking libcurl3t64-gnutls:arm64 (8.11.1-1) ... Selecting previously unselected package liberror-perl. Preparing to unpack .../125-liberror-perl_0.17029-2_all.deb ... Unpacking liberror-perl (0.17029-2) ... Selecting previously unselected package git-man. Preparing to unpack .../126-git-man_1%3a2.45.2-1.2_all.deb ... Unpacking git-man (1:2.45.2-1.2) ... Selecting previously unselected package git. Preparing to unpack .../127-git_1%3a2.45.2-1.2_arm64.deb ... Unpacking git (1:2.45.2-1.2) ... Selecting previously unselected package python3-dateutil. Preparing to unpack .../128-python3-dateutil_2.9.0-3_all.deb ... Unpacking python3-dateutil (2.9.0-3) ... Selecting previously unselected package libyaml-0-2:arm64. Preparing to unpack .../129-libyaml-0-2_0.2.5-1+b2_arm64.deb ... Unpacking libyaml-0-2:arm64 (0.2.5-1+b2) ... Selecting previously unselected package python3-yaml. Preparing to unpack .../130-python3-yaml_6.0.2-1+b1_arm64.deb ... Unpacking python3-yaml (6.0.2-1+b1) ... Selecting previously unselected package git-buildpackage. Preparing to unpack .../131-git-buildpackage_0.9.35_all.deb ... Unpacking git-buildpackage (0.9.35) ... Selecting previously unselected package libarchive13t64:arm64. Preparing to unpack .../132-libarchive13t64_3.7.4-1.1_arm64.deb ... Unpacking libarchive13t64:arm64 (3.7.4-1.1) ... Selecting previously unselected package libhttp-parser2.9:arm64. Preparing to unpack .../133-libhttp-parser2.9_2.9.4-6+b2_arm64.deb ... Unpacking libhttp-parser2.9:arm64 (2.9.4-6+b2) ... Selecting previously unselected package libmbedcrypto16:arm64. Preparing to unpack .../134-libmbedcrypto16_3.6.2-3_arm64.deb ... Unpacking libmbedcrypto16:arm64 (3.6.2-3) ... Selecting previously unselected package libmbedx509-7:arm64. Preparing to unpack .../135-libmbedx509-7_3.6.2-3_arm64.deb ... Unpacking libmbedx509-7:arm64 (3.6.2-3) ... Selecting previously unselected package libmbedtls21:arm64. Preparing to unpack .../136-libmbedtls21_3.6.2-3_arm64.deb ... Unpacking libmbedtls21:arm64 (3.6.2-3) ... Selecting previously unselected package libgit2-1.8:arm64. Preparing to unpack .../137-libgit2-1.8_1.8.4+ds-3_arm64.deb ... Unpacking libgit2-1.8:arm64 (1.8.4+ds-3) ... Selecting previously unselected package libglib2.0-0t64:arm64. Preparing to unpack .../138-libglib2.0-0t64_2.82.4-1_arm64.deb ... Unpacking libglib2.0-0t64:arm64 (2.82.4-1) ... Selecting previously unselected package libnorm1t64:arm64. Preparing to unpack .../139-libnorm1t64_1.5.9+dfsg-3.1+b1_arm64.deb ... Unpacking libnorm1t64:arm64 (1.5.9+dfsg-3.1+b1) ... Selecting previously unselected package libpgm-5.3-0t64:arm64. Preparing to unpack .../140-libpgm-5.3-0t64_5.3.128~dfsg-2.1+b1_arm64.deb ... Unpacking libpgm-5.3-0t64:arm64 (5.3.128~dfsg-2.1+b1) ... Selecting previously unselected package libsodium23:arm64. Preparing to unpack .../141-libsodium23_1.0.18-1+b2_arm64.deb ... Unpacking libsodium23:arm64 (1.0.18-1+b2) ... Selecting previously unselected package libsys-cpuaffinity-perl. Preparing to unpack .../142-libsys-cpuaffinity-perl_1.13~03-2+b4_arm64.deb ... Unpacking libsys-cpuaffinity-perl (1.13~03-2+b4) ... Selecting previously unselected package libxdelta2t64:arm64. Preparing to unpack .../143-libxdelta2t64_1.1.3-10.7_arm64.deb ... Unpacking libxdelta2t64:arm64 (1.1.3-10.7) ... Selecting previously unselected package libzmq5:arm64. Preparing to unpack .../144-libzmq5_4.3.5-1+b3_arm64.deb ... Unpacking libzmq5:arm64 (4.3.5-1+b3) ... Selecting previously unselected package lsb-release. Preparing to unpack .../145-lsb-release_12.1-1_all.deb ... Unpacking lsb-release (12.1-1) ... Selecting previously unselected package pbzip2. Preparing to unpack .../146-pbzip2_1.1.13-1+b1_arm64.deb ... Unpacking pbzip2 (1.1.13-1+b1) ... Selecting previously unselected package pixz. Preparing to unpack .../147-pixz_1.0.7-3+b1_arm64.deb ... Unpacking pixz (1.0.7-3+b1) ... Selecting previously unselected package xdelta. Preparing to unpack .../148-xdelta_1.1.3-10.7_arm64.deb ... Unpacking xdelta (1.1.3-10.7) ... Selecting previously unselected package xdelta3. Preparing to unpack .../149-xdelta3_3.0.11-dfsg-1.2+b1_arm64.deb ... Unpacking xdelta3 (3.0.11-dfsg-1.2+b1) ... Selecting previously unselected package pristine-tar. Preparing to unpack .../150-pristine-tar_1.50+nmu2+b1_arm64.deb ... Unpacking pristine-tar (1.50+nmu2+b1) ... Selecting previously unselected package python-apt-common. Preparing to unpack .../151-python-apt-common_2.9.2_all.deb ... Unpacking python-apt-common (2.9.2) ... Selecting previously unselected package python3-apt. Preparing to unpack .../152-python3-apt_2.9.2_arm64.deb ... Unpacking python3-apt (2.9.2) ... Selecting previously unselected package python3-bcrypt. Preparing to unpack .../153-python3-bcrypt_4.2.0-2.1_arm64.deb ... Unpacking python3-bcrypt (4.2.0-2.1) ... Selecting previously unselected package python3-blinker. Preparing to unpack .../154-python3-blinker_1.9.0-1_all.deb ... Unpacking python3-blinker (1.9.0-1) ... Selecting previously unselected package python3-cachetools. Preparing to unpack .../155-python3-cachetools_5.3.3-1_all.deb ... Unpacking python3-cachetools (5.3.3-1) ... Selecting previously unselected package python3-certifi. Preparing to unpack .../156-python3-certifi_2024.8.30+dfsg-1_all.deb ... Unpacking python3-certifi (2024.8.30+dfsg-1) ... Selecting previously unselected package python3-cffi-backend:arm64. Preparing to unpack .../157-python3-cffi-backend_1.17.1-2+b1_arm64.deb ... Unpacking python3-cffi-backend:arm64 (1.17.1-2+b1) ... Selecting previously unselected package python3-charset-normalizer. Preparing to unpack .../158-python3-charset-normalizer_3.4.0-1+b1_arm64.deb ... Unpacking python3-charset-normalizer (3.4.0-1+b1) ... Selecting previously unselected package python3-cryptography. Preparing to unpack .../159-python3-cryptography_43.0.0-1_arm64.deb ... Unpacking python3-cryptography (43.0.0-1) ... Selecting previously unselected package python3-debianbts. Preparing to unpack .../160-python3-debianbts_4.1.1_all.deb ... Unpacking python3-debianbts (4.1.1) ... Selecting previously unselected package python3-distro. Preparing to unpack .../161-python3-distro_1.9.0-1_all.deb ... Unpacking python3-distro (1.9.0-1) ... Selecting previously unselected package python3-distro-info. Preparing to unpack .../162-python3-distro-info_1.12_all.deb ... Unpacking python3-distro-info (1.12) ... Selecting previously unselected package python3-pyparsing. Preparing to unpack .../163-python3-pyparsing_3.1.2-1_all.deb ... Unpacking python3-pyparsing (3.1.2-1) ... Selecting previously unselected package python3-httplib2. Preparing to unpack .../164-python3-httplib2_0.22.0-1_all.deb ... Unpacking python3-httplib2 (0.22.0-1) ... Selecting previously unselected package python3-idna. Preparing to unpack .../165-python3-idna_3.8-2_all.deb ... Unpacking python3-idna (3.8-2) ... Selecting previously unselected package python3-iniconfig. Preparing to unpack .../166-python3-iniconfig_1.1.1-2_all.deb ... Unpacking python3-iniconfig (1.1.1-2) ... Selecting previously unselected package python3-jaraco.classes. Preparing to unpack .../167-python3-jaraco.classes_3.4.0-1_all.deb ... Unpacking python3-jaraco.classes (3.4.0-1) ... Selecting previously unselected package python3-jeepney. Preparing to unpack .../168-python3-jeepney_0.8.0-4_all.deb ... Unpacking python3-jeepney (0.8.0-4) ... Selecting previously unselected package python3-jwt. Preparing to unpack .../169-python3-jwt_2.7.0-1_all.deb ... Unpacking python3-jwt (2.7.0-1) ... Selecting previously unselected package python3-secretstorage. Preparing to unpack .../170-python3-secretstorage_3.3.3-3_all.deb ... Unpacking python3-secretstorage (3.3.3-3) ... Selecting previously unselected package python3-keyring. Preparing to unpack .../171-python3-keyring_25.4.1-1_all.deb ... Unpacking python3-keyring (25.4.1-1) ... Selecting previously unselected package python3-pycryptodome. Preparing to unpack .../172-python3-pycryptodome_3.20.0+dfsg-3_arm64.deb ... Unpacking python3-pycryptodome (3.20.0+dfsg-3) ... Selecting previously unselected package python3-keyrings.alt. Preparing to unpack .../173-python3-keyrings.alt_5.0.2-1_all.deb ... Unpacking python3-keyrings.alt (5.0.2-1) ... Selecting previously unselected package python3-lazr.uri. Preparing to unpack .../174-python3-lazr.uri_1.0.6-4_all.deb ... Unpacking python3-lazr.uri (1.0.6-4) ... Selecting previously unselected package python3-wadllib. Preparing to unpack .../175-python3-wadllib_2.0.0-1_all.deb ... Unpacking python3-wadllib (2.0.0-1) ... Selecting previously unselected package python3-oauthlib. Preparing to unpack .../176-python3-oauthlib_3.2.2-2_all.deb ... Unpacking python3-oauthlib (3.2.2-2) ... Selecting previously unselected package python3-lazr.restfulclient. Preparing to unpack .../177-python3-lazr.restfulclient_0.14.6-2_all.deb ... Unpacking python3-lazr.restfulclient (0.14.6-2) ... Selecting previously unselected package python3-launchpadlib. Preparing to unpack .../178-python3-launchpadlib_2.0.0-1_all.deb ... Unpacking python3-launchpadlib (2.0.0-1) ... Selecting previously unselected package python3-launchpadlib-desktop. Preparing to unpack .../179-python3-launchpadlib-desktop_2.0.0-1_all.deb ... Unpacking python3-launchpadlib-desktop (2.0.0-1) ... Selecting previously unselected package python3-packaging. Preparing to unpack .../180-python3-packaging_24.2-1_all.deb ... Unpacking python3-packaging (24.2-1) ... Selecting previously unselected package python3-pluggy. Preparing to unpack .../181-python3-pluggy_1.5.0-1_all.deb ... Unpacking python3-pluggy (1.5.0-1) ... Selecting previously unselected package python3-pygit2. Preparing to unpack .../182-python3-pygit2_1.16.0-2_arm64.deb ... Unpacking python3-pygit2 (1.16.0-2) ... Selecting previously unselected package python3-pytest. Preparing to unpack .../183-python3-pytest_8.3.4-1_all.deb ... Unpacking python3-pytest (8.3.4-1) ... Selecting previously unselected package python3-urllib3. Preparing to unpack .../184-python3-urllib3_2.2.3-4_all.deb ... Unpacking python3-urllib3 (2.2.3-4) ... Selecting previously unselected package python3-requests. Preparing to unpack .../185-python3-requests_2.32.3+dfsg-1_all.deb ... Unpacking python3-requests (2.32.3+dfsg-1) ... Selecting previously unselected package python3-systemd. Preparing to unpack .../186-python3-systemd_235-1+b6_arm64.deb ... Unpacking python3-systemd (235-1+b6) ... Selecting previously unselected package python3-tenacity. Preparing to unpack .../187-python3-tenacity_8.4.2+really8.4.1-1_all.deb ... Unpacking python3-tenacity (8.4.2+really8.4.1-1) ... Selecting previously unselected package python3-ubuntutools. Preparing to unpack .../188-python3-ubuntutools_0.203_all.deb ... Unpacking python3-ubuntutools (0.203) ... Selecting previously unselected package python3-zmq. Preparing to unpack .../189-python3-zmq_26.2.0-1_arm64.deb ... Unpacking python3-zmq (26.2.0-1) ... Selecting previously unselected package quilt. Preparing to unpack .../190-quilt_0.68-1_all.deb ... Unpacking quilt (0.68-1) ... Selecting previously unselected package ubuntu-dev-tools. Preparing to unpack .../191-ubuntu-dev-tools_0.203_all.deb ... Unpacking ubuntu-dev-tools (0.203) ... Selecting previously unselected package ubuntu-keyring. Preparing to unpack .../192-ubuntu-keyring_2023.11.28.1-0.2_all.deb ... Unpacking ubuntu-keyring (2023.11.28.1-0.2) ... Setting up libksba8:arm64 (1.6.7-2+b1) ... Setting up media-types (10.1.0) ... Setting up libpipeline1:arm64 (1.5.8-1) ... Setting up libnorm1t64:arm64 (1.5.9+dfsg-3.1+b1) ... Setting up wdiff (1.2.2-6+b1) ... Setting up libfile-which-perl (1.27-2) ... Setting up libnpth0t64:arm64 (1.8-2) ... Setting up libkeyutils1:arm64 (1.6.3-4) ... Setting up libapparmor1:arm64 (3.1.7-1+b3) ... Setting up libsodium23:arm64 (1.0.18-1+b2) ... Setting up libicu72:arm64 (72.1-5+b1) ... Setting up bsdextrautils (2.40.2-12) ... Setting up libsys-cpuaffinity-perl (1.13~03-2+b4) ... Setting up libdynaloader-functions-perl (0.004-1) ... Setting up libclass-method-modifiers-perl (2.15-1) ... Setting up libio-pty-perl (1:1.20-1+b2) ... Setting up libmagic-mgc (1:5.45-3+b1) ... Setting up libclone-perl:arm64 (0.47-1+b1) ... Setting up libarchive-zip-perl (1.68-1) ... Setting up libyaml-0-2:arm64 (0.2.5-1+b2) ... Setting up distro-info-data (0.63) ... Setting up libtirpc-common (1.3.4+ds-1.3) ... Setting up libhtml-tagset-perl (3.24-1) ... Setting up libdebhelper-perl (13.21) ... Setting up libbrotli1:arm64 (1.1.0-2+b6) ... Setting up liblwp-mediatypes-perl (6.04-2) ... Setting up libmagic1t64:arm64 (1:5.45-3+b1) ... Setting up libtry-tiny-perl (0.32-1) ... Setting up libpsl5t64:arm64 (0.21.2-1.1+b1) ... Setting up libnghttp2-14:arm64 (1.64.0-1) ... Setting up perl-openssl-defaults:arm64 (7+b2) ... Setting up gettext-base (0.22.5-3) ... Setting up m4 (1.4.19-4) ... Setting up libencode-locale-perl (1.05-3) ... Setting up libcom-err2:arm64 (1.47.2~rc1-2) ... Setting up file (1:5.45-3+b1) ... Setting up ubuntu-keyring (2023.11.28.1-0.2) ... Setting up pbzip2 (1.1.13-1+b1) ... Setting up libelf1t64:arm64 (0.192-4) ... Setting up libkrb5support0:arm64 (1.21.3-3) ... Setting up libsasl2-modules-db:arm64 (2.1.28+dfsg1-8) ... Setting up tzdata (2024b-4) ... Current default time zone: 'Etc/UTC' Local time is now: Tue Dec 17 08:17:39 UTC 2024. Universal Time is now: Tue Dec 17 08:17:39 UTC 2024. Run 'dpkg-reconfigure tzdata' if you wish to change it. Setting up liberror-perl (0.17029-2) ... Setting up libpgm-5.3-0t64:arm64 (5.3.128~dfsg-2.1+b1) ... Setting up autotools-dev (20220109.1) ... Setting up libglib2.0-0t64:arm64 (2.82.4-1) ... No schema files found: doing nothing. Setting up gnupg-l10n (2.2.45-2) ... Setting up ed (1.20.2-2+b1) ... Setting up librtmp1:arm64 (2.4+20151223.gitfa8646d.1-2+b5) ... Setting up bash-completion (1:2.14.0-2) ... Setting up diffstat (1.67-1) ... Setting up libio-html-perl (1.004-3) ... Setting up autopoint (0.22.5-3) ... Setting up libb-hooks-op-check-perl:arm64 (0.22-3+b2) ... Setting up sudo (1.9.16p1-1) ... invoke-rc.d: could not determine current runlevel invoke-rc.d: policy-rc.d denied execution of start. Setting up libipc-run-perl (20231003.0-2) ... Setting up libk5crypto3:arm64 (1.21.3-3) ... Setting up libsasl2-2:arm64 (2.1.28+dfsg1-8) ... Setting up autoconf (2.72-3) ... Setting up libnghttp3-9:arm64 (1.6.0-2) ... Setting up libtimedate-perl (2.3300-2) ... Setting up dwz (0.15-1+b1) ... Setting up python-apt-common (2.9.2) ... Setting up sensible-utils (0.0.24) ... Setting up xdelta3 (3.0.11-dfsg-1.2+b1) ... Setting up libuchardet0:arm64 (0.0.8-1+b2) ... Setting up libassuan9:arm64 (3.0.1-2) ... Setting up librole-tiny-perl (2.002004-1) ... Setting up git-man (1:2.45.2-1.2) ... Setting up netbase (6.4) ... Setting up libngtcp2-16:arm64 (1.9.1-1) ... Setting up libsub-quote-perl (2.006008-1) ... Setting up libclass-xsaccessor-perl (1.19-4+b4) ... Setting up libkrb5-3:arm64 (1.21.3-3) ... Setting up libmbedcrypto16:arm64 (3.6.2-3) ... Setting up libssh2-1t64:arm64 (1.11.1-1) ... Setting up libfile-dirlist-perl (0.05-3) ... Setting up lsb-release (12.1-1) ... Setting up libfile-homedir-perl (1.006-2) ... Setting up openssl (3.3.2-2) ... Setting up readline-common (8.2-6) ... Setting up libxml2:arm64 (2.12.7+dfsg+really2.9.14-0.2+b1) ... Setting up liburi-perl (5.30-1) ... Setting up libfile-touch-perl (0.12-2) ... Setting up libngtcp2-crypto-gnutls8:arm64 (1.9.1-1) ... Setting up dctrl-tools (2.24-3+b1) ... Setting up libhttp-parser2.9:arm64 (2.9.4-6+b2) ... Setting up libnet-ssleay-perl:arm64 (1.94-2) ... Setting up automake (1:1.16.5-1.3) ... update-alternatives: using /usr/bin/automake-1.16 to provide /usr/bin/automake (automake) in auto mode Setting up pinentry-curses (1.2.1-4+b1) ... Setting up libfile-stripnondeterminism-perl (1.14.0-1) ... Setting up distro-info (1.12) ... Setting up libhttp-date-perl (6.06-1) ... Setting up gettext (0.22.5-3) ... Setting up libxdelta2t64:arm64 (1.1.3-10.7) ... Setting up libfile-listing-perl (6.16-1) ... Setting up xdelta (1.1.3-10.7) ... Setting up libtool (2.4.7-8) ... Setting up libnet-http-perl (6.23-1) ... Setting up quilt (0.68-1) ... Setting up libdevel-callchecker-perl:arm64 (0.009-1+b1) ... Setting up libldap-2.5-0:arm64 (2.5.18+dfsg-3+b1) ... Setting up intltool-debian (0.35.0+20060710.6) ... Setting up dh-autoreconf (20) ... Setting up patchutils (0.4.2-1+b1) ... Setting up ca-certificates (20240203) ... Updating certificates in /etc/ssl/certs... 146 added, 0 removed; done. Setting up libmbedx509-7:arm64 (3.6.2-3) ... Setting up libgssapi-krb5-2:arm64 (1.21.3-3) ... Setting up libmbedtls21:arm64 (3.6.2-3) ... Setting up libreadline8t64:arm64 (8.2-6) ... Setting up dh-strip-nondeterminism (1.14.0-1) ... Setting up libwww-robotrules-perl (6.02-1) ... Setting up groff-base (1.23.0-6) ... Setting up libhtml-parser-perl:arm64 (3.83-1+b1) ... Setting up gpgconf (2.2.45-2) ... Setting up libarchive13t64:arm64 (3.7.4-1.1) ... Setting up libio-socket-ssl-perl (2.089-1) ... Setting up gpg (2.2.45-2) ... Setting up libhttp-message-perl (7.00-2) ... Setting up libhttp-negotiate-perl (6.01-2) ... Setting up gpg-agent (2.2.45-2) ... Setting up libzmq5:arm64 (4.3.5-1+b3) ... Setting up libtirpc3t64:arm64 (1.3.4+ds-1.3+b1) ... Setting up libhttp-cookies-perl (6.11-1) ... Setting up po-debconf (1.0.21+nmu1) ... Setting up libhtml-tree-perl (5.07-3) ... Setting up libparams-classify-perl:arm64 (0.015-2+b4) ... Setting up gpgsm (2.2.45-2) ... Setting up libcurl3t64-gnutls:arm64 (8.11.1-1) ... Setting up man-db (2.13.0-1) ... Not building database; man-db/auto-update is not 'true'. Setting up dirmngr (2.2.45-2) ... Setting up libmodule-runtime-perl (0.016-2) ... Setting up libgit2-1.8:arm64 (1.8.4+ds-3) ... Setting up git (1:2.45.2-1.2) ... Setting up libnsl2:arm64 (1.3.0-3+b3) ... Setting up pixz (1.0.7-3+b1) ... Setting up gnupg (2.2.45-2) ... Setting up libgpgme11t64:arm64 (1.24.0-2) ... Setting up pristine-tar (1.50+nmu2+b1) ... Setting up libpython3.12-stdlib:arm64 (3.12.8-3) ... Setting up libimport-into-perl (1.002005-2) ... Setting up libmoo-perl (2.005005-1) ... Setting up python3.12 (3.12.8-3) ... Setting up debhelper (13.21) ... Setting up dh-exec (0.30+b1) ... Setting up libpython3-stdlib:arm64 (3.12.7-1) ... Setting up python3 (3.12.7-1) ... Setting up python3-zipp (3.21.0-1) ... Setting up python3-xdg (0.28-2) ... Setting up python3-autocommand (2.2.2-3) ... Setting up python3-packaging (24.2-1) ... Setting up python3-pyparsing (3.1.2-1) ... Setting up python3-gpg (1.24.0-2) ... Setting up python3-certifi (2024.8.30+dfsg-1) ... Setting up python3-idna (3.8-2) ... Setting up python3-typing-extensions (4.12.2-2) ... Setting up python3-jeepney (0.8.0-4) ... Setting up python3-urllib3 (2.2.3-4) ... Setting up python3-pluggy (1.5.0-1) ... Setting up python3-httplib2 (0.22.0-1) ... Setting up python3-dateutil (2.9.0-3) ... Setting up python3-distro-info (1.12) ... Setting up python3-systemd (235-1+b6) ... Setting up python3-cffi-backend:arm64 (1.17.1-2+b1) ... Setting up python3-blinker (1.9.0-1) ... Setting up python3-more-itertools (10.5.0-1) ... Setting up python3-iniconfig (1.1.1-2) ... Setting up python3-jaraco.classes (3.4.0-1) ... Setting up python3-importlib-metadata (8.5.0-1) ... Setting up python3-jaraco.functools (4.1.0-1) ... Setting up python3-distro (1.9.0-1) ... Setting up python3-jaraco.context (6.0.0-1) ... Setting up python3-jwt (2.7.0-1) ... Setting up python3-cachetools (5.3.3-1) ... Setting up python3-debianbts (4.1.1) ... Setting up python3-apt (2.9.2) ... Setting up python3-charset-normalizer (3.4.0-1+b1) ... Setting up python3-pygit2 (1.16.0-2) ... Setting up python3-pytest (8.3.4-1) ... Setting up python3-pycryptodome (3.20.0+dfsg-3) ... Setting up python3-tenacity (8.4.2+really8.4.1-1) ... Setting up python3-bcrypt (4.2.0-2.1) ... Setting up python3-typeguard (4.4.1-1) ... Setting up python3-yaml (6.0.2-1+b1) ... Setting up python3-inflect (7.3.1-2) ... Setting up python3-jaraco.text (4.0.0-1) ... Setting up python3-zmq (26.2.0-1) ... Setting up python3-cryptography (43.0.0-1) ... Setting up python3-pkg-resources (75.2.0-1) ... Setting up python3-setuptools (75.2.0-1) ... Setting up python3-lazr.uri (1.0.6-4) ... Setting up python3-oauthlib (3.2.2-2) ... Setting up python3-chardet (5.2.0+dfsg-1) ... Setting up python3-secretstorage (3.3.3-3) ... Setting up python3-wadllib (2.0.0-1) ... Setting up python3-debian (0.1.49) ... Setting up python3-requests (2.32.3+dfsg-1) ... Setting up python3-keyring (25.4.1-1) ... Setting up python3-lazr.restfulclient (0.14.6-2) ... Setting up dh-python (6.20241024) ... Setting up python3-launchpadlib (2.0.0-1) ... Setting up dput (1.2.4) ... Setting up python3-launchpadlib-desktop (2.0.0-1) ... Setting up python3-keyrings.alt (5.0.2-1) ... Setting up python3-ubuntutools (0.203) ... Setting up libwww-perl (6.77-1) ... Setting up devscripts (2.24.7) ... Setting up git-buildpackage (0.9.35) ... Setting up liblwp-protocol-https-perl (6.14-1) ... Setting up ubuntu-dev-tools (0.203) ... Processing triggers for libc-bin (2.40-4) ... Processing triggers for ca-certificates (20240203) ... Updating certificates in /etc/ssl/certs... 0 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done. Reading package lists... Building dependency tree... Reading state information... Reading extended state information... Initializing package states... Writing extended state information... Building tag database... -> Finished parsing the build-deps I: Building the package I: Running cd /build/reproducible-path/git-ubuntu-1.1/ && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" HOME="/nonexistent/first-build" dpkg-buildpackage -us -uc -b && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" HOME="/nonexistent/first-build" dpkg-genchanges -S > ../git-ubuntu_1.1-2_source.changes dpkg-buildpackage: info: source package git-ubuntu dpkg-buildpackage: info: source version 1.1-2 dpkg-buildpackage: info: source distribution unstable dpkg-buildpackage: info: source changed by Benjamin Drung dpkg-source --before-build . dpkg-buildpackage: info: host architecture arm64 debian/rules clean dh clean --with bash-completion,python3 --buildsystem=pybuild dh_auto_clean -O--buildsystem=pybuild I: pybuild base:311: python3.12 setup.py clean running clean removing '/build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build' (and everything under it) 'build/bdist.linux-aarch64' does not exist -- can't clean it 'build/scripts-3.12' does not exist -- can't clean it dh_autoreconf_clean -O--buildsystem=pybuild dh_clean -O--buildsystem=pybuild debian/rules binary dh binary --with bash-completion,python3 --buildsystem=pybuild dh_update_autotools_config -O--buildsystem=pybuild dh_autoreconf -O--buildsystem=pybuild dh_auto_configure -O--buildsystem=pybuild I: pybuild base:311: python3.12 setup.py config running config dh_auto_build -O--buildsystem=pybuild I: pybuild base:311: /usr/bin/python3 setup.py build running build running build_py creating /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/source_builder_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/repo_builder.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/git_repository.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/integration_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/submit.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/build.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/versioning.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/version.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/test_util.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/test_fixtures.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/tag.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/spec.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/source_information_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/source_information.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/source_builder.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/scriptutils.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/run.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/rich_history_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/rich_history.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/repo_comparator.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/repo_builder_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/remote.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/queue.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/prepare_upload_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/prepare_upload.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/patch_state.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/merge.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/logging.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_tag_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_service_worker_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_service_worker.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_service_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_service_poller.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_service_ipc.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_service_broker.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer_service.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/importer.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/git_repository_test.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/exportorig.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/dsc.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/clone.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/cache.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/__main__.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/__init__.py -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu running egg_info creating gitubuntu.egg-info writing gitubuntu.egg-info/PKG-INFO writing dependency_links to gitubuntu.egg-info/dependency_links.txt writing entry points to gitubuntu.egg-info/entry_points.txt writing requirements to gitubuntu.egg-info/requires.txt writing top-level names to gitubuntu.egg-info/top_level.txt writing manifest file 'gitubuntu.egg-info/SOURCES.txt' reading manifest file 'gitubuntu.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' warning: no directories found matching 'gitubuntu/apt_repo_test' adding license file 'COPYING' adding license file 'AUTHORS' writing manifest file 'gitubuntu.egg-info/SOURCES.txt' /usr/lib/python3/dist-packages/setuptools/command/build_py.py:218: _Warning: Package 'gitubuntu.changelog_tests' is absent from the `packages` configuration. !! ******************************************************************************** ############################ # Package would be ignored # ############################ Python recognizes 'gitubuntu.changelog_tests' as an importable package[^1], but it is absent from setuptools' `packages` configuration. This leads to an ambiguous overall configuration. If you want to distribute this package, please make sure that 'gitubuntu.changelog_tests' is explicitly added to the `packages` configuration field. Alternatively, you can also rely on setuptools' discovery methods (for example by using `find_namespace_packages(...)`/`find_namespace:` instead of `find_packages(...)`/`find:`). You can read more about "package discovery" on setuptools documentation page: - https://setuptools.pypa.io/en/latest/userguide/package_discovery.html If you don't want 'gitubuntu.changelog_tests' to be distributed and are already explicitly excluding 'gitubuntu.changelog_tests' via `find_namespace_packages(...)/find_namespace` or `find_packages(...)/find`, you can try to use `exclude_package_data`, or `include-package-data=False` in combination with a more fine grained `package-data` configuration. You can read more about "package data files" on setuptools documentation page: - https://setuptools.pypa.io/en/latest/userguide/datafiles.html [^1]: For Python, any directory (with suitable naming) can be imported, even if it does not contain any `.py` files. On the other hand, currently there is no concept of package data directory, all directories are treated like packages. ******************************************************************************** !! check.warn(importable) /usr/lib/python3/dist-packages/setuptools/command/build_py.py:218: _Warning: Package 'gitubuntu.hooks' is absent from the `packages` configuration. !! ******************************************************************************** ############################ # Package would be ignored # ############################ Python recognizes 'gitubuntu.hooks' as an importable package[^1], but it is absent from setuptools' `packages` configuration. This leads to an ambiguous overall configuration. If you want to distribute this package, please make sure that 'gitubuntu.hooks' is explicitly added to the `packages` configuration field. Alternatively, you can also rely on setuptools' discovery methods (for example by using `find_namespace_packages(...)`/`find_namespace:` instead of `find_packages(...)`/`find:`). You can read more about "package discovery" on setuptools documentation page: - https://setuptools.pypa.io/en/latest/userguide/package_discovery.html If you don't want 'gitubuntu.hooks' to be distributed and are already explicitly excluding 'gitubuntu.hooks' via `find_namespace_packages(...)/find_namespace` or `find_packages(...)/find`, you can try to use `exclude_package_data`, or `include-package-data=False` in combination with a more fine grained `package-data` configuration. You can read more about "package data files" on setuptools documentation page: - https://setuptools.pypa.io/en/latest/userguide/datafiles.html [^1]: For Python, any directory (with suitable naming) can be imported, even if it does not contain any `.py` files. On the other hand, currently there is no concept of package data directory, all directories are treated like packages. ******************************************************************************** !! check.warn(importable) copying gitubuntu/changelog_date_overrides.txt -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/parent_overrides.txt -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/pull_overrides.txt -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu copying gitubuntu/source-package-denylist.txt -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu creating /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/duplicate-version-with-extra -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/maintainer_name_inner_space -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/maintainer_name_leading_space -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/maintainer_name_trailing_space -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_date_1 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_date_2 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_distribution -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_distribution_source_1 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_distribution_source_2 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_distribution_source_3 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_distribution_source_4 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_maintainer_1 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_maintainer_2 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_maintainer_3 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_multiple_angle_brackets -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_utf8_error -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_versions_1 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_versions_2 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_versions_3 -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests copying gitubuntu/changelog_tests/test_versions_unknown -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/changelog_tests creating /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/hooks copying gitubuntu/hooks/post-checkout -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/hooks copying gitubuntu/hooks/pre-commit -> /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/hooks dh_auto_test -O--buildsystem=pybuild I: pybuild base:311: cd /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build; python3.12 -m pytest ============================= test session starts ============================== platform linux -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0 rootdir: /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build configfile: pytest.ini plugins: typeguard-4.4.1 collected 407 items gitubuntu/git_repository_test.py ....................................... [ 9%] ..................................................................... [ 26%] gitubuntu/importer_service_test.py ..................................... [ 35%] ..... [ 36%] gitubuntu/importer_service_worker_test.py ... [ 37%] gitubuntu/importer_tag_test.py FFFFFFFF.x. [ 40%] gitubuntu/importer_test.py ........................................FFFFF [ 51%] FF..xx..FF........................................................... [ 68%] gitubuntu/integration_test.py ...............ssss [ 72%] gitubuntu/prepare_upload_test.py .............. [ 76%] gitubuntu/repo_builder_test.py ............................. [ 83%] gitubuntu/rich_history_test.py ........ [ 85%] gitubuntu/source_builder_test.py ..................... [ 90%] gitubuntu/source_information_test.py ................................... [ 99%] ... [100%] =================================== FAILURES =================================== _ test_import_unapplied_spi_tags[input_repo0-expected_output_refs0-validation_repo_delta0-validation_repo_expected_identical_refs0-True] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = expected_output_refs = ['refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar'] validation_repo_delta = {'update_branches': {'importer/ubuntu/trusty': }} validation_repo_expected_identical_refs = ['refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1'] reuse = True @pytest.mark.parametrize( [ 'input_repo', 'expected_output_refs', 'validation_repo_delta', 'validation_repo_expected_identical_refs', 'reuse', ], [ # 1) An existing import tag (or reimport tag) with the same Git tree # - Reuse import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='import')], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('import'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', ], # reuse: True, ), pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='import tag contents', ), Commit.from_spec(name='reimport'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 2) An existing import tag with a different Git tree and an existing # upload tag with the same Git tree # - Reuse upload tag, create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec(name='upload'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 3) An existing import tag with a different Git tree and an existing # upload tag with a different Git tree # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 4) An existing import tag with a different Git tree and no upload tag # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 5) No import tag and an existing upload tag with the same Git tree # - Reuse upload tag, create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='upload')], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/import/1-1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: True, ), # 6) No import tag and an existing upload tag with a different Git tree # - Create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: False, ), # 7) No import tags or upload tags # - Create import tag pytest.param( # input_repo: repo_builder.Repo(), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1' ], # reuse: False, ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_tags( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, expected_output_refs, validation_repo_delta, validation_repo_expected_identical_refs, reuse, ): """Test that unapplied tags are correctly created, adjusted and/or reused :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) expected_output_refs: refs that must exist in the output repository :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository :param bool reuse: if set, the output ref importer/ubuntu/trusty must be one supplied by the input repository (assumed to have a commit message of "Test commit") and not one created by the importer in this run (arranged by this test to have a different commit message) The input repository data is written into the output repository and then a fake non-native source package publication of version 1-1 in the Trusty release pocket is imported into it by calling import_unapplied_spi() directly. expected_output_refs, validation_repo_expected_identical_refs and reuse are then asserted. It is further asserted that no other refs exist in the output repository except for those listed in expected_output_refs and validation_repo_expected_identical_refs. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' # Importantly, the following commit message must not be the same as the # commit messages used by the test input repository commits, so that we can # later detect the difference between commits that were already there and # new commits created by the importer for the purposes of asserting the # reuse parameter correctly. get_import_commit_msg_mock.return_value = b'Test commit (new)' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( version='1-1', native=False, ) with source_builder.Source(publish_spec) as dsc_path: > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_tag_test.py:471: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_tags[input_repo1-expected_output_refs1-validation_repo_delta1-validation_repo_expected_identical_refs1-True] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = expected_output_refs = ['refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar'] validation_repo_delta = {'update_branches': {'importer/ubuntu/trusty': }} validation_repo_expected_identical_refs = ['refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1'] reuse = True @pytest.mark.parametrize( [ 'input_repo', 'expected_output_refs', 'validation_repo_delta', 'validation_repo_expected_identical_refs', 'reuse', ], [ # 1) An existing import tag (or reimport tag) with the same Git tree # - Reuse import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='import')], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('import'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', ], # reuse: True, ), pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='import tag contents', ), Commit.from_spec(name='reimport'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 2) An existing import tag with a different Git tree and an existing # upload tag with the same Git tree # - Reuse upload tag, create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec(name='upload'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 3) An existing import tag with a different Git tree and an existing # upload tag with a different Git tree # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 4) An existing import tag with a different Git tree and no upload tag # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 5) No import tag and an existing upload tag with the same Git tree # - Reuse upload tag, create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='upload')], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/import/1-1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: True, ), # 6) No import tag and an existing upload tag with a different Git tree # - Create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: False, ), # 7) No import tags or upload tags # - Create import tag pytest.param( # input_repo: repo_builder.Repo(), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1' ], # reuse: False, ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_tags( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, expected_output_refs, validation_repo_delta, validation_repo_expected_identical_refs, reuse, ): """Test that unapplied tags are correctly created, adjusted and/or reused :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) expected_output_refs: refs that must exist in the output repository :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository :param bool reuse: if set, the output ref importer/ubuntu/trusty must be one supplied by the input repository (assumed to have a commit message of "Test commit") and not one created by the importer in this run (arranged by this test to have a different commit message) The input repository data is written into the output repository and then a fake non-native source package publication of version 1-1 in the Trusty release pocket is imported into it by calling import_unapplied_spi() directly. expected_output_refs, validation_repo_expected_identical_refs and reuse are then asserted. It is further asserted that no other refs exist in the output repository except for those listed in expected_output_refs and validation_repo_expected_identical_refs. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' # Importantly, the following commit message must not be the same as the # commit messages used by the test input repository commits, so that we can # later detect the difference between commits that were already there and # new commits created by the importer for the purposes of asserting the # reuse parameter correctly. get_import_commit_msg_mock.return_value = b'Test commit (new)' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( version='1-1', native=False, ) with source_builder.Source(publish_spec) as dsc_path: > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_tag_test.py:471: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_tags[input_repo2-expected_output_refs2-validation_repo_delta2-validation_repo_expected_identical_refs2-True] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = expected_output_refs = ['refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer'] validation_repo_delta = {'update_branches': {'importer/ubuntu/trusty': }, 'update...t at 0xffff81e5a720>, 'importer/reimport/import/1-1/1': }} validation_repo_expected_identical_refs = ['refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1'] reuse = True @pytest.mark.parametrize( [ 'input_repo', 'expected_output_refs', 'validation_repo_delta', 'validation_repo_expected_identical_refs', 'reuse', ], [ # 1) An existing import tag (or reimport tag) with the same Git tree # - Reuse import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='import')], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('import'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', ], # reuse: True, ), pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='import tag contents', ), Commit.from_spec(name='reimport'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 2) An existing import tag with a different Git tree and an existing # upload tag with the same Git tree # - Reuse upload tag, create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec(name='upload'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 3) An existing import tag with a different Git tree and an existing # upload tag with a different Git tree # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 4) An existing import tag with a different Git tree and no upload tag # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 5) No import tag and an existing upload tag with the same Git tree # - Reuse upload tag, create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='upload')], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/import/1-1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: True, ), # 6) No import tag and an existing upload tag with a different Git tree # - Create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: False, ), # 7) No import tags or upload tags # - Create import tag pytest.param( # input_repo: repo_builder.Repo(), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1' ], # reuse: False, ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_tags( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, expected_output_refs, validation_repo_delta, validation_repo_expected_identical_refs, reuse, ): """Test that unapplied tags are correctly created, adjusted and/or reused :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) expected_output_refs: refs that must exist in the output repository :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository :param bool reuse: if set, the output ref importer/ubuntu/trusty must be one supplied by the input repository (assumed to have a commit message of "Test commit") and not one created by the importer in this run (arranged by this test to have a different commit message) The input repository data is written into the output repository and then a fake non-native source package publication of version 1-1 in the Trusty release pocket is imported into it by calling import_unapplied_spi() directly. expected_output_refs, validation_repo_expected_identical_refs and reuse are then asserted. It is further asserted that no other refs exist in the output repository except for those listed in expected_output_refs and validation_repo_expected_identical_refs. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' # Importantly, the following commit message must not be the same as the # commit messages used by the test input repository commits, so that we can # later detect the difference between commits that were already there and # new commits created by the importer for the purposes of asserting the # reuse parameter correctly. get_import_commit_msg_mock.return_value = b'Test commit (new)' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( version='1-1', native=False, ) with source_builder.Source(publish_spec) as dsc_path: > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_tag_test.py:471: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_tags[input_repo3-expected_output_refs3-validation_repo_delta3-validation_repo_expected_identical_refs3-False] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = expected_output_refs = ['refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer'] validation_repo_delta = {'add_commits': [], 'update_branches': {'importer/ubuntu/trust...t at 0xffff81e5ae40>, 'importer/reimport/import/1-1/1': }} validation_repo_expected_identical_refs = ['refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1'] reuse = False @pytest.mark.parametrize( [ 'input_repo', 'expected_output_refs', 'validation_repo_delta', 'validation_repo_expected_identical_refs', 'reuse', ], [ # 1) An existing import tag (or reimport tag) with the same Git tree # - Reuse import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='import')], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('import'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', ], # reuse: True, ), pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='import tag contents', ), Commit.from_spec(name='reimport'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 2) An existing import tag with a different Git tree and an existing # upload tag with the same Git tree # - Reuse upload tag, create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec(name='upload'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 3) An existing import tag with a different Git tree and an existing # upload tag with a different Git tree # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 4) An existing import tag with a different Git tree and no upload tag # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 5) No import tag and an existing upload tag with the same Git tree # - Reuse upload tag, create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='upload')], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/import/1-1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: True, ), # 6) No import tag and an existing upload tag with a different Git tree # - Create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: False, ), # 7) No import tags or upload tags # - Create import tag pytest.param( # input_repo: repo_builder.Repo(), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1' ], # reuse: False, ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_tags( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, expected_output_refs, validation_repo_delta, validation_repo_expected_identical_refs, reuse, ): """Test that unapplied tags are correctly created, adjusted and/or reused :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) expected_output_refs: refs that must exist in the output repository :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository :param bool reuse: if set, the output ref importer/ubuntu/trusty must be one supplied by the input repository (assumed to have a commit message of "Test commit") and not one created by the importer in this run (arranged by this test to have a different commit message) The input repository data is written into the output repository and then a fake non-native source package publication of version 1-1 in the Trusty release pocket is imported into it by calling import_unapplied_spi() directly. expected_output_refs, validation_repo_expected_identical_refs and reuse are then asserted. It is further asserted that no other refs exist in the output repository except for those listed in expected_output_refs and validation_repo_expected_identical_refs. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' # Importantly, the following commit message must not be the same as the # commit messages used by the test input repository commits, so that we can # later detect the difference between commits that were already there and # new commits created by the importer for the purposes of asserting the # reuse parameter correctly. get_import_commit_msg_mock.return_value = b'Test commit (new)' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( version='1-1', native=False, ) with source_builder.Source(publish_spec) as dsc_path: > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_tag_test.py:471: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_tags[input_repo4-expected_output_refs4-validation_repo_delta4-validation_repo_expected_identical_refs4-False] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = expected_output_refs = ['refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer'] validation_repo_delta = {'add_commits': [], 'update_branches': {'importer/ubuntu/trust...t at 0xffff81e5b320>, 'importer/reimport/import/1-1/1': }} validation_repo_expected_identical_refs = ['refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1'] reuse = False @pytest.mark.parametrize( [ 'input_repo', 'expected_output_refs', 'validation_repo_delta', 'validation_repo_expected_identical_refs', 'reuse', ], [ # 1) An existing import tag (or reimport tag) with the same Git tree # - Reuse import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='import')], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('import'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', ], # reuse: True, ), pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='import tag contents', ), Commit.from_spec(name='reimport'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 2) An existing import tag with a different Git tree and an existing # upload tag with the same Git tree # - Reuse upload tag, create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec(name='upload'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 3) An existing import tag with a different Git tree and an existing # upload tag with a different Git tree # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 4) An existing import tag with a different Git tree and no upload tag # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 5) No import tag and an existing upload tag with the same Git tree # - Reuse upload tag, create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='upload')], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/import/1-1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: True, ), # 6) No import tag and an existing upload tag with a different Git tree # - Create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: False, ), # 7) No import tags or upload tags # - Create import tag pytest.param( # input_repo: repo_builder.Repo(), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1' ], # reuse: False, ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_tags( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, expected_output_refs, validation_repo_delta, validation_repo_expected_identical_refs, reuse, ): """Test that unapplied tags are correctly created, adjusted and/or reused :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) expected_output_refs: refs that must exist in the output repository :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository :param bool reuse: if set, the output ref importer/ubuntu/trusty must be one supplied by the input repository (assumed to have a commit message of "Test commit") and not one created by the importer in this run (arranged by this test to have a different commit message) The input repository data is written into the output repository and then a fake non-native source package publication of version 1-1 in the Trusty release pocket is imported into it by calling import_unapplied_spi() directly. expected_output_refs, validation_repo_expected_identical_refs and reuse are then asserted. It is further asserted that no other refs exist in the output repository except for those listed in expected_output_refs and validation_repo_expected_identical_refs. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' # Importantly, the following commit message must not be the same as the # commit messages used by the test input repository commits, so that we can # later detect the difference between commits that were already there and # new commits created by the importer for the purposes of asserting the # reuse parameter correctly. get_import_commit_msg_mock.return_value = b'Test commit (new)' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( version='1-1', native=False, ) with source_builder.Source(publish_spec) as dsc_path: > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_tag_test.py:471: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_tags[input_repo5-expected_output_refs5-validation_repo_delta5-validation_repo_expected_identical_refs5-True] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = expected_output_refs = ['refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer'] validation_repo_delta = {'update_branches': {'importer/ubuntu/trusty': }, 'update_tags': {'importer/import/1-1': }} validation_repo_expected_identical_refs = ['refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1'] reuse = True @pytest.mark.parametrize( [ 'input_repo', 'expected_output_refs', 'validation_repo_delta', 'validation_repo_expected_identical_refs', 'reuse', ], [ # 1) An existing import tag (or reimport tag) with the same Git tree # - Reuse import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='import')], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('import'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', ], # reuse: True, ), pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='import tag contents', ), Commit.from_spec(name='reimport'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 2) An existing import tag with a different Git tree and an existing # upload tag with the same Git tree # - Reuse upload tag, create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec(name='upload'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 3) An existing import tag with a different Git tree and an existing # upload tag with a different Git tree # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 4) An existing import tag with a different Git tree and no upload tag # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 5) No import tag and an existing upload tag with the same Git tree # - Reuse upload tag, create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='upload')], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/import/1-1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: True, ), # 6) No import tag and an existing upload tag with a different Git tree # - Create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: False, ), # 7) No import tags or upload tags # - Create import tag pytest.param( # input_repo: repo_builder.Repo(), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1' ], # reuse: False, ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_tags( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, expected_output_refs, validation_repo_delta, validation_repo_expected_identical_refs, reuse, ): """Test that unapplied tags are correctly created, adjusted and/or reused :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) expected_output_refs: refs that must exist in the output repository :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository :param bool reuse: if set, the output ref importer/ubuntu/trusty must be one supplied by the input repository (assumed to have a commit message of "Test commit") and not one created by the importer in this run (arranged by this test to have a different commit message) The input repository data is written into the output repository and then a fake non-native source package publication of version 1-1 in the Trusty release pocket is imported into it by calling import_unapplied_spi() directly. expected_output_refs, validation_repo_expected_identical_refs and reuse are then asserted. It is further asserted that no other refs exist in the output repository except for those listed in expected_output_refs and validation_repo_expected_identical_refs. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' # Importantly, the following commit message must not be the same as the # commit messages used by the test input repository commits, so that we can # later detect the difference between commits that were already there and # new commits created by the importer for the purposes of asserting the # reuse parameter correctly. get_import_commit_msg_mock.return_value = b'Test commit (new)' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( version='1-1', native=False, ) with source_builder.Source(publish_spec) as dsc_path: > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_tag_test.py:471: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_tags[input_repo6-expected_output_refs6-validation_repo_delta6-validation_repo_expected_identical_refs6-False] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = expected_output_refs = ['refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer'] validation_repo_delta = {'add_commits': [], 'update_branches': {'importer/ubuntu/trust...xffff81e5bc20>}, 'update_tags': {'importer/import/1-1': }} validation_repo_expected_identical_refs = ['refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1'] reuse = False @pytest.mark.parametrize( [ 'input_repo', 'expected_output_refs', 'validation_repo_delta', 'validation_repo_expected_identical_refs', 'reuse', ], [ # 1) An existing import tag (or reimport tag) with the same Git tree # - Reuse import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='import')], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('import'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', ], # reuse: True, ), pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='import tag contents', ), Commit.from_spec(name='reimport'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 2) An existing import tag with a different Git tree and an existing # upload tag with the same Git tree # - Reuse upload tag, create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec(name='upload'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 3) An existing import tag with a different Git tree and an existing # upload tag with a different Git tree # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 4) An existing import tag with a different Git tree and no upload tag # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 5) No import tag and an existing upload tag with the same Git tree # - Reuse upload tag, create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='upload')], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/import/1-1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: True, ), # 6) No import tag and an existing upload tag with a different Git tree # - Create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: False, ), # 7) No import tags or upload tags # - Create import tag pytest.param( # input_repo: repo_builder.Repo(), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1' ], # reuse: False, ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_tags( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, expected_output_refs, validation_repo_delta, validation_repo_expected_identical_refs, reuse, ): """Test that unapplied tags are correctly created, adjusted and/or reused :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) expected_output_refs: refs that must exist in the output repository :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository :param bool reuse: if set, the output ref importer/ubuntu/trusty must be one supplied by the input repository (assumed to have a commit message of "Test commit") and not one created by the importer in this run (arranged by this test to have a different commit message) The input repository data is written into the output repository and then a fake non-native source package publication of version 1-1 in the Trusty release pocket is imported into it by calling import_unapplied_spi() directly. expected_output_refs, validation_repo_expected_identical_refs and reuse are then asserted. It is further asserted that no other refs exist in the output repository except for those listed in expected_output_refs and validation_repo_expected_identical_refs. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' # Importantly, the following commit message must not be the same as the # commit messages used by the test input repository commits, so that we can # later detect the difference between commits that were already there and # new commits created by the importer for the purposes of asserting the # reuse parameter correctly. get_import_commit_msg_mock.return_value = b'Test commit (new)' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( version='1-1', native=False, ) with source_builder.Source(publish_spec) as dsc_path: > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_tag_test.py:471: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_tags[input_repo7-expected_output_refs7-validation_repo_delta7-validation_repo_expected_identical_refs7-False] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = expected_output_refs = ['refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer'] validation_repo_delta = {'add_commits': [], 'update_branches': {'importer/ubuntu/trust...xffff81e5bf20>}, 'update_tags': {'importer/import/1-1': }} validation_repo_expected_identical_refs = ['refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1'] reuse = False @pytest.mark.parametrize( [ 'input_repo', 'expected_output_refs', 'validation_repo_delta', 'validation_repo_expected_identical_refs', 'reuse', ], [ # 1) An existing import tag (or reimport tag) with the same Git tree # - Reuse import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='import')], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('import'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', ], # reuse: True, ), pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='import tag contents', ), Commit.from_spec(name='reimport'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', ], # validation_repo_delta: { 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 2) An existing import tag with a different Git tree and an existing # upload tag with the same Git tree # - Reuse upload tag, create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec(name='upload'), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: True, ), # 3) An existing import tag with a different Git tree and an existing # upload tag with a different Git tree # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={ 'importer/import/1-1': Placeholder('import'), 'importer/upload/1-1': Placeholder('upload'), }, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 4) An existing import tag with a different Git tree and no upload tag # - Create reimport tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='import', mutate='The import tag contents', ), ], branches={ 'importer/ubuntu/trusty-proposed': Placeholder('import'), }, tags={'importer/import/1-1': Placeholder('import')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [Commit.from_spec( name='reimport', message='Test commit (new)', )], 'update_tags': { 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('reimport'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty-proposed', 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', ], # reuse: False, ), # 5) No import tag and an existing upload tag with the same Git tree # - Reuse upload tag, create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[Commit.from_spec(name='upload')], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'update_tags': { 'importer/import/1-1': Placeholder('upload'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('upload'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: True, ), # 6) No import tag and an existing upload tag with a different Git tree # - Create import tag pytest.param( # input_repo: repo_builder.Repo( commits=[ Commit.from_spec( name='upload', mutate='The upload tag contents', ), ], tags={'importer/upload/1-1': Placeholder('upload')}, ), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1', 'refs/tags/importer/upload/1-1', ], # reuse: False, ), # 7) No import tags or upload tags # - Create import tag pytest.param( # input_repo: repo_builder.Repo(), # expected_output_refs: [ 'refs/heads/do-not-push', 'refs/tags/importer/upstream/ubuntu/1.gz', 'refs/heads/importer/importer/ubuntu/dsc', 'refs/heads/importer/importer/ubuntu/pristine-tar', 'refs/notes/importer/changelog', 'refs/notes/importer/importer', ], # validation_repo_delta: { 'add_commits': [ Commit.from_spec( name='publish', message='Test commit (new)', ), ], 'update_tags': { 'importer/import/1-1': Placeholder('publish'), }, 'update_branches': { 'importer/ubuntu/trusty': Placeholder('publish'), }, }, # validation_repo_expected_identical_refs: [ 'refs/heads/importer/ubuntu/trusty', 'refs/tags/importer/import/1-1' ], # reuse: False, ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_tags( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, expected_output_refs, validation_repo_delta, validation_repo_expected_identical_refs, reuse, ): """Test that unapplied tags are correctly created, adjusted and/or reused :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) expected_output_refs: refs that must exist in the output repository :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository :param bool reuse: if set, the output ref importer/ubuntu/trusty must be one supplied by the input repository (assumed to have a commit message of "Test commit") and not one created by the importer in this run (arranged by this test to have a different commit message) The input repository data is written into the output repository and then a fake non-native source package publication of version 1-1 in the Trusty release pocket is imported into it by calling import_unapplied_spi() directly. expected_output_refs, validation_repo_expected_identical_refs and reuse are then asserted. It is further asserted that no other refs exist in the output repository except for those listed in expected_output_refs and validation_repo_expected_identical_refs. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' # Importantly, the following commit message must not be the same as the # commit messages used by the test input repository commits, so that we can # later detect the difference between commits that were already there and # new commits created by the importer for the purposes of asserting the # reuse parameter correctly. get_import_commit_msg_mock.return_value = b'Test commit (new)' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( version='1-1', native=False, ) with source_builder.Source(publish_spec) as dsc_path: > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_tag_test.py:471: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _______________________ test_import_creates_import_note ________________________ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: repo = def test_import_creates_import_note(repo): """When an import runs, the note should appear in the correct ref""" with source_builder.Source() as dsc_pathname: > target.import_unapplied_dsc( repo=repo, version='1-1', namespace='importer', dist='ubuntu', dsc_pathname=dsc_pathname, head_name='ubuntu/focal', skip_orig=True, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1102: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed ___________________ test_import_unapplied_spi_quilt_patches ____________________ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': 'db7f686c1844fb26c2b78a54bc8b7580', 'size': '612', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_quilt_patches( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, ): """Test that a package with quilt patches is imported with correct unapplied refs :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' get_import_commit_msg_mock.return_value = b'Test commit' publish_spec = source_builder.SourceSpec(has_patches=True) input_repo = repo_builder.Repo() input_repo.write(repo.raw_repo) expected_result = repo_builder.Repo( commits=[ repo_builder.Commit( tree=repo_builder.SourceTree( source_builder.Source(publish_spec) ), name='publish' ), ], tags={'importer/import/1-1': Placeholder('publish')}, branches={'importer/ubuntu/trusty': Placeholder('publish')}, ) with source_builder.Source(publish_spec) as dsc_path: # import_unapplied_spi currently assumes it is called from the # repository directory (pristine-tar and other commands rely on # this) > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1222: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: using patch list from debian/patches/series dpkg-source: info: applying a dpkg-source: info: applying b dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: using patch list from debian/patches/series dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_parenting[input_repo0-changelog_versions0-validation_repo_delta0-validation_repo_expected_identical_refs0] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '0a43f752e772a77fc6ba7927a4674f73', 'size': '524', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = changelog_versions = ['1-1'] validation_repo_delta = {'add_commits': [], 'update_tags': {'importer/import/1-1': }} validation_repo_expected_identical_refs = ['refs/tags/importer/import/1-1'] @pytest.mark.parametrize( [ 'input_repo', 'changelog_versions', 'validation_repo_delta', 'validation_repo_expected_identical_refs', ], [ pytest.param( repo_builder.Repo(), ['1-1'], { 'add_commits': [ repo_builder.Commit.from_spec(name='publish'), ], 'update_tags': {'importer/import/1-1': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', ] ), pytest.param( repo_builder.Repo( commits=[repo_builder.Commit.from_spec(name='import')], tags={'importer/import/1-1': Placeholder('import')}, ), ['1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( name='publish', parents=[Placeholder('import')], changelog_versions=['1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-2': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-2', ], ), pytest.param( repo_builder.Repo( commits=[repo_builder.Commit.from_spec(name='import')], tags={'importer/import/1-1': Placeholder('import')}, ), ['1-3', '1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( parents=[Placeholder('import')], name='publish', changelog_versions=['1-3', '1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-3': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-3', ], ), ( repo_builder.Repo( commits=[ repo_builder.Commit.from_spec(name='import'), repo_builder.Commit.from_spec( name='reimport', mutate='Reimport tag contents', ), ], tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), ['1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( parents=[ Placeholder('import'), Placeholder('reimport'), ], name='publish', changelog_versions=['1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-2': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', 'refs/tags/importer/import/1-2', ], ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_parenting( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, changelog_versions, validation_repo_delta, validation_repo_expected_identical_refs, ): """Test that unapplied import commits have the correct parents :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) changelog_versions: the versions in the changelog of a fake package to test import :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository Verify that if an import of a package is made into input_repo where the package being imported has the given changelog_versions, then the output repository has commits with the parents we expect. This is tested by comparing specific output references against the validation repository. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' get_import_commit_msg_mock.return_value = b'Test commit' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( changelog_versions=changelog_versions, ) with source_builder.Source(publish_spec) as dsc_path: # import_unapplied_spi currently assumes it is called from the # repository directory (pristine-tar and other commands rely on # this) > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1391: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_parenting[input_repo1-changelog_versions1-validation_repo_delta1-validation_repo_expected_identical_refs1] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '2e86dac2b6e042390dc169147089e18b', 'size': '528', 'name': 'source-builder-package_1-2.debian.tar.xz'}]} namespace = 'importer', version = '1-2', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = changelog_versions = ['1-2', '1-1'] validation_repo_delta = {'add_commits': [], 'update_tags': {'importer/import/1-2': }} validation_repo_expected_identical_refs = ['refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-2'] @pytest.mark.parametrize( [ 'input_repo', 'changelog_versions', 'validation_repo_delta', 'validation_repo_expected_identical_refs', ], [ pytest.param( repo_builder.Repo(), ['1-1'], { 'add_commits': [ repo_builder.Commit.from_spec(name='publish'), ], 'update_tags': {'importer/import/1-1': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', ] ), pytest.param( repo_builder.Repo( commits=[repo_builder.Commit.from_spec(name='import')], tags={'importer/import/1-1': Placeholder('import')}, ), ['1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( name='publish', parents=[Placeholder('import')], changelog_versions=['1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-2': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-2', ], ), pytest.param( repo_builder.Repo( commits=[repo_builder.Commit.from_spec(name='import')], tags={'importer/import/1-1': Placeholder('import')}, ), ['1-3', '1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( parents=[Placeholder('import')], name='publish', changelog_versions=['1-3', '1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-3': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-3', ], ), ( repo_builder.Repo( commits=[ repo_builder.Commit.from_spec(name='import'), repo_builder.Commit.from_spec( name='reimport', mutate='Reimport tag contents', ), ], tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), ['1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( parents=[ Placeholder('import'), Placeholder('reimport'), ], name='publish', changelog_versions=['1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-2': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', 'refs/tags/importer/import/1-2', ], ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_parenting( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, changelog_versions, validation_repo_delta, validation_repo_expected_identical_refs, ): """Test that unapplied import commits have the correct parents :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) changelog_versions: the versions in the changelog of a fake package to test import :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository Verify that if an import of a package is made into input_repo where the package being imported has the given changelog_versions, then the output repository has commits with the parents we expect. This is tested by comparing specific output references against the validation repository. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' get_import_commit_msg_mock.return_value = b'Test commit' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( changelog_versions=changelog_versions, ) with source_builder.Source(publish_spec) as dsc_path: # import_unapplied_spi currently assumes it is called from the # repository directory (pristine-tar and other commands rely on # this) > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1391: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-2'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-2']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-2.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-2.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-2" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_parenting[input_repo2-changelog_versions2-validation_repo_delta2-validation_repo_expected_identical_refs2] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': 'a4a9f2d2fc3b4361caaa82ed58a153f5', 'size': '528', 'name': 'source-builder-package_1-3.debian.tar.xz'}]} namespace = 'importer', version = '1-3', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = changelog_versions = ['1-3', '1-2', '1-1'] validation_repo_delta = {'add_commits': [], 'update_tags': {'importer/import/1-3': }} validation_repo_expected_identical_refs = ['refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-3'] @pytest.mark.parametrize( [ 'input_repo', 'changelog_versions', 'validation_repo_delta', 'validation_repo_expected_identical_refs', ], [ pytest.param( repo_builder.Repo(), ['1-1'], { 'add_commits': [ repo_builder.Commit.from_spec(name='publish'), ], 'update_tags': {'importer/import/1-1': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', ] ), pytest.param( repo_builder.Repo( commits=[repo_builder.Commit.from_spec(name='import')], tags={'importer/import/1-1': Placeholder('import')}, ), ['1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( name='publish', parents=[Placeholder('import')], changelog_versions=['1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-2': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-2', ], ), pytest.param( repo_builder.Repo( commits=[repo_builder.Commit.from_spec(name='import')], tags={'importer/import/1-1': Placeholder('import')}, ), ['1-3', '1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( parents=[Placeholder('import')], name='publish', changelog_versions=['1-3', '1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-3': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-3', ], ), ( repo_builder.Repo( commits=[ repo_builder.Commit.from_spec(name='import'), repo_builder.Commit.from_spec( name='reimport', mutate='Reimport tag contents', ), ], tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), ['1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( parents=[ Placeholder('import'), Placeholder('reimport'), ], name='publish', changelog_versions=['1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-2': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', 'refs/tags/importer/import/1-2', ], ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_parenting( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, changelog_versions, validation_repo_delta, validation_repo_expected_identical_refs, ): """Test that unapplied import commits have the correct parents :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) changelog_versions: the versions in the changelog of a fake package to test import :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository Verify that if an import of a package is made into input_repo where the package being imported has the given changelog_versions, then the output repository has commits with the parents we expect. This is tested by comparing specific output references against the validation repository. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' get_import_commit_msg_mock.return_value = b'Test commit' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( changelog_versions=changelog_versions, ) with source_builder.Source(publish_spec) as dsc_path: # import_unapplied_spi currently assumes it is called from the # repository directory (pristine-tar and other commands rely on # this) > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1391: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-3'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-3']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-3.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-3.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-3" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_import_unapplied_spi_parenting[input_repo3-changelog_versions3-validation_repo_delta3-validation_repo_expected_identical_refs3] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '2e86dac2b6e042390dc169147089e18b', 'size': '528', 'name': 'source-builder-package_1-2.debian.tar.xz'}]} namespace = 'importer', version = '1-2', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = input_repo = changelog_versions = ['1-2', '1-1'] validation_repo_delta = {'add_commits': [], 'update_tags': {'importer/import/1-2': }} validation_repo_expected_identical_refs = ['refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', 'refs/tags/importer/import/1-2'] @pytest.mark.parametrize( [ 'input_repo', 'changelog_versions', 'validation_repo_delta', 'validation_repo_expected_identical_refs', ], [ pytest.param( repo_builder.Repo(), ['1-1'], { 'add_commits': [ repo_builder.Commit.from_spec(name='publish'), ], 'update_tags': {'importer/import/1-1': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', ] ), pytest.param( repo_builder.Repo( commits=[repo_builder.Commit.from_spec(name='import')], tags={'importer/import/1-1': Placeholder('import')}, ), ['1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( name='publish', parents=[Placeholder('import')], changelog_versions=['1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-2': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-2', ], ), pytest.param( repo_builder.Repo( commits=[repo_builder.Commit.from_spec(name='import')], tags={'importer/import/1-1': Placeholder('import')}, ), ['1-3', '1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( parents=[Placeholder('import')], name='publish', changelog_versions=['1-3', '1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-3': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/import/1-3', ], ), ( repo_builder.Repo( commits=[ repo_builder.Commit.from_spec(name='import'), repo_builder.Commit.from_spec( name='reimport', mutate='Reimport tag contents', ), ], tags={ 'importer/import/1-1': Placeholder('import'), 'importer/reimport/import/1-1/0': Placeholder('import'), 'importer/reimport/import/1-1/1': Placeholder('reimport'), }, ), ['1-2', '1-1'], { 'add_commits': [ repo_builder.Commit.from_spec( parents=[ Placeholder('import'), Placeholder('reimport'), ], name='publish', changelog_versions=['1-2', '1-1'], ), ], 'update_tags': {'importer/import/1-2': Placeholder('publish')}, }, [ 'refs/tags/importer/import/1-1', 'refs/tags/importer/reimport/import/1-1/0', 'refs/tags/importer/reimport/import/1-1/1', 'refs/tags/importer/import/1-2', ], ), ] ) @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_parenting( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, input_repo, changelog_versions, validation_repo_delta, validation_repo_expected_identical_refs, ): """Test that unapplied import commits have the correct parents :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data :param list(str) changelog_versions: the versions in the changelog of a fake package to test import :param dict validation_repo_delta: how to transform the input repository into a "validation repository", expressed as a dict to provide as **kwargs to gitubuntu.repo_builder.Repo.copy() against the input repository. The validation repository is then used for the purposes of comparison against the output repository. :param list(str) validation_repo_expected_identical_refs: refs that must be identical between the validation repository and the output repository Verify that if an import of a package is made into input_repo where the package being imported has the given changelog_versions, then the output repository has commits with the parents we expect. This is tested by comparing specific output references against the validation repository. """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' get_import_commit_msg_mock.return_value = b'Test commit' input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( changelog_versions=changelog_versions, ) with source_builder.Source(publish_spec) as dsc_path: # import_unapplied_spi currently assumes it is called from the # repository directory (pristine-tar and other commands rely on # this) > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1391: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-2'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-2']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-2.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-2.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-2" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed __________________ test_import_unapplied_spi_parent_override ___________________ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': '01e7cc499b0035c40a6e28e5ad00fb6b', 'size': '528', 'name': 'source-builder-package_2-1.debian.tar.xz'}]} namespace = 'importer', version = '2-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: get_import_commit_msg_mock = get_import_tag_msg_mock = repo = @patch('gitubuntu.importer.get_import_tag_msg') @patch('gitubuntu.importer.get_import_commit_msg') def test_import_unapplied_spi_parent_override( get_import_commit_msg_mock, get_import_tag_msg_mock, repo, ): """Test import_unapplied_spi() parent_override functionality Test that if parent_overrides is used in the import_unapplied_spi call then the resulting commit correctly uses the overridden parents specified. :param unittest.mock.Mock get_import_commit_msg_mock: mock of the function that determines the commit message to use for a given import :param unittest.mock.Mock get_import_tag_msg_mock: mock of the function that determines the tag message to use for a given import :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a temporary output repository :param repo_builder.Repo input_repo: input repository data """ # Match the repo_builder objects get_import_tag_msg_mock.return_value = 'Test tag' get_import_commit_msg_mock.return_value = b'Test commit' input_repo = repo_builder.Repo( commits=[ repo_builder.Commit.from_spec(name='import1-1', version='1-1'), repo_builder.Commit.from_spec(name='import1-2', version='1-2'), ], tags={ 'importer/import/1-1': Placeholder('import1-1'), 'importer/import/1-2': Placeholder('import1-2'), }, ) input_repo.write(repo.raw_repo) publish_spec = source_builder.SourceSpec( changelog_versions=['2-1', '1-1'], ) with source_builder.Source(publish_spec) as dsc_path: # import_unapplied_spi currently assumes it is called from the # repository directory (pristine-tar and other commands rely on # this) > target.import_unapplied_spi( repo=repo, spi=MockSPI(dsc_path, publish_spec.version), namespace='importer', skip_orig=False, parent_overrides={'2-1': {'changelog_parent': '1-2'}}, ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1454: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2308: in import_unapplied_spi import_unapplied_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 2-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 2-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-2.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-2.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-2.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-2.dsc dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_2.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_2-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_2-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 2-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_authorship_date[False-Fri, 2 Feb 1971 12:34:56 +0100-expected_result0] __ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': 'bd33ca2066e9b725731dc2781679db54', 'size': '528', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: repo = override = False, input_string = 'Fri, 2 Feb 1971 12:34:56 +0100' expected_result = (1971, 2, 2, 11, 34, 56, ...) @pytest.mark.parametrize(['override', 'input_string', 'expected_result'], [ # Standard date that should parse and be used (False, 'Fri, 2 Feb 1971 12:34:56 +0100', (1971, 2, 2, 11, 34, 56, 60)), # Deliberately illegal date that cannot be parsed (True, 'Failday, 30 Feb 1971 99:99:99 +9999', (1972, 3, 3, 12, 45, 57, 0)), ]) def test_authorship_date(repo, override, input_string, expected_result): """Synthesized commit should use changelog or override when provided A synthesized commit should use the date of the changelog entry in the usual case, or commit_date when an override is requested. :param GitUbuntuRepository repo: fixture providing a temporary GitUbuntuRepository instance to use :param bool override: whether a changelog date override should be requested from import_unapplied_dsc() :param str input_string: the timestamp part of the changelog entry to use :param tuple expected_result: the expected author date of the synthesized commit, specified as six parameters to datetime.datetime() followed by the expected tz offset in minutes. """ spec = source_builder.SourceSpec(changelog_date=input_string) with source_builder.Source(spec) as dsc_pathname: > target.import_unapplied_dsc( repo=repo, version='1-1', namespace='importer', dist='ubuntu', dsc_pathname=dsc_pathname, head_name='ubuntu/focal', skip_orig=True, parent_overrides={}, commit_date=datetime.datetime( 1972, 3, 3, 12, 45, 57, tzinfo=datetime.timezone.utc, ), changelog_date_overrides=( frozenset({'1-1'}) if override else frozenset() ), ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1815: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed _ test_authorship_date[True-Failday, 30 Feb 1971 99:99:99 +9999-expected_result1] _ repo = dsc = {'Format': '3.0 (quilt)', 'Source': 'source-builder-package', 'Binary': 'source-builder-package', 'Architecture': 'all...'}, {'md5sum': 'e57600c6b55d4ee620c4f0d00b841eea', 'size': '528', 'name': 'source-builder-package_1-1.debian.tar.xz'}]} namespace = 'importer', version = '1-1', dist = 'ubuntu' def import_dsc(repo, dsc, namespace, version, dist): """Imports the dsc file to importer/{debian,ubuntu}/dsc Arguments: spi - A GitUbuntuSourcePackageInformation instance """ # Add DSC file to the appropriate branch dsc_branch_name = '%s/importer/%s/dsc' % (namespace, dist) dsc_ref_name = 'refs/heads/%s' % dsc_branch_name try: repo.raw_repo.lookup_reference(dsc_ref_name) except KeyError: runq(['git', 'checkout', '--orphan', dsc_branch_name], env=repo.env) runq(['git', 'reset', '--hard'], env=repo.env) else: runq(['git', 'checkout', dsc_branch_name], env=repo.env) # It is possible the same-named DSC is published multiple times # with different contents, e.g. on epoch bumps local_dir = os.path.join(repo.local_dir, version) os.makedirs(local_dir, exist_ok=True) shutil.copy(dsc.dsc_path, local_dir) repo.git_run(['add', repo.local_dir]) try: # Anything to commit? (this will be 0 if, for instance, the # same dsc is being imported again) > runq(['git', 'diff', '--exit-code', 'HEAD'], env=repo.env) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:735: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:31: in runq return run(*args, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'diff', '--exit-code', 'HEAD'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -3, 'stdin': -3, ...} process = stdout = None, stderr = None, retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'diff', '--exit-code', 'HEAD']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError During handling of the above exception, another exception occurred: repo = override = True, input_string = 'Failday, 30 Feb 1971 99:99:99 +9999' expected_result = (1972, 3, 3, 12, 45, 57, ...) @pytest.mark.parametrize(['override', 'input_string', 'expected_result'], [ # Standard date that should parse and be used (False, 'Fri, 2 Feb 1971 12:34:56 +0100', (1971, 2, 2, 11, 34, 56, 60)), # Deliberately illegal date that cannot be parsed (True, 'Failday, 30 Feb 1971 99:99:99 +9999', (1972, 3, 3, 12, 45, 57, 0)), ]) def test_authorship_date(repo, override, input_string, expected_result): """Synthesized commit should use changelog or override when provided A synthesized commit should use the date of the changelog entry in the usual case, or commit_date when an override is requested. :param GitUbuntuRepository repo: fixture providing a temporary GitUbuntuRepository instance to use :param bool override: whether a changelog date override should be requested from import_unapplied_dsc() :param str input_string: the timestamp part of the changelog entry to use :param tuple expected_result: the expected author date of the synthesized commit, specified as six parameters to datetime.datetime() followed by the expected tz offset in minutes. """ spec = source_builder.SourceSpec(changelog_date=input_string) with source_builder.Source(spec) as dsc_pathname: > target.import_unapplied_dsc( repo=repo, version='1-1', namespace='importer', dist='ubuntu', dsc_pathname=dsc_pathname, head_name='ubuntu/focal', skip_orig=True, parent_overrides={}, commit_date=datetime.datetime( 1972, 3, 3, 12, 45, 57, tzinfo=datetime.timezone.utc, ), changelog_date_overrides=( frozenset({'1-1'}) if override else frozenset() ), ) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer_test.py:1815: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:2197: in import_unapplied_dsc import_dsc( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/importer.py:737: in import_dsc repo.git_run(['commit', '-m', 'DSC file for %s' % version]) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:1842: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:268: in git_run return run(['git'] + list(args), env=env, **kwargs) /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:87: in run raise e /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/run.py:64: in run cp = subprocess.run( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = None, capture_output = False, timeout = None, check = True popenargs = (['git', 'commit', '-m', 'DSC file for 1-1'],) kwargs = {'env': {'ASFLAGS': '', 'ASFLAGS_FOR_BUILD': '', 'BUILDUSERGECOS': 'first user,first room,first work-phone,first home-phone,first other', 'BUILDUSERNAME': 'pbuilder1', ...}, 'shell': False, 'stderr': -1, 'stdin': -3, ...} process = stdout = b'' stderr = b'Author identity unknown\n\n*** Please tell me who you are.\n\nRun\n\n git config --global user.email "you@example.c...-global to set the identity only in this repository.\n\nfatal: empty ident name (for ) not allowed\n' retcode = 128 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['git', 'commit', '-m', 'DSC file for 1-1']' returned non-zero exit status 128. /usr/lib/python3.12/subprocess.py:571: CalledProcessError ----------------------------- Captured stdout call ----------------------------- dpkg-source: info: using source format '3.0 (quilt)' dpkg-source: info: building source-builder-package using existing ./source-builder-package_1.orig.tar.gz dpkg-source: info: building source-builder-package in source-builder-package_1-1.debian.tar.xz dpkg-source: info: building source-builder-package in source-builder-package_1-1.dsc ----------------------------- Captured stderr call ----------------------------- dpkg-source: warning: srcpkg/debian/changelog(l4): ignoring invalid week day 'Failday' LINE: -- git ubuntu Failday, 30 Feb 1971 99:99:99 +9999 dpkg-source: warning: srcpkg/debian/changelog(l4): cannot parse non-conformant date '30 Feb 1971 99:99:99 +9999' LINE: -- git ubuntu Failday, 30 Feb 1971 99:99:99 +9999 dpkg-source: warning: missing information for output field Standards-Version ------------------------------ Captured log call ------------------------------- ERROR root:run.py:78 Command exited 128: git commit -m "DSC file for 1-1" ERROR root:run.py:79 stdout: ERROR root:run.py:83 stderr: Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for ) not allowed =============================== warnings summary =============================== gitubuntu/git_repository_test.py:5 /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository_test.py:5: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html import pkg_resources -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED gitubuntu/importer_tag_test.py::test_import_unapplied_spi_tags[input_repo0-expected_output_refs0-validation_repo_delta0-validation_repo_expected_identical_refs0-True] FAILED gitubuntu/importer_tag_test.py::test_import_unapplied_spi_tags[input_repo1-expected_output_refs1-validation_repo_delta1-validation_repo_expected_identical_refs1-True] FAILED gitubuntu/importer_tag_test.py::test_import_unapplied_spi_tags[input_repo2-expected_output_refs2-validation_repo_delta2-validation_repo_expected_identical_refs2-True] FAILED gitubuntu/importer_tag_test.py::test_import_unapplied_spi_tags[input_repo3-expected_output_refs3-validation_repo_delta3-validation_repo_expected_identical_refs3-False] FAILED gitubuntu/importer_tag_test.py::test_import_unapplied_spi_tags[input_repo4-expected_output_refs4-validation_repo_delta4-validation_repo_expected_identical_refs4-False] FAILED gitubuntu/importer_tag_test.py::test_import_unapplied_spi_tags[input_repo5-expected_output_refs5-validation_repo_delta5-validation_repo_expected_identical_refs5-True] FAILED gitubuntu/importer_tag_test.py::test_import_unapplied_spi_tags[input_repo6-expected_output_refs6-validation_repo_delta6-validation_repo_expected_identical_refs6-False] FAILED gitubuntu/importer_tag_test.py::test_import_unapplied_spi_tags[input_repo7-expected_output_refs7-validation_repo_delta7-validation_repo_expected_identical_refs7-False] FAILED gitubuntu/importer_test.py::test_import_creates_import_note - subproce... FAILED gitubuntu/importer_test.py::test_import_unapplied_spi_quilt_patches - ... FAILED gitubuntu/importer_test.py::test_import_unapplied_spi_parenting[input_repo0-changelog_versions0-validation_repo_delta0-validation_repo_expected_identical_refs0] FAILED gitubuntu/importer_test.py::test_import_unapplied_spi_parenting[input_repo1-changelog_versions1-validation_repo_delta1-validation_repo_expected_identical_refs1] FAILED gitubuntu/importer_test.py::test_import_unapplied_spi_parenting[input_repo2-changelog_versions2-validation_repo_delta2-validation_repo_expected_identical_refs2] FAILED gitubuntu/importer_test.py::test_import_unapplied_spi_parenting[input_repo3-changelog_versions3-validation_repo_delta3-validation_repo_expected_identical_refs3] FAILED gitubuntu/importer_test.py::test_import_unapplied_spi_parent_override FAILED gitubuntu/importer_test.py::test_authorship_date[False-Fri, 2 Feb 1971 12:34:56 +0100-expected_result0] FAILED gitubuntu/importer_test.py::test_authorship_date[True-Failday, 30 Feb 1971 99:99:99 +9999-expected_result1] = 17 failed, 383 passed, 4 skipped, 3 xfailed, 1 warning in 155.42s (0:02:35) == E: pybuild pybuild:389: test: plugin distutils failed with: exit code=1: cd /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build; python3.12 -m pytest dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p 3.12 returned exit code 13 make: *** [debian/rules:4: binary] Error 25 dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2 I: copying local configuration E: Failed autobuilding of package I: unmounting dev/ptmx filesystem I: unmounting dev/pts filesystem I: unmounting dev/shm filesystem I: unmounting proc filesystem I: unmounting sys filesystem I: cleaning the build env I: removing directory /srv/workspace/pbuilder/2498186 and its subdirectories Tue Dec 17 08:20:50 UTC 2024 W: No second build log, what happened?