Sun Sep 15 15:27:32 UTC 2024 I: starting to build git-ubuntu/unstable/amd64 on jenkins on '2024-09-15 15:27' Sun Sep 15 15:27:32 UTC 2024 I: The jenkins build log is/was available at https://jenkins.debian.net/userContent/reproducible/debian/build_service/amd64_27/32999/console.log Sun Sep 15 15:27:32 UTC 2024 I: Downloading source for unstable/git-ubuntu=1.1-1 --2024-09-15 15:27:33-- http://deb.debian.org/debian/pool/main/g/git-ubuntu/git-ubuntu_1.1-1.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-1.dsc’ 0K .. 100% 257M=0s 2024-09-15 15:27:33 (257 MB/s) - ‘git-ubuntu_1.1-1.dsc’ saved [2280/2280] Sun Sep 15 15:27:33 UTC 2024 I: git-ubuntu_1.1-1.dsc -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Format: 3.0 (quilt) Source: git-ubuntu Binary: git-ubuntu Architecture: all Version: 1.1-1 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 61cf24b744986eb9134c98efb395e0aa6b04e079 5776 git-ubuntu_1.1-1.debian.tar.xz Checksums-Sha256: 9de2950a5a3a16db8517966b7590de31483f4d3786c8ba455bb412ade0e53106 179268 git-ubuntu_1.1.orig.tar.xz 2cd2e41f4f0b97a33a1e96cdf53ff59745bdf1a1686552bead108f088d9b43f8 5776 git-ubuntu_1.1-1.debian.tar.xz Files: ea902a0087f7a52b86767e02f4013027 179268 git-ubuntu_1.1.orig.tar.xz 99d463f0d96c93a27d058a1edd2704f2 5776 git-ubuntu_1.1-1.debian.tar.xz -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEpi0s+9ULm1vzYNVLFZ61xO/Id0wFAmaFedAACgkQFZ61xO/I d0wzsA//UiTM9YGgwJ4XyV7F68h0B143Qwbejvz6WoMBsJCMgnYXjrCdDkAz+d2K 0F1oHpKGEFSV+oZphPqHR261t9DNDxCyqLoZoEBvH0H7XSDNVRw+cSuLn3tpV6xz 62em1+i1NNRNkANViGByGGdd+0WCml9fvvsO/8EDdyqSxEtd4FLvJMdTimcGdA3t /IY7kKiDE/VNE1gaTVoAPA1wrKvNRDSds/fUzsfPv1U6Sjnpt1O57+/ZBULCvynx hDYBL9ca4eO1ErufgQzF4m30B1M8Bh5LeXdghn3lPhqedmTgwB4EXrumcFEu1v9F 7JZHNvc+w01oy0MN0n7oNoO+1rZ3n1ZtaUCVp4Ttkj28pGwkNMFoyb6FUnma1v+2 TnUt1XHCa0OreGZ26JA8mPXmPI5MtVjISaNsZ2arIAyBbIst6gnGAuocafU1yYLd fxJWQ8a0jLzCfX/Oup4pQQVVc9iaZlRPTHTJvBDuaPphT0fbpL5KmgA/MXqD9Ftq tB4qCIWxmA1h/3FniW5s8ZLhSqmD6tuaSd9+hxMxOce7UAzUsk4z51+5zsh3TDdX enoapCQ9PVCdy2iyaGwXGq5TrL7w7v1K2kohShfwkMIc3E7FpRwJfKZS5Bg2VLBk mUuQ3FZECXeuwyPnzMP1RL0arxy+WjyK0+zTM1JMV/7oIIYHmDs= =EJzc -----END PGP SIGNATURE----- Sun Sep 15 15:27:33 UTC 2024 I: Checking whether the package is not for us Sun Sep 15 15:27:33 UTC 2024 I: Starting 1st build on remote node ionos11-amd64.debian.net. Sun Sep 15 15:27:33 UTC 2024 I: Preparing to do remote build '1' on ionos11-amd64.debian.net. Sun Sep 15 15:44:17 UTC 2024 I: Deleting $TMPDIR on ionos11-amd64.debian.net. I: pbuilder: network access will be disabled during build I: Current time: Sun Sep 15 03:27:36 -12 2024 I: pbuilder-time-stamp: 1726414056 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-1.dsc] I: copying [./git-ubuntu_1.1.orig.tar.xz] I: copying [./git-ubuntu_1.1-1.debian.tar.xz] I: Extracting source gpgv: Signature made Wed Jul 3 16:18:24 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-1.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-1.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 I: Not using root during the build. I: Installing the build-deps I: user script /srv/workspace/pbuilder/2388579/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='amd64' DEBIAN_FRONTEND='noninteractive' DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all parallel=20 ' DISTRIBUTION='unstable' HOME='/root' HOST_ARCH='amd64' IFS=' ' INVOCATION_ID='d8ab859295e349659ed5d0d4b3afde2b' 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='2388579' 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.4sfY6zpY/pbuilderrc_Vsu0 --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.4sfY6zpY/b1 --logfile b1/build.log git-ubuntu_1.1-1.dsc' SUDO_GID='111' SUDO_UID='106' SUDO_USER='jenkins' TERM='unknown' TZ='/usr/share/zoneinfo/Etc/GMT+12' USER='root' _='/usr/bin/systemd-run' http_proxy='http://46.16.76.132:3128' I: uname -a Linux ionos11-amd64 6.1.0-25-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.106-3 (2024-08-26) x86_64 GNU/Linux I: ls -l /bin lrwxrwxrwx 1 root root 7 Aug 4 21:30 /bin -> usr/bin I: user script /srv/workspace/pbuilder/2388579/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: amd64 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 ... 19782 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.7{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} libmbedcrypto7t64{a} libmbedtls14t64{a} libmbedx509-1t64{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-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-py{a} python3-pycryptodome{a} python3-pygit2{a} python3-pyparsing{a} python3-pytest{a} python3-requests{a} python3-secretstorage{a} python3-setuptools{a} python3-six{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, 215 newly installed, 0 to remove and 0 not upgraded. Need to get 62.4 MB of archives. After unpacking 239 MB will be used. Writing extended state information... Get: 1 http://deb.debian.org/debian unstable/main amd64 libpython3.12-minimal amd64 3.12.6-1 [814 kB] Get: 2 http://deb.debian.org/debian unstable/main amd64 libexpat1 amd64 2.6.3-1 [105 kB] Get: 3 http://deb.debian.org/debian unstable/main amd64 python3.12-minimal amd64 3.12.6-1 [2168 kB] Get: 4 http://deb.debian.org/debian unstable/main amd64 python3-minimal amd64 3.12.5-1+b1 [27.0 kB] Get: 5 http://deb.debian.org/debian unstable/main amd64 media-types all 10.1.0 [26.9 kB] Get: 6 http://deb.debian.org/debian unstable/main amd64 netbase all 6.4 [12.8 kB] Get: 7 http://deb.debian.org/debian unstable/main amd64 tzdata all 2024a-4 [255 kB] Get: 8 http://deb.debian.org/debian unstable/main amd64 libkrb5support0 amd64 1.21.3-3 [32.5 kB] Get: 9 http://deb.debian.org/debian unstable/main amd64 libcom-err2 amd64 1.47.1-1 [22.9 kB] Get: 10 http://deb.debian.org/debian unstable/main amd64 libk5crypto3 amd64 1.21.3-3 [79.9 kB] Get: 11 http://deb.debian.org/debian unstable/main amd64 libkeyutils1 amd64 1.6.3-3 [8952 B] Get: 12 http://deb.debian.org/debian unstable/main amd64 libkrb5-3 amd64 1.21.3-3 [324 kB] Get: 13 http://deb.debian.org/debian unstable/main amd64 libgssapi-krb5-2 amd64 1.21.3-3 [136 kB] Get: 14 http://deb.debian.org/debian unstable/main amd64 libtirpc-common all 1.3.4+ds-1.3 [10.9 kB] Get: 15 http://deb.debian.org/debian unstable/main amd64 libtirpc3t64 amd64 1.3.4+ds-1.3 [82.7 kB] Get: 16 http://deb.debian.org/debian unstable/main amd64 libnsl2 amd64 1.3.0-3+b2 [40.3 kB] Get: 17 http://deb.debian.org/debian unstable/main amd64 readline-common all 8.2-5 [69.3 kB] Get: 18 http://deb.debian.org/debian unstable/main amd64 libreadline8t64 amd64 8.2-5 [169 kB] Get: 19 http://deb.debian.org/debian unstable/main amd64 libpython3.12-stdlib amd64 3.12.6-1 [1963 kB] Get: 20 http://deb.debian.org/debian unstable/main amd64 python3.12 amd64 3.12.6-1 [669 kB] Get: 21 http://deb.debian.org/debian unstable/main amd64 libpython3-stdlib amd64 3.12.5-1+b1 [9884 B] Get: 22 http://deb.debian.org/debian unstable/main amd64 python3 amd64 3.12.5-1+b1 [27.9 kB] Get: 23 http://deb.debian.org/debian unstable/main amd64 libapparmor1 amd64 3.1.7-1+b1 [42.0 kB] Get: 24 http://deb.debian.org/debian unstable/main amd64 sudo amd64 1.9.15p5-3+b1 [2043 kB] Get: 25 http://deb.debian.org/debian unstable/main amd64 sensible-utils all 0.0.24 [24.8 kB] Get: 26 http://deb.debian.org/debian unstable/main amd64 bash-completion all 1:2.14.0-1 [305 kB] Get: 27 http://deb.debian.org/debian unstable/main amd64 openssl amd64 3.3.2-1 [1381 kB] Get: 28 http://deb.debian.org/debian unstable/main amd64 ca-certificates all 20240203 [158 kB] Get: 29 http://deb.debian.org/debian unstable/main amd64 libmagic-mgc amd64 1:5.45-3 [314 kB] Get: 30 http://deb.debian.org/debian unstable/main amd64 libmagic1t64 amd64 1:5.45-3 [105 kB] Get: 31 http://deb.debian.org/debian unstable/main amd64 file amd64 1:5.45-3 [42.9 kB] Get: 32 http://deb.debian.org/debian unstable/main amd64 gettext-base amd64 0.22.5-2 [200 kB] Get: 33 http://deb.debian.org/debian unstable/main amd64 libuchardet0 amd64 0.0.8-1+b1 [68.8 kB] Get: 34 http://deb.debian.org/debian unstable/main amd64 groff-base amd64 1.23.0-5 [1181 kB] Get: 35 http://deb.debian.org/debian unstable/main amd64 bsdextrautils amd64 2.40.2-8 [97.3 kB] Get: 36 http://deb.debian.org/debian unstable/main amd64 libpipeline1 amd64 1.5.8-1 [42.0 kB] Get: 37 http://deb.debian.org/debian unstable/main amd64 man-db amd64 2.13.0-1 [1420 kB] Get: 38 http://deb.debian.org/debian unstable/main amd64 m4 amd64 1.4.19-4 [287 kB] Get: 39 http://deb.debian.org/debian unstable/main amd64 autoconf all 2.72-3 [493 kB] Get: 40 http://deb.debian.org/debian unstable/main amd64 autotools-dev all 20220109.1 [51.6 kB] Get: 41 http://deb.debian.org/debian unstable/main amd64 automake all 1:1.16.5-1.3 [823 kB] Get: 42 http://deb.debian.org/debian unstable/main amd64 autopoint all 0.22.5-2 [723 kB] Get: 43 http://deb.debian.org/debian unstable/main amd64 dctrl-tools amd64 2.24-3+b1 [104 kB] Get: 44 http://deb.debian.org/debian unstable/main amd64 libdebhelper-perl all 13.20 [89.7 kB] Get: 45 http://deb.debian.org/debian unstable/main amd64 libtool all 2.4.7-7 [517 kB] Get: 46 http://deb.debian.org/debian unstable/main amd64 dh-autoreconf all 20 [17.1 kB] Get: 47 http://deb.debian.org/debian unstable/main amd64 libarchive-zip-perl all 1.68-1 [104 kB] Get: 48 http://deb.debian.org/debian unstable/main amd64 libfile-stripnondeterminism-perl all 1.14.0-1 [19.5 kB] Get: 49 http://deb.debian.org/debian unstable/main amd64 dh-strip-nondeterminism all 1.14.0-1 [8448 B] Get: 50 http://deb.debian.org/debian unstable/main amd64 libelf1t64 amd64 0.191-2 [188 kB] Get: 51 http://deb.debian.org/debian unstable/main amd64 dwz amd64 0.15-1+b1 [110 kB] Get: 52 http://deb.debian.org/debian unstable/main amd64 libicu72 amd64 72.1-5 [9396 kB] Get: 53 http://deb.debian.org/debian unstable/main amd64 libxml2 amd64 2.12.7+dfsg-3+b1 [671 kB] Get: 54 http://deb.debian.org/debian unstable/main amd64 gettext amd64 0.22.5-2 [1601 kB] Get: 55 http://deb.debian.org/debian unstable/main amd64 intltool-debian all 0.35.0+20060710.6 [22.9 kB] Get: 56 http://deb.debian.org/debian unstable/main amd64 po-debconf all 1.0.21+nmu1 [248 kB] Get: 57 http://deb.debian.org/debian unstable/main amd64 debhelper all 13.20 [915 kB] Get: 58 http://deb.debian.org/debian unstable/main amd64 libassuan9 amd64 3.0.1-2 [60.6 kB] Get: 59 http://deb.debian.org/debian unstable/main amd64 gpgconf amd64 2.2.43-8+b1 [120 kB] Get: 60 http://deb.debian.org/debian unstable/main amd64 libksba8 amd64 1.6.7-2 [132 kB] Get: 61 http://deb.debian.org/debian unstable/main amd64 libsasl2-modules-db amd64 2.1.28+dfsg1-8 [19.6 kB] Get: 62 http://deb.debian.org/debian unstable/main amd64 libsasl2-2 amd64 2.1.28+dfsg1-8 [57.3 kB] Get: 63 http://deb.debian.org/debian unstable/main amd64 libldap-2.5-0 amd64 2.5.18+dfsg-3 [187 kB] Get: 64 http://deb.debian.org/debian unstable/main amd64 libnpth0t64 amd64 1.6-3.1 [17.9 kB] Get: 65 http://deb.debian.org/debian unstable/main amd64 dirmngr amd64 2.2.43-8+b1 [367 kB] Get: 66 http://deb.debian.org/debian unstable/main amd64 gnupg-l10n all 2.2.43-8 [696 kB] Get: 67 http://deb.debian.org/debian unstable/main amd64 gpg amd64 2.2.43-8+b1 [527 kB] Get: 68 http://deb.debian.org/debian unstable/main amd64 pinentry-curses amd64 1.2.1-4+b1 [79.7 kB] Get: 69 http://deb.debian.org/debian unstable/main amd64 gpg-agent amd64 2.2.43-8+b1 [250 kB] Get: 70 http://deb.debian.org/debian unstable/main amd64 gpgsm amd64 2.2.43-8+b1 [252 kB] Get: 71 http://deb.debian.org/debian unstable/main amd64 gnupg all 2.2.43-8 [375 kB] Get: 72 http://deb.debian.org/debian unstable/main amd64 libfile-dirlist-perl all 0.05-3 [7600 B] Get: 73 http://deb.debian.org/debian unstable/main amd64 libfile-which-perl all 1.27-2 [15.1 kB] Get: 74 http://deb.debian.org/debian unstable/main amd64 libfile-homedir-perl all 1.006-2 [42.4 kB] Get: 75 http://deb.debian.org/debian unstable/main amd64 libfile-touch-perl all 0.12-2 [8816 B] Get: 76 http://deb.debian.org/debian unstable/main amd64 libio-pty-perl amd64 1:1.20-1+b1 [34.4 kB] Get: 77 http://deb.debian.org/debian unstable/main amd64 libipc-run-perl all 20231003.0-2 [101 kB] Get: 78 http://deb.debian.org/debian unstable/main amd64 libclass-method-modifiers-perl all 2.15-1 [18.0 kB] Get: 79 http://deb.debian.org/debian unstable/main amd64 libclass-xsaccessor-perl amd64 1.19-4+b3 [36.2 kB] Get: 80 http://deb.debian.org/debian unstable/main amd64 libb-hooks-op-check-perl amd64 0.22-3+b1 [10.6 kB] Get: 81 http://deb.debian.org/debian unstable/main amd64 libdynaloader-functions-perl all 0.004-1 [12.1 kB] Get: 82 http://deb.debian.org/debian unstable/main amd64 libdevel-callchecker-perl amd64 0.009-1 [15.9 kB] Get: 83 http://deb.debian.org/debian unstable/main amd64 libparams-classify-perl amd64 0.015-2+b3 [22.4 kB] Get: 84 http://deb.debian.org/debian unstable/main amd64 libmodule-runtime-perl all 0.016-2 [19.6 kB] Get: 85 http://deb.debian.org/debian unstable/main amd64 libimport-into-perl all 1.002005-2 [11.3 kB] Get: 86 http://deb.debian.org/debian unstable/main amd64 librole-tiny-perl all 2.002004-1 [21.4 kB] Get: 87 http://deb.debian.org/debian unstable/main amd64 libsub-quote-perl all 2.006008-1 [21.8 kB] Get: 88 http://deb.debian.org/debian unstable/main amd64 libmoo-perl all 2.005005-1 [58.0 kB] Get: 89 http://deb.debian.org/debian unstable/main amd64 libencode-locale-perl all 1.05-3 [12.9 kB] Get: 90 http://deb.debian.org/debian unstable/main amd64 libtimedate-perl all 2.3300-2 [39.3 kB] Get: 91 http://deb.debian.org/debian unstable/main amd64 libhttp-date-perl all 6.06-1 [10.7 kB] Get: 92 http://deb.debian.org/debian unstable/main amd64 libfile-listing-perl all 6.16-1 [12.4 kB] Get: 93 http://deb.debian.org/debian unstable/main amd64 libhtml-tagset-perl all 3.24-1 [14.7 kB] Get: 94 http://deb.debian.org/debian unstable/main amd64 liburi-perl all 5.29-1 [103 kB] Get: 95 http://deb.debian.org/debian unstable/main amd64 libhtml-parser-perl amd64 3.83-1 [99.4 kB] Get: 96 http://deb.debian.org/debian unstable/main amd64 libhtml-tree-perl all 5.07-3 [211 kB] Get: 97 http://deb.debian.org/debian unstable/main amd64 libclone-perl amd64 0.47-1 [13.5 kB] Get: 98 http://deb.debian.org/debian unstable/main amd64 libio-html-perl all 1.004-3 [16.2 kB] Get: 99 http://deb.debian.org/debian unstable/main amd64 liblwp-mediatypes-perl all 6.04-2 [20.2 kB] Get: 100 http://deb.debian.org/debian unstable/main amd64 libhttp-message-perl all 6.46-1 [79.7 kB] Get: 101 http://deb.debian.org/debian unstable/main amd64 libhttp-cookies-perl all 6.11-1 [19.1 kB] Get: 102 http://deb.debian.org/debian unstable/main amd64 libhttp-negotiate-perl all 6.01-2 [13.1 kB] Get: 103 http://deb.debian.org/debian unstable/main amd64 perl-openssl-defaults amd64 7+b2 [6724 B] Get: 104 http://deb.debian.org/debian unstable/main amd64 libnet-ssleay-perl amd64 1.94-1+b1 [339 kB] Get: 105 http://deb.debian.org/debian unstable/main amd64 libio-socket-ssl-perl all 2.089-1 [223 kB] Get: 106 http://deb.debian.org/debian unstable/main amd64 libnet-http-perl all 6.23-1 [23.9 kB] Get: 107 http://deb.debian.org/debian unstable/main amd64 liblwp-protocol-https-perl all 6.14-1 [10.8 kB] Get: 108 http://deb.debian.org/debian unstable/main amd64 libtry-tiny-perl all 0.32-1 [22.9 kB] Get: 109 http://deb.debian.org/debian unstable/main amd64 libwww-robotrules-perl all 6.02-1 [12.9 kB] Get: 110 http://deb.debian.org/debian unstable/main amd64 libwww-perl all 6.77-1 [183 kB] Get: 111 http://deb.debian.org/debian unstable/main amd64 patchutils amd64 0.4.2-1 [77.5 kB] Get: 112 http://deb.debian.org/debian unstable/main amd64 wdiff amd64 1.2.2-6 [119 kB] Get: 113 http://deb.debian.org/debian unstable/main amd64 devscripts all 2.23.7 [1068 kB] Get: 114 http://deb.debian.org/debian unstable/main amd64 dh-exec amd64 0.30 [25.6 kB] Get: 115 http://deb.debian.org/debian unstable/main amd64 python3-autocommand all 2.2.2-3 [13.6 kB] Get: 116 http://deb.debian.org/debian unstable/main amd64 python3-more-itertools all 10.4.0-1 [63.7 kB] Get: 117 http://deb.debian.org/debian unstable/main amd64 python3-typing-extensions all 4.12.2-2 [73.0 kB] Get: 118 http://deb.debian.org/debian unstable/main amd64 python3-zipp all 3.20.1-1 [10.2 kB] Get: 119 http://deb.debian.org/debian unstable/main amd64 python3-importlib-metadata all 8.4.0-1 [20.8 kB] Get: 120 http://deb.debian.org/debian unstable/main amd64 python3-typeguard all 4.3.0-1 [36.5 kB] Get: 121 http://deb.debian.org/debian unstable/main amd64 python3-inflect all 7.3.1-1 [42.2 kB] Get: 122 http://deb.debian.org/debian unstable/main amd64 python3-jaraco.context all 6.0.0-1 [7984 B] Get: 123 http://deb.debian.org/debian unstable/main amd64 python3-jaraco.functools all 4.0.2-1 [11.7 kB] Get: 124 http://deb.debian.org/debian unstable/main amd64 python3-pkg-resources all 74.1.2-2 [213 kB] Get: 125 http://deb.debian.org/debian unstable/main amd64 python3-setuptools all 74.1.2-2 [736 kB] Get: 126 http://deb.debian.org/debian unstable/main amd64 dh-python all 6.20240824 [109 kB] Get: 127 http://deb.debian.org/debian unstable/main amd64 diffstat amd64 1.66-1 [34.0 kB] Get: 128 http://deb.debian.org/debian unstable/main amd64 distro-info-data all 0.62 [6344 B] Get: 129 http://deb.debian.org/debian unstable/main amd64 distro-info amd64 1.7 [18.6 kB] Get: 130 http://deb.debian.org/debian unstable/main amd64 python3-chardet all 5.2.0+dfsg-1 [107 kB] Get: 131 http://deb.debian.org/debian unstable/main amd64 python3-debian all 0.1.49 [115 kB] Get: 132 http://deb.debian.org/debian unstable/main amd64 libgpgme11t64 amd64 1.18.0-6+b1 [302 kB] Get: 133 http://deb.debian.org/debian unstable/main amd64 python3-gpg amd64 1.18.0-6+b1 [364 kB] Get: 134 http://deb.debian.org/debian unstable/main amd64 python3-xdg all 0.28-2 [40.5 kB] Get: 135 http://deb.debian.org/debian unstable/main amd64 dput all 1.2.2 [45.0 kB] Get: 136 http://deb.debian.org/debian unstable/main amd64 ed amd64 1.20.2-2 [60.8 kB] Get: 137 http://deb.debian.org/debian unstable/main amd64 libbrotli1 amd64 1.1.0-2+b4 [300 kB] Get: 138 http://deb.debian.org/debian unstable/main amd64 libnghttp2-14 amd64 1.63.0-1 [74.8 kB] Get: 139 http://deb.debian.org/debian unstable/main amd64 libnghttp3-9 amd64 1.4.0-1 [63.1 kB] Get: 140 http://deb.debian.org/debian unstable/main amd64 libngtcp2-16 amd64 1.6.0-1 [122 kB] Get: 141 http://deb.debian.org/debian unstable/main amd64 libngtcp2-crypto-gnutls8 amd64 1.6.0-1 [19.6 kB] Get: 142 http://deb.debian.org/debian unstable/main amd64 libpsl5t64 amd64 0.21.2-1.1 [56.8 kB] Get: 143 http://deb.debian.org/debian unstable/main amd64 librtmp1 amd64 2.4+20151223.gitfa8646d.1-2+b4 [58.5 kB] Get: 144 http://deb.debian.org/debian unstable/main amd64 libssh2-1t64 amd64 1.11.0-7 [216 kB] Get: 145 http://deb.debian.org/debian unstable/main amd64 libcurl3t64-gnutls amd64 8.10.0-2 [359 kB] Get: 146 http://deb.debian.org/debian unstable/main amd64 liberror-perl all 0.17029-2 [29.0 kB] Get: 147 http://deb.debian.org/debian unstable/main amd64 git-man all 1:2.45.2-1 [2158 kB] Get: 148 http://deb.debian.org/debian unstable/main amd64 git amd64 1:2.45.2-1 [8645 kB] Get: 149 http://deb.debian.org/debian unstable/main amd64 python3-six all 1.16.0-7 [16.4 kB] Get: 150 http://deb.debian.org/debian unstable/main amd64 python3-dateutil all 2.9.0-2 [79.4 kB] Get: 151 http://deb.debian.org/debian unstable/main amd64 libyaml-0-2 amd64 0.2.5-1+b1 [52.6 kB] Get: 152 http://deb.debian.org/debian unstable/main amd64 python3-yaml amd64 6.0.2-1 [134 kB] Get: 153 http://deb.debian.org/debian unstable/main amd64 git-buildpackage all 0.9.34 [811 kB] Get: 154 http://deb.debian.org/debian unstable/main amd64 libarchive13t64 amd64 3.7.4-1 [349 kB] Get: 155 http://deb.debian.org/debian unstable/main amd64 libhttp-parser2.9 amd64 2.9.4-6+b1 [21.0 kB] Get: 156 http://deb.debian.org/debian unstable/main amd64 libmbedcrypto7t64 amd64 2.28.8-1 [284 kB] Get: 157 http://deb.debian.org/debian unstable/main amd64 libmbedx509-1t64 amd64 2.28.8-1 [131 kB] Get: 158 http://deb.debian.org/debian unstable/main amd64 libmbedtls14t64 amd64 2.28.8-1 [167 kB] Get: 159 http://deb.debian.org/debian unstable/main amd64 libgit2-1.7 amd64 1.7.2+ds-1+b2 [518 kB] Get: 160 http://deb.debian.org/debian unstable/main amd64 libglib2.0-0t64 amd64 2.82.0-1 [1498 kB] Get: 161 http://deb.debian.org/debian unstable/main amd64 libnorm1t64 amd64 1.5.9+dfsg-3.1 [221 kB] Get: 162 http://deb.debian.org/debian unstable/main amd64 libpgm-5.3-0t64 amd64 5.3.128~dfsg-2.1 [161 kB] Get: 163 http://deb.debian.org/debian unstable/main amd64 libsodium23 amd64 1.0.18-1+b1 [163 kB] Get: 164 http://deb.debian.org/debian unstable/main amd64 libsys-cpuaffinity-perl amd64 1.13~03-2+b3 [32.5 kB] Get: 165 http://deb.debian.org/debian unstable/main amd64 libxdelta2t64 amd64 1.1.3-10.7 [48.6 kB] Get: 166 http://deb.debian.org/debian unstable/main amd64 libzmq5 amd64 4.3.5-1+b2 [281 kB] Get: 167 http://deb.debian.org/debian unstable/main amd64 lsb-release all 12.1-1 [5912 B] Get: 168 http://deb.debian.org/debian unstable/main amd64 pbzip2 amd64 1.1.13-1 [44.9 kB] Get: 169 http://deb.debian.org/debian unstable/main amd64 pixz amd64 1.0.7-3 [20.9 kB] Get: 170 http://deb.debian.org/debian unstable/main amd64 xdelta amd64 1.1.3-10.7 [25.9 kB] Get: 171 http://deb.debian.org/debian unstable/main amd64 xdelta3 amd64 3.0.11-dfsg-1.2 [70.4 kB] Get: 172 http://deb.debian.org/debian unstable/main amd64 pristine-tar amd64 1.50+nmu2 [108 kB] Get: 173 http://deb.debian.org/debian unstable/main amd64 python-apt-common all 2.9.0 [66.2 kB] Get: 174 http://deb.debian.org/debian unstable/main amd64 python3-apt amd64 2.9.0+b1 [166 kB] Get: 175 http://deb.debian.org/debian unstable/main amd64 python3-bcrypt amd64 4.2.0-1 [206 kB] Get: 176 http://deb.debian.org/debian unstable/main amd64 python3-blinker all 1.8.2-1 [13.1 kB] Get: 177 http://deb.debian.org/debian unstable/main amd64 python3-cachetools all 5.3.3-1 [13.2 kB] Get: 178 http://deb.debian.org/debian unstable/main amd64 python3-certifi all 2024.8.30-1 [159 kB] Get: 179 http://deb.debian.org/debian unstable/main amd64 python3-cffi-backend amd64 1.17.1-1 [87.1 kB] Get: 180 http://deb.debian.org/debian unstable/main amd64 python3-charset-normalizer amd64 3.3.2-3 [116 kB] Get: 181 http://deb.debian.org/debian unstable/main amd64 python3-cryptography amd64 43.0.0-1 [935 kB] Get: 182 http://deb.debian.org/debian unstable/main amd64 python3-debianbts all 4.1.1 [12.4 kB] Get: 183 http://deb.debian.org/debian unstable/main amd64 python3-distro all 1.9.0-1 [20.3 kB] Get: 184 http://deb.debian.org/debian unstable/main amd64 python3-distro-info all 1.7 [6884 B] Get: 185 http://deb.debian.org/debian unstable/main amd64 python3-pyparsing all 3.1.2-1 [146 kB] Get: 186 http://deb.debian.org/debian unstable/main amd64 python3-httplib2 all 0.22.0-1 [36.1 kB] Get: 187 http://deb.debian.org/debian unstable/main amd64 python3-idna all 3.6-2.1 [38.6 kB] Get: 188 http://deb.debian.org/debian unstable/main amd64 python3-iniconfig all 1.1.1-2 [6396 B] Get: 189 http://deb.debian.org/debian unstable/main amd64 python3-jaraco.classes all 3.4.0-1 [7728 B] Get: 190 http://deb.debian.org/debian unstable/main amd64 python3-jeepney all 0.8.0-3 [34.0 kB] Get: 191 http://deb.debian.org/debian unstable/main amd64 python3-jwt all 2.7.0-1 [29.7 kB] Get: 192 http://deb.debian.org/debian unstable/main amd64 python3-secretstorage all 3.3.3-3 [16.1 kB] Get: 193 http://deb.debian.org/debian unstable/main amd64 python3-keyring all 25.3.0-1 [54.2 kB] Get: 194 http://deb.debian.org/debian unstable/main amd64 python3-pycryptodome amd64 3.20.0+dfsg-3 [1073 kB] Get: 195 http://deb.debian.org/debian unstable/main amd64 python3-keyrings.alt all 5.0.2-1 [17.7 kB] Get: 196 http://deb.debian.org/debian unstable/main amd64 python3-lazr.uri all 1.0.6-4 [13.8 kB] Get: 197 http://deb.debian.org/debian unstable/main amd64 python3-wadllib all 1.3.6-5 [37.0 kB] Get: 198 http://deb.debian.org/debian unstable/main amd64 python3-oauthlib all 3.2.2-1 [95.4 kB] Get: 199 http://deb.debian.org/debian unstable/main amd64 python3-lazr.restfulclient all 0.14.6-2 [50.7 kB] Get: 200 http://deb.debian.org/debian unstable/main amd64 python3-launchpadlib all 2.0.0-1 [136 kB] Get: 201 http://deb.debian.org/debian unstable/main amd64 python3-launchpadlib-desktop all 2.0.0-1 [8684 B] Get: 202 http://deb.debian.org/debian unstable/main amd64 python3-packaging all 24.1-1 [45.8 kB] Get: 203 http://deb.debian.org/debian unstable/main amd64 python3-pluggy all 1.5.0-1 [26.9 kB] Get: 204 http://deb.debian.org/debian unstable/main amd64 python3-py all 1.11.0-2 [88.7 kB] Get: 205 http://deb.debian.org/debian unstable/main amd64 python3-pygit2 amd64 1.14.1-1 [202 kB] Get: 206 http://deb.debian.org/debian unstable/main amd64 python3-pytest all 8.3.3-1 [249 kB] Get: 207 http://deb.debian.org/debian unstable/main amd64 python3-urllib3 all 2.0.7-2 [111 kB] Get: 208 http://deb.debian.org/debian unstable/main amd64 python3-requests all 2.32.3+dfsg-1 [71.9 kB] Get: 209 http://deb.debian.org/debian unstable/main amd64 python3-systemd amd64 235-1+b4 [39.6 kB] Get: 210 http://deb.debian.org/debian unstable/main amd64 python3-tenacity all 8.4.2+really8.4.1-1 [46.0 kB] Get: 211 http://deb.debian.org/debian unstable/main amd64 python3-ubuntutools all 0.202 [66.3 kB] Get: 212 http://deb.debian.org/debian unstable/main amd64 python3-zmq amd64 24.0.1-5+b2 [269 kB] Get: 213 http://deb.debian.org/debian unstable/main amd64 quilt all 0.68-1 [437 kB] Get: 214 http://deb.debian.org/debian unstable/main amd64 ubuntu-dev-tools all 0.202 [98.9 kB] Get: 215 http://deb.debian.org/debian unstable/main amd64 ubuntu-keyring all 2023.11.28.1-0.2 [14.1 kB] Fetched 62.4 MB in 10s (6301 kB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package libpython3.12-minimal:amd64. (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 ... 19782 files and directories currently installed.) Preparing to unpack .../libpython3.12-minimal_3.12.6-1_amd64.deb ... Unpacking libpython3.12-minimal:amd64 (3.12.6-1) ... Selecting previously unselected package libexpat1:amd64. Preparing to unpack .../libexpat1_2.6.3-1_amd64.deb ... Unpacking libexpat1:amd64 (2.6.3-1) ... Selecting previously unselected package python3.12-minimal. Preparing to unpack .../python3.12-minimal_3.12.6-1_amd64.deb ... Unpacking python3.12-minimal (3.12.6-1) ... Setting up libpython3.12-minimal:amd64 (3.12.6-1) ... Setting up libexpat1:amd64 (2.6.3-1) ... Setting up python3.12-minimal (3.12.6-1) ... 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 ... 20102 files and directories currently installed.) Preparing to unpack .../00-python3-minimal_3.12.5-1+b1_amd64.deb ... Unpacking python3-minimal (3.12.5-1+b1) ... 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_2024a-4_all.deb ... Unpacking tzdata (2024a-4) ... Selecting previously unselected package libkrb5support0:amd64. Preparing to unpack .../04-libkrb5support0_1.21.3-3_amd64.deb ... Unpacking libkrb5support0:amd64 (1.21.3-3) ... Selecting previously unselected package libcom-err2:amd64. Preparing to unpack .../05-libcom-err2_1.47.1-1_amd64.deb ... Unpacking libcom-err2:amd64 (1.47.1-1) ... Selecting previously unselected package libk5crypto3:amd64. Preparing to unpack .../06-libk5crypto3_1.21.3-3_amd64.deb ... Unpacking libk5crypto3:amd64 (1.21.3-3) ... Selecting previously unselected package libkeyutils1:amd64. Preparing to unpack .../07-libkeyutils1_1.6.3-3_amd64.deb ... Unpacking libkeyutils1:amd64 (1.6.3-3) ... Selecting previously unselected package libkrb5-3:amd64. Preparing to unpack .../08-libkrb5-3_1.21.3-3_amd64.deb ... Unpacking libkrb5-3:amd64 (1.21.3-3) ... Selecting previously unselected package libgssapi-krb5-2:amd64. Preparing to unpack .../09-libgssapi-krb5-2_1.21.3-3_amd64.deb ... Unpacking libgssapi-krb5-2:amd64 (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:amd64. Preparing to unpack .../11-libtirpc3t64_1.3.4+ds-1.3_amd64.deb ... Adding 'diversion of /lib/x86_64-linux-gnu/libtirpc.so.3 to /lib/x86_64-linux-gnu/libtirpc.so.3.usr-is-merged by libtirpc3t64' Adding 'diversion of /lib/x86_64-linux-gnu/libtirpc.so.3.0.0 to /lib/x86_64-linux-gnu/libtirpc.so.3.0.0.usr-is-merged by libtirpc3t64' Unpacking libtirpc3t64:amd64 (1.3.4+ds-1.3) ... Selecting previously unselected package libnsl2:amd64. Preparing to unpack .../12-libnsl2_1.3.0-3+b2_amd64.deb ... Unpacking libnsl2:amd64 (1.3.0-3+b2) ... Selecting previously unselected package readline-common. Preparing to unpack .../13-readline-common_8.2-5_all.deb ... Unpacking readline-common (8.2-5) ... Selecting previously unselected package libreadline8t64:amd64. Preparing to unpack .../14-libreadline8t64_8.2-5_amd64.deb ... Adding 'diversion of /lib/x86_64-linux-gnu/libhistory.so.8 to /lib/x86_64-linux-gnu/libhistory.so.8.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/x86_64-linux-gnu/libhistory.so.8.2 to /lib/x86_64-linux-gnu/libhistory.so.8.2.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/x86_64-linux-gnu/libreadline.so.8 to /lib/x86_64-linux-gnu/libreadline.so.8.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/x86_64-linux-gnu/libreadline.so.8.2 to /lib/x86_64-linux-gnu/libreadline.so.8.2.usr-is-merged by libreadline8t64' Unpacking libreadline8t64:amd64 (8.2-5) ... Selecting previously unselected package libpython3.12-stdlib:amd64. Preparing to unpack .../15-libpython3.12-stdlib_3.12.6-1_amd64.deb ... Unpacking libpython3.12-stdlib:amd64 (3.12.6-1) ... Selecting previously unselected package python3.12. Preparing to unpack .../16-python3.12_3.12.6-1_amd64.deb ... Unpacking python3.12 (3.12.6-1) ... Selecting previously unselected package libpython3-stdlib:amd64. Preparing to unpack .../17-libpython3-stdlib_3.12.5-1+b1_amd64.deb ... Unpacking libpython3-stdlib:amd64 (3.12.5-1+b1) ... Setting up python3-minimal (3.12.5-1+b1) ... 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 ... 21176 files and directories currently installed.) Preparing to unpack .../000-python3_3.12.5-1+b1_amd64.deb ... Unpacking python3 (3.12.5-1+b1) ... Selecting previously unselected package libapparmor1:amd64. Preparing to unpack .../001-libapparmor1_3.1.7-1+b1_amd64.deb ... Unpacking libapparmor1:amd64 (3.1.7-1+b1) ... Selecting previously unselected package sudo. Preparing to unpack .../002-sudo_1.9.15p5-3+b1_amd64.deb ... Unpacking sudo (1.9.15p5-3+b1) ... 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-1_all.deb ... Unpacking bash-completion (1:2.14.0-1) ... Selecting previously unselected package openssl. Preparing to unpack .../005-openssl_3.3.2-1_amd64.deb ... Unpacking openssl (3.3.2-1) ... 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_amd64.deb ... Unpacking libmagic-mgc (1:5.45-3) ... Selecting previously unselected package libmagic1t64:amd64. Preparing to unpack .../008-libmagic1t64_1%3a5.45-3_amd64.deb ... Unpacking libmagic1t64:amd64 (1:5.45-3) ... Selecting previously unselected package file. Preparing to unpack .../009-file_1%3a5.45-3_amd64.deb ... Unpacking file (1:5.45-3) ... Selecting previously unselected package gettext-base. Preparing to unpack .../010-gettext-base_0.22.5-2_amd64.deb ... Unpacking gettext-base (0.22.5-2) ... Selecting previously unselected package libuchardet0:amd64. Preparing to unpack .../011-libuchardet0_0.0.8-1+b1_amd64.deb ... Unpacking libuchardet0:amd64 (0.0.8-1+b1) ... Selecting previously unselected package groff-base. Preparing to unpack .../012-groff-base_1.23.0-5_amd64.deb ... Unpacking groff-base (1.23.0-5) ... Selecting previously unselected package bsdextrautils. Preparing to unpack .../013-bsdextrautils_2.40.2-8_amd64.deb ... Unpacking bsdextrautils (2.40.2-8) ... Selecting previously unselected package libpipeline1:amd64. Preparing to unpack .../014-libpipeline1_1.5.8-1_amd64.deb ... Unpacking libpipeline1:amd64 (1.5.8-1) ... Selecting previously unselected package man-db. Preparing to unpack .../015-man-db_2.13.0-1_amd64.deb ... Unpacking man-db (2.13.0-1) ... Selecting previously unselected package m4. Preparing to unpack .../016-m4_1.4.19-4_amd64.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-2_all.deb ... Unpacking autopoint (0.22.5-2) ... Selecting previously unselected package dctrl-tools. Preparing to unpack .../021-dctrl-tools_2.24-3+b1_amd64.deb ... Unpacking dctrl-tools (2.24-3+b1) ... Selecting previously unselected package libdebhelper-perl. Preparing to unpack .../022-libdebhelper-perl_13.20_all.deb ... Unpacking libdebhelper-perl (13.20) ... Selecting previously unselected package libtool. Preparing to unpack .../023-libtool_2.4.7-7_all.deb ... Unpacking libtool (2.4.7-7) ... 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:amd64. Preparing to unpack .../028-libelf1t64_0.191-2_amd64.deb ... Unpacking libelf1t64:amd64 (0.191-2) ... Selecting previously unselected package dwz. Preparing to unpack .../029-dwz_0.15-1+b1_amd64.deb ... Unpacking dwz (0.15-1+b1) ... Selecting previously unselected package libicu72:amd64. Preparing to unpack .../030-libicu72_72.1-5_amd64.deb ... Unpacking libicu72:amd64 (72.1-5) ... Selecting previously unselected package libxml2:amd64. Preparing to unpack .../031-libxml2_2.12.7+dfsg-3+b1_amd64.deb ... Unpacking libxml2:amd64 (2.12.7+dfsg-3+b1) ... Selecting previously unselected package gettext. Preparing to unpack .../032-gettext_0.22.5-2_amd64.deb ... Unpacking gettext (0.22.5-2) ... 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.20_all.deb ... Unpacking debhelper (13.20) ... Selecting previously unselected package libassuan9:amd64. Preparing to unpack .../036-libassuan9_3.0.1-2_amd64.deb ... Unpacking libassuan9:amd64 (3.0.1-2) ... Selecting previously unselected package gpgconf. Preparing to unpack .../037-gpgconf_2.2.43-8+b1_amd64.deb ... Unpacking gpgconf (2.2.43-8+b1) ... Selecting previously unselected package libksba8:amd64. Preparing to unpack .../038-libksba8_1.6.7-2_amd64.deb ... Unpacking libksba8:amd64 (1.6.7-2) ... Selecting previously unselected package libsasl2-modules-db:amd64. Preparing to unpack .../039-libsasl2-modules-db_2.1.28+dfsg1-8_amd64.deb ... Unpacking libsasl2-modules-db:amd64 (2.1.28+dfsg1-8) ... Selecting previously unselected package libsasl2-2:amd64. Preparing to unpack .../040-libsasl2-2_2.1.28+dfsg1-8_amd64.deb ... Unpacking libsasl2-2:amd64 (2.1.28+dfsg1-8) ... Selecting previously unselected package libldap-2.5-0:amd64. Preparing to unpack .../041-libldap-2.5-0_2.5.18+dfsg-3_amd64.deb ... Unpacking libldap-2.5-0:amd64 (2.5.18+dfsg-3) ... Selecting previously unselected package libnpth0t64:amd64. Preparing to unpack .../042-libnpth0t64_1.6-3.1_amd64.deb ... Unpacking libnpth0t64:amd64 (1.6-3.1) ... Selecting previously unselected package dirmngr. Preparing to unpack .../043-dirmngr_2.2.43-8+b1_amd64.deb ... Unpacking dirmngr (2.2.43-8+b1) ... Selecting previously unselected package gnupg-l10n. Preparing to unpack .../044-gnupg-l10n_2.2.43-8_all.deb ... Unpacking gnupg-l10n (2.2.43-8) ... Selecting previously unselected package gpg. Preparing to unpack .../045-gpg_2.2.43-8+b1_amd64.deb ... Unpacking gpg (2.2.43-8+b1) ... Selecting previously unselected package pinentry-curses. Preparing to unpack .../046-pinentry-curses_1.2.1-4+b1_amd64.deb ... Unpacking pinentry-curses (1.2.1-4+b1) ... Selecting previously unselected package gpg-agent. Preparing to unpack .../047-gpg-agent_2.2.43-8+b1_amd64.deb ... Unpacking gpg-agent (2.2.43-8+b1) ... Selecting previously unselected package gpgsm. Preparing to unpack .../048-gpgsm_2.2.43-8+b1_amd64.deb ... Unpacking gpgsm (2.2.43-8+b1) ... Selecting previously unselected package gnupg. Preparing to unpack .../049-gnupg_2.2.43-8_all.deb ... Unpacking gnupg (2.2.43-8) ... 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+b1_amd64.deb ... Unpacking libio-pty-perl (1:1.20-1+b1) ... 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+b3_amd64.deb ... Unpacking libclass-xsaccessor-perl (1.19-4+b3) ... Selecting previously unselected package libb-hooks-op-check-perl:amd64. Preparing to unpack .../058-libb-hooks-op-check-perl_0.22-3+b1_amd64.deb ... Unpacking libb-hooks-op-check-perl:amd64 (0.22-3+b1) ... 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:amd64. Preparing to unpack .../060-libdevel-callchecker-perl_0.009-1_amd64.deb ... Unpacking libdevel-callchecker-perl:amd64 (0.009-1) ... Selecting previously unselected package libparams-classify-perl:amd64. Preparing to unpack .../061-libparams-classify-perl_0.015-2+b3_amd64.deb ... Unpacking libparams-classify-perl:amd64 (0.015-2+b3) ... 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.29-1_all.deb ... Unpacking liburi-perl (5.29-1) ... Selecting previously unselected package libhtml-parser-perl:amd64. Preparing to unpack .../073-libhtml-parser-perl_3.83-1_amd64.deb ... Unpacking libhtml-parser-perl:amd64 (3.83-1) ... 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:amd64. Preparing to unpack .../075-libclone-perl_0.47-1_amd64.deb ... Unpacking libclone-perl:amd64 (0.47-1) ... 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_6.46-1_all.deb ... Unpacking libhttp-message-perl (6.46-1) ... 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:amd64. Preparing to unpack .../081-perl-openssl-defaults_7+b2_amd64.deb ... Unpacking perl-openssl-defaults:amd64 (7+b2) ... Selecting previously unselected package libnet-ssleay-perl:amd64. Preparing to unpack .../082-libnet-ssleay-perl_1.94-1+b1_amd64.deb ... Unpacking libnet-ssleay-perl:amd64 (1.94-1+b1) ... 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_amd64.deb ... Unpacking patchutils (0.4.2-1) ... Selecting previously unselected package wdiff. Preparing to unpack .../090-wdiff_1.2.2-6_amd64.deb ... Unpacking wdiff (1.2.2-6) ... Selecting previously unselected package devscripts. Preparing to unpack .../091-devscripts_2.23.7_all.deb ... Unpacking devscripts (2.23.7) ... Selecting previously unselected package dh-exec. Preparing to unpack .../092-dh-exec_0.30_amd64.deb ... Unpacking dh-exec (0.30) ... 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.4.0-1_all.deb ... Unpacking python3-more-itertools (10.4.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.20.1-1_all.deb ... Unpacking python3-zipp (3.20.1-1) ... Selecting previously unselected package python3-importlib-metadata. Preparing to unpack .../097-python3-importlib-metadata_8.4.0-1_all.deb ... Unpacking python3-importlib-metadata (8.4.0-1) ... Selecting previously unselected package python3-typeguard. Preparing to unpack .../098-python3-typeguard_4.3.0-1_all.deb ... Unpacking python3-typeguard (4.3.0-1) ... Selecting previously unselected package python3-inflect. Preparing to unpack .../099-python3-inflect_7.3.1-1_all.deb ... Unpacking python3-inflect (7.3.1-1) ... 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.0.2-1_all.deb ... Unpacking python3-jaraco.functools (4.0.2-1) ... Selecting previously unselected package python3-pkg-resources. Preparing to unpack .../102-python3-pkg-resources_74.1.2-2_all.deb ... Unpacking python3-pkg-resources (74.1.2-2) ... Selecting previously unselected package python3-setuptools. Preparing to unpack .../103-python3-setuptools_74.1.2-2_all.deb ... Unpacking python3-setuptools (74.1.2-2) ... Selecting previously unselected package dh-python. Preparing to unpack .../104-dh-python_6.20240824_all.deb ... Unpacking dh-python (6.20240824) ... Selecting previously unselected package diffstat. Preparing to unpack .../105-diffstat_1.66-1_amd64.deb ... Unpacking diffstat (1.66-1) ... Selecting previously unselected package distro-info-data. Preparing to unpack .../106-distro-info-data_0.62_all.deb ... Unpacking distro-info-data (0.62) ... Selecting previously unselected package distro-info. Preparing to unpack .../107-distro-info_1.7_amd64.deb ... Unpacking distro-info (1.7) ... Selecting previously unselected package python3-chardet. Preparing to unpack .../108-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 .../109-python3-debian_0.1.49_all.deb ... Unpacking python3-debian (0.1.49) ... Selecting previously unselected package libgpgme11t64:amd64. Preparing to unpack .../110-libgpgme11t64_1.18.0-6+b1_amd64.deb ... Unpacking libgpgme11t64:amd64 (1.18.0-6+b1) ... Selecting previously unselected package python3-gpg. Preparing to unpack .../111-python3-gpg_1.18.0-6+b1_amd64.deb ... Unpacking python3-gpg (1.18.0-6+b1) ... Selecting previously unselected package python3-xdg. Preparing to unpack .../112-python3-xdg_0.28-2_all.deb ... Unpacking python3-xdg (0.28-2) ... Selecting previously unselected package dput. Preparing to unpack .../113-dput_1.2.2_all.deb ... Unpacking dput (1.2.2) ... Selecting previously unselected package ed. Preparing to unpack .../114-ed_1.20.2-2_amd64.deb ... Unpacking ed (1.20.2-2) ... Selecting previously unselected package libbrotli1:amd64. Preparing to unpack .../115-libbrotli1_1.1.0-2+b4_amd64.deb ... Unpacking libbrotli1:amd64 (1.1.0-2+b4) ... Selecting previously unselected package libnghttp2-14:amd64. Preparing to unpack .../116-libnghttp2-14_1.63.0-1_amd64.deb ... Unpacking libnghttp2-14:amd64 (1.63.0-1) ... Selecting previously unselected package libnghttp3-9:amd64. Preparing to unpack .../117-libnghttp3-9_1.4.0-1_amd64.deb ... Unpacking libnghttp3-9:amd64 (1.4.0-1) ... Selecting previously unselected package libngtcp2-16:amd64. Preparing to unpack .../118-libngtcp2-16_1.6.0-1_amd64.deb ... Unpacking libngtcp2-16:amd64 (1.6.0-1) ... Selecting previously unselected package libngtcp2-crypto-gnutls8:amd64. Preparing to unpack .../119-libngtcp2-crypto-gnutls8_1.6.0-1_amd64.deb ... Unpacking libngtcp2-crypto-gnutls8:amd64 (1.6.0-1) ... Selecting previously unselected package libpsl5t64:amd64. Preparing to unpack .../120-libpsl5t64_0.21.2-1.1_amd64.deb ... Unpacking libpsl5t64:amd64 (0.21.2-1.1) ... Selecting previously unselected package librtmp1:amd64. Preparing to unpack .../121-librtmp1_2.4+20151223.gitfa8646d.1-2+b4_amd64.deb ... Unpacking librtmp1:amd64 (2.4+20151223.gitfa8646d.1-2+b4) ... Selecting previously unselected package libssh2-1t64:amd64. Preparing to unpack .../122-libssh2-1t64_1.11.0-7_amd64.deb ... Unpacking libssh2-1t64:amd64 (1.11.0-7) ... Selecting previously unselected package libcurl3t64-gnutls:amd64. Preparing to unpack .../123-libcurl3t64-gnutls_8.10.0-2_amd64.deb ... Unpacking libcurl3t64-gnutls:amd64 (8.10.0-2) ... Selecting previously unselected package liberror-perl. Preparing to unpack .../124-liberror-perl_0.17029-2_all.deb ... Unpacking liberror-perl (0.17029-2) ... Selecting previously unselected package git-man. Preparing to unpack .../125-git-man_1%3a2.45.2-1_all.deb ... Unpacking git-man (1:2.45.2-1) ... Selecting previously unselected package git. Preparing to unpack .../126-git_1%3a2.45.2-1_amd64.deb ... Unpacking git (1:2.45.2-1) ... Selecting previously unselected package python3-six. Preparing to unpack .../127-python3-six_1.16.0-7_all.deb ... Unpacking python3-six (1.16.0-7) ... Selecting previously unselected package python3-dateutil. Preparing to unpack .../128-python3-dateutil_2.9.0-2_all.deb ... Unpacking python3-dateutil (2.9.0-2) ... Selecting previously unselected package libyaml-0-2:amd64. Preparing to unpack .../129-libyaml-0-2_0.2.5-1+b1_amd64.deb ... Unpacking libyaml-0-2:amd64 (0.2.5-1+b1) ... Selecting previously unselected package python3-yaml. Preparing to unpack .../130-python3-yaml_6.0.2-1_amd64.deb ... Unpacking python3-yaml (6.0.2-1) ... Selecting previously unselected package git-buildpackage. Preparing to unpack .../131-git-buildpackage_0.9.34_all.deb ... Unpacking git-buildpackage (0.9.34) ... Selecting previously unselected package libarchive13t64:amd64. Preparing to unpack .../132-libarchive13t64_3.7.4-1_amd64.deb ... Unpacking libarchive13t64:amd64 (3.7.4-1) ... Selecting previously unselected package libhttp-parser2.9:amd64. Preparing to unpack .../133-libhttp-parser2.9_2.9.4-6+b1_amd64.deb ... Unpacking libhttp-parser2.9:amd64 (2.9.4-6+b1) ... Selecting previously unselected package libmbedcrypto7t64:amd64. Preparing to unpack .../134-libmbedcrypto7t64_2.28.8-1_amd64.deb ... Unpacking libmbedcrypto7t64:amd64 (2.28.8-1) ... Selecting previously unselected package libmbedx509-1t64:amd64. Preparing to unpack .../135-libmbedx509-1t64_2.28.8-1_amd64.deb ... Unpacking libmbedx509-1t64:amd64 (2.28.8-1) ... Selecting previously unselected package libmbedtls14t64:amd64. Preparing to unpack .../136-libmbedtls14t64_2.28.8-1_amd64.deb ... Unpacking libmbedtls14t64:amd64 (2.28.8-1) ... Selecting previously unselected package libgit2-1.7:amd64. Preparing to unpack .../137-libgit2-1.7_1.7.2+ds-1+b2_amd64.deb ... Unpacking libgit2-1.7:amd64 (1.7.2+ds-1+b2) ... Selecting previously unselected package libglib2.0-0t64:amd64. Preparing to unpack .../138-libglib2.0-0t64_2.82.0-1_amd64.deb ... Unpacking libglib2.0-0t64:amd64 (2.82.0-1) ... Selecting previously unselected package libnorm1t64:amd64. Preparing to unpack .../139-libnorm1t64_1.5.9+dfsg-3.1_amd64.deb ... Unpacking libnorm1t64:amd64 (1.5.9+dfsg-3.1) ... Selecting previously unselected package libpgm-5.3-0t64:amd64. Preparing to unpack .../140-libpgm-5.3-0t64_5.3.128~dfsg-2.1_amd64.deb ... Unpacking libpgm-5.3-0t64:amd64 (5.3.128~dfsg-2.1) ... Selecting previously unselected package libsodium23:amd64. Preparing to unpack .../141-libsodium23_1.0.18-1+b1_amd64.deb ... Unpacking libsodium23:amd64 (1.0.18-1+b1) ... Selecting previously unselected package libsys-cpuaffinity-perl. Preparing to unpack .../142-libsys-cpuaffinity-perl_1.13~03-2+b3_amd64.deb ... Unpacking libsys-cpuaffinity-perl (1.13~03-2+b3) ... Selecting previously unselected package libxdelta2t64:amd64. Preparing to unpack .../143-libxdelta2t64_1.1.3-10.7_amd64.deb ... Unpacking libxdelta2t64:amd64 (1.1.3-10.7) ... Selecting previously unselected package libzmq5:amd64. Preparing to unpack .../144-libzmq5_4.3.5-1+b2_amd64.deb ... Unpacking libzmq5:amd64 (4.3.5-1+b2) ... 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_amd64.deb ... Unpacking pbzip2 (1.1.13-1) ... Selecting previously unselected package pixz. Preparing to unpack .../147-pixz_1.0.7-3_amd64.deb ... Unpacking pixz (1.0.7-3) ... Selecting previously unselected package xdelta. Preparing to unpack .../148-xdelta_1.1.3-10.7_amd64.deb ... Unpacking xdelta (1.1.3-10.7) ... Selecting previously unselected package xdelta3. Preparing to unpack .../149-xdelta3_3.0.11-dfsg-1.2_amd64.deb ... Unpacking xdelta3 (3.0.11-dfsg-1.2) ... Selecting previously unselected package pristine-tar. Preparing to unpack .../150-pristine-tar_1.50+nmu2_amd64.deb ... Unpacking pristine-tar (1.50+nmu2) ... Selecting previously unselected package python-apt-common. Preparing to unpack .../151-python-apt-common_2.9.0_all.deb ... Unpacking python-apt-common (2.9.0) ... Selecting previously unselected package python3-apt. Preparing to unpack .../152-python3-apt_2.9.0+b1_amd64.deb ... Unpacking python3-apt (2.9.0+b1) ... Selecting previously unselected package python3-bcrypt. Preparing to unpack .../153-python3-bcrypt_4.2.0-1_amd64.deb ... Unpacking python3-bcrypt (4.2.0-1) ... Selecting previously unselected package python3-blinker. Preparing to unpack .../154-python3-blinker_1.8.2-1_all.deb ... Unpacking python3-blinker (1.8.2-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-1_all.deb ... Unpacking python3-certifi (2024.8.30-1) ... Selecting previously unselected package python3-cffi-backend:amd64. Preparing to unpack .../157-python3-cffi-backend_1.17.1-1_amd64.deb ... Unpacking python3-cffi-backend:amd64 (1.17.1-1) ... Selecting previously unselected package python3-charset-normalizer. Preparing to unpack .../158-python3-charset-normalizer_3.3.2-3_amd64.deb ... Unpacking python3-charset-normalizer (3.3.2-3) ... Selecting previously unselected package python3-cryptography. Preparing to unpack .../159-python3-cryptography_43.0.0-1_amd64.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.7_all.deb ... Unpacking python3-distro-info (1.7) ... 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.6-2.1_all.deb ... Unpacking python3-idna (3.6-2.1) ... 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-3_all.deb ... Unpacking python3-jeepney (0.8.0-3) ... 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.3.0-1_all.deb ... Unpacking python3-keyring (25.3.0-1) ... Selecting previously unselected package python3-pycryptodome. Preparing to unpack .../172-python3-pycryptodome_3.20.0+dfsg-3_amd64.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_1.3.6-5_all.deb ... Unpacking python3-wadllib (1.3.6-5) ... Selecting previously unselected package python3-oauthlib. Preparing to unpack .../176-python3-oauthlib_3.2.2-1_all.deb ... Unpacking python3-oauthlib (3.2.2-1) ... 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.1-1_all.deb ... Unpacking python3-packaging (24.1-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-py. Preparing to unpack .../182-python3-py_1.11.0-2_all.deb ... Unpacking python3-py (1.11.0-2) ... Selecting previously unselected package python3-pygit2. Preparing to unpack .../183-python3-pygit2_1.14.1-1_amd64.deb ... Unpacking python3-pygit2 (1.14.1-1) ... Selecting previously unselected package python3-pytest. Preparing to unpack .../184-python3-pytest_8.3.3-1_all.deb ... Unpacking python3-pytest (8.3.3-1) ... Selecting previously unselected package python3-urllib3. Preparing to unpack .../185-python3-urllib3_2.0.7-2_all.deb ... Unpacking python3-urllib3 (2.0.7-2) ... Selecting previously unselected package python3-requests. Preparing to unpack .../186-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 .../187-python3-systemd_235-1+b4_amd64.deb ... Unpacking python3-systemd (235-1+b4) ... Selecting previously unselected package python3-tenacity. Preparing to unpack .../188-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 .../189-python3-ubuntutools_0.202_all.deb ... Unpacking python3-ubuntutools (0.202) ... Selecting previously unselected package python3-zmq. Preparing to unpack .../190-python3-zmq_24.0.1-5+b2_amd64.deb ... Unpacking python3-zmq (24.0.1-5+b2) ... Selecting previously unselected package quilt. Preparing to unpack .../191-quilt_0.68-1_all.deb ... Unpacking quilt (0.68-1) ... Selecting previously unselected package ubuntu-dev-tools. Preparing to unpack .../192-ubuntu-dev-tools_0.202_all.deb ... Unpacking ubuntu-dev-tools (0.202) ... Selecting previously unselected package ubuntu-keyring. Preparing to unpack .../193-ubuntu-keyring_2023.11.28.1-0.2_all.deb ... Unpacking ubuntu-keyring (2023.11.28.1-0.2) ... Setting up libksba8:amd64 (1.6.7-2) ... Setting up media-types (10.1.0) ... Setting up libpipeline1:amd64 (1.5.8-1) ... Setting up libnorm1t64:amd64 (1.5.9+dfsg-3.1) ... Setting up wdiff (1.2.2-6) ... Setting up libfile-which-perl (1.27-2) ... Setting up libnpth0t64:amd64 (1.6-3.1) ... Setting up libkeyutils1:amd64 (1.6.3-3) ... Setting up libapparmor1:amd64 (3.1.7-1+b1) ... Setting up libsodium23:amd64 (1.0.18-1+b1) ... Setting up libicu72:amd64 (72.1-5) ... Setting up bsdextrautils (2.40.2-8) ... Setting up libsys-cpuaffinity-perl (1.13~03-2+b3) ... Setting up libmbedcrypto7t64:amd64 (2.28.8-1) ... 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+b1) ... Setting up libmagic-mgc (1:5.45-3) ... Setting up libclone-perl:amd64 (0.47-1) ... Setting up libarchive-zip-perl (1.68-1) ... Setting up libyaml-0-2:amd64 (0.2.5-1+b1) ... Setting up distro-info-data (0.62) ... Setting up libtirpc-common (1.3.4+ds-1.3) ... Setting up libhtml-tagset-perl (3.24-1) ... Setting up libdebhelper-perl (13.20) ... Setting up libbrotli1:amd64 (1.1.0-2+b4) ... Setting up liblwp-mediatypes-perl (6.04-2) ... Setting up libmagic1t64:amd64 (1:5.45-3) ... Setting up libtry-tiny-perl (0.32-1) ... Setting up libpsl5t64:amd64 (0.21.2-1.1) ... Setting up libnghttp2-14:amd64 (1.63.0-1) ... Setting up perl-openssl-defaults:amd64 (7+b2) ... Setting up gettext-base (0.22.5-2) ... Setting up m4 (1.4.19-4) ... Setting up libencode-locale-perl (1.05-3) ... Setting up libcom-err2:amd64 (1.47.1-1) ... Setting up file (1:5.45-3) ... Setting up ubuntu-keyring (2023.11.28.1-0.2) ... Setting up pbzip2 (1.1.13-1) ... Setting up libelf1t64:amd64 (0.191-2) ... Setting up libkrb5support0:amd64 (1.21.3-3) ... Setting up libsasl2-modules-db:amd64 (2.1.28+dfsg1-8) ... Setting up tzdata (2024a-4) ... Current default time zone: 'Etc/UTC' Local time is now: Sun Sep 15 15:30:08 UTC 2024. Universal Time is now: Sun Sep 15 15:30:08 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:amd64 (5.3.128~dfsg-2.1) ... Setting up autotools-dev (20220109.1) ... Setting up libglib2.0-0t64:amd64 (2.82.0-1) ... No schema files found: doing nothing. Setting up gnupg-l10n (2.2.43-8) ... Setting up ed (1.20.2-2) ... Setting up librtmp1:amd64 (2.4+20151223.gitfa8646d.1-2+b4) ... Setting up bash-completion (1:2.14.0-1) ... Setting up diffstat (1.66-1) ... Setting up libio-html-perl (1.004-3) ... Setting up autopoint (0.22.5-2) ... Setting up libb-hooks-op-check-perl:amd64 (0.22-3+b1) ... Setting up sudo (1.9.15p5-3+b1) ... 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:amd64 (1.21.3-3) ... Setting up libsasl2-2:amd64 (2.1.28+dfsg1-8) ... Setting up autoconf (2.72-3) ... Setting up libnghttp3-9:amd64 (1.4.0-1) ... Setting up libtimedate-perl (2.3300-2) ... Setting up dwz (0.15-1+b1) ... Setting up python-apt-common (2.9.0) ... Setting up sensible-utils (0.0.24) ... Setting up xdelta3 (3.0.11-dfsg-1.2) ... Setting up libuchardet0:amd64 (0.0.8-1+b1) ... Setting up libassuan9:amd64 (3.0.1-2) ... Setting up librole-tiny-perl (2.002004-1) ... Setting up git-man (1:2.45.2-1) ... Setting up netbase (6.4) ... Setting up libngtcp2-16:amd64 (1.6.0-1) ... Setting up libsub-quote-perl (2.006008-1) ... Setting up libclass-xsaccessor-perl (1.19-4+b3) ... Setting up libkrb5-3:amd64 (1.21.3-3) ... Setting up libssh2-1t64:amd64 (1.11.0-7) ... 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-1) ... Setting up readline-common (8.2-5) ... Setting up libxml2:amd64 (2.12.7+dfsg-3+b1) ... Setting up liburi-perl (5.29-1) ... Setting up libfile-touch-perl (0.12-2) ... Setting up libngtcp2-crypto-gnutls8:amd64 (1.6.0-1) ... Setting up dctrl-tools (2.24-3+b1) ... Setting up libhttp-parser2.9:amd64 (2.9.4-6+b1) ... Setting up libnet-ssleay-perl:amd64 (1.94-1+b1) ... 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.7) ... Setting up libhttp-date-perl (6.06-1) ... Setting up gettext (0.22.5-2) ... Setting up libmbedx509-1t64:amd64 (2.28.8-1) ... Setting up libxdelta2t64:amd64 (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-7) ... Setting up libnet-http-perl (6.23-1) ... Setting up quilt (0.68-1) ... Setting up libdevel-callchecker-perl:amd64 (0.009-1) ... Setting up libldap-2.5-0:amd64 (2.5.18+dfsg-3) ... Setting up intltool-debian (0.35.0+20060710.6) ... Setting up dh-autoreconf (20) ... Setting up patchutils (0.4.2-1) ... Setting up ca-certificates (20240203) ... Updating certificates in /etc/ssl/certs... 146 added, 0 removed; done. Setting up libgssapi-krb5-2:amd64 (1.21.3-3) ... Setting up libreadline8t64:amd64 (8.2-5) ... Setting up dh-strip-nondeterminism (1.14.0-1) ... Setting up libwww-robotrules-perl (6.02-1) ... Setting up libmbedtls14t64:amd64 (2.28.8-1) ... Setting up groff-base (1.23.0-5) ... Setting up libhtml-parser-perl:amd64 (3.83-1) ... Setting up gpgconf (2.2.43-8+b1) ... Setting up libgit2-1.7:amd64 (1.7.2+ds-1+b2) ... Setting up libarchive13t64:amd64 (3.7.4-1) ... Setting up libio-socket-ssl-perl (2.089-1) ... Setting up gpg (2.2.43-8+b1) ... Setting up libhttp-message-perl (6.46-1) ... Setting up libhttp-negotiate-perl (6.01-2) ... Setting up gpg-agent (2.2.43-8+b1) ... Setting up libzmq5:amd64 (4.3.5-1+b2) ... Setting up libtirpc3t64:amd64 (1.3.4+ds-1.3) ... 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:amd64 (0.015-2+b3) ... Setting up gpgsm (2.2.43-8+b1) ... Setting up libcurl3t64-gnutls:amd64 (8.10.0-2) ... Setting up man-db (2.13.0-1) ... Not building database; man-db/auto-update is not 'true'. Setting up dirmngr (2.2.43-8+b1) ... Setting up libmodule-runtime-perl (0.016-2) ... Setting up git (1:2.45.2-1) ... Setting up libnsl2:amd64 (1.3.0-3+b2) ... Setting up pixz (1.0.7-3) ... Setting up gnupg (2.2.43-8) ... Setting up libgpgme11t64:amd64 (1.18.0-6+b1) ... Setting up pristine-tar (1.50+nmu2) ... Setting up libpython3.12-stdlib:amd64 (3.12.6-1) ... Setting up libimport-into-perl (1.002005-2) ... Setting up libmoo-perl (2.005005-1) ... Setting up python3.12 (3.12.6-1) ... Setting up debhelper (13.20) ... Setting up dh-exec (0.30) ... Setting up libpython3-stdlib:amd64 (3.12.5-1+b1) ... Setting up python3 (3.12.5-1+b1) ... Setting up python3-zipp (3.20.1-1) ... Setting up python3-xdg (0.28-2) ... Setting up python3-autocommand (2.2.2-3) ... Setting up python3-six (1.16.0-7) ... Setting up python3-packaging (24.1-1) ... Setting up python3-pyparsing (3.1.2-1) ... Setting up python3-gpg (1.18.0-6+b1) ... Setting up python3-certifi (2024.8.30-1) ... Setting up python3-idna (3.6-2.1) ... Setting up python3-typing-extensions (4.12.2-2) ... Setting up python3-jeepney (0.8.0-3) ... Setting up python3-urllib3 (2.0.7-2) ... Setting up python3-pluggy (1.5.0-1) ... Setting up python3-httplib2 (0.22.0-1) ... Setting up python3-dateutil (2.9.0-2) ... Setting up python3-distro-info (1.7) ... Setting up python3-systemd (235-1+b4) ... Setting up python3-cffi-backend:amd64 (1.17.1-1) ... Setting up python3-blinker (1.8.2-1) ... Setting up python3-more-itertools (10.4.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.4.0-1) ... Setting up python3-jaraco.functools (4.0.2-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.0+b1) ... Setting up python3-charset-normalizer (3.3.2-3) ... Setting up python3-pytest (8.3.3-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-1) ... Setting up python3-typeguard (4.3.0-1) ... Setting up python3-yaml (6.0.2-1) ... Setting up python3-inflect (7.3.1-1) ... Setting up python3-cryptography (43.0.0-1) ... Setting up python3-pkg-resources (74.1.2-2) ... Setting up python3-setuptools (74.1.2-2) ... Setting up python3-py (1.11.0-2) ... Setting up python3-pygit2 (1.14.1-1) ... Setting up python3-lazr.uri (1.0.6-4) ... Setting up python3-oauthlib (3.2.2-1) ... Setting up python3-chardet (5.2.0+dfsg-1) ... Setting up python3-secretstorage (3.3.3-3) ... Setting up python3-zmq (24.0.1-5+b2) ... Setting up python3-wadllib (1.3.6-5) ... Setting up python3-debian (0.1.49) ... Setting up python3-requests (2.32.3+dfsg-1) ... Setting up python3-keyring (25.3.0-1) ... Setting up python3-lazr.restfulclient (0.14.6-2) ... Setting up dh-python (6.20240824) ... Setting up python3-launchpadlib (2.0.0-1) ... Setting up dput (1.2.2) ... Setting up python3-launchpadlib-desktop (2.0.0-1) ... Setting up python3-keyrings.alt (5.0.2-1) ... Setting up python3-ubuntutools (0.202) ... Setting up libwww-perl (6.77-1) ... Setting up devscripts (2.23.7) ... Setting up git-buildpackage (0.9.34) ... Setting up liblwp-protocol-https-perl (6.14-1) ... Setting up ubuntu-dev-tools (0.202) ... Processing triggers for libc-bin (2.40-2) ... 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-1_source.changes dpkg-buildpackage: info: source package git-ubuntu dpkg-buildpackage: info: source version 1.1-1 dpkg-buildpackage: info: source distribution unstable dpkg-buildpackage: info: source changed by Benjamin Drung dpkg-source --before-build . dpkg-buildpackage: info: host architecture amd64 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-x86_64' 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/prepare_upload.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 copying gitubuntu/dsc.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/patch_state.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/source_information.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/rich_history_test.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/versioning.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/importer_service.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/submit.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/tag.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_tag_test.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/merge.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/scriptutils.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/build.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/spec.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/importer_service_poller.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/importer_service_broker.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/repo_builder.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/source_builder.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/remote.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/logging.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.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/source_builder_test.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 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.6, pytest-8.3.3, pluggy-1.5.0 rootdir: /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build configfile: pytest.ini plugins: typeguard-4.3.0 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': '6277ba0650104b4f3e329b42e855e558', '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: 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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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: 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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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: 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 0x7fed3bc1ed50>, '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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: 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 0x7fed3bc1f470>, '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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: 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 0x7fed3bc1f950>, '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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: 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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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: 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...x7fed3bc215b0>}, '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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: 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...x7fed3bc20110>}, '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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 = 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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '02fa18f407af7561c7ece62b3bb065de', 'size': '616', '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6277ba0650104b4f3e329b42e855e558', '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: 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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '586d016620a36e376ba593f7d04c65a7', 'size': '532', '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '42f45abeea1602cef6a688c18d5e609d', 'size': '532', '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '586d016620a36e376ba593f7d04c65a7', 'size': '532', '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': 'cea292acf3ad676cbb618c117cab87ff', 'size': '532', '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '747671b312c2077100fc1e9c1c5c3d7d', 'size': '532', '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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': '6ab50bf391c280c3a594770334672747', 'size': '532', '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:1841: in git_run return git_run( /build/reproducible-path/git-ubuntu-1.1/.pybuild/cpython3_3.12/build/gitubuntu/git_repository.py:267: 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 622.03s (0:10:22) == 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/2388579 and its subdirectories Sun Sep 15 15:44:19 UTC 2024 W: No second build log, what happened?