I: pbuilder: network access will be disabled during build I: Current time: Thu May 23 23:47:22 -12 2024 I: pbuilder-time-stamp: 1716551242 I: Building the build Environment I: extracting base tarball [/var/cache/pbuilder/bookworm-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 [locust_2.12.1-1.dsc] I: copying [./locust_2.12.1.orig.tar.xz] I: copying [./locust_2.12.1-1.debian.tar.xz] I: Extracting source gpgv: Signature made Fri Dec 23 18:00:51 2022 -12 gpgv: using RSA key B9FAD3192AF3E4A5309D9D39879F3C993801A94F gpgv: Can't check signature: No public key dpkg-source: warning: cannot verify inline signature for ./locust_2.12.1-1.dsc: no acceptable signature found dpkg-source: info: extracting locust in locust-2.12.1 dpkg-source: info: unpacking locust_2.12.1.orig.tar.xz dpkg-source: info: unpacking locust_2.12.1-1.debian.tar.xz dpkg-source: info: using patch list from debian/patches/series dpkg-source: info: applying doc-no-cli-output-or-sphinx-search.patch I: using fakeroot in build. I: Installing the build-deps I: user script /srv/workspace/pbuilder/178780/tmp/hooks/D02_print_environment starting I: set BUILDDIR='/build' 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=16' DISTRIBUTION='bookworm' HOME='/root' HOST_ARCH='amd64' IFS=' ' INVOCATION_ID='2759a2bcdce74a738b216ddfcab8c3d8' 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='178780' 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.IrjmrTS1/pbuilderrc_X28S --distribution bookworm --hookdir /etc/pbuilder/first-build-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/bookworm-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/r-b-build.IrjmrTS1/b1 --logfile b1/build.log locust_2.12.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://85.184.249.68:3128' I: uname -a Linux ionos15-amd64 6.1.0-0.deb11.5-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.12-1~bpo11+1 (2023-03-05) x86_64 GNU/Linux I: ls -l /bin total 5632 -rwxr-xr-x 1 root root 1265648 Feb 12 2023 bash -rwxr-xr-x 3 root root 39224 Sep 18 2022 bunzip2 -rwxr-xr-x 3 root root 39224 Sep 18 2022 bzcat lrwxrwxrwx 1 root root 6 Sep 18 2022 bzcmp -> bzdiff -rwxr-xr-x 1 root root 2225 Sep 18 2022 bzdiff lrwxrwxrwx 1 root root 6 Sep 18 2022 bzegrep -> bzgrep -rwxr-xr-x 1 root root 4893 Nov 27 2021 bzexe lrwxrwxrwx 1 root root 6 Sep 18 2022 bzfgrep -> bzgrep -rwxr-xr-x 1 root root 3775 Sep 18 2022 bzgrep -rwxr-xr-x 3 root root 39224 Sep 18 2022 bzip2 -rwxr-xr-x 1 root root 14568 Sep 18 2022 bzip2recover lrwxrwxrwx 1 root root 6 Sep 18 2022 bzless -> bzmore -rwxr-xr-x 1 root root 1297 Sep 18 2022 bzmore -rwxr-xr-x 1 root root 44016 Sep 20 2022 cat -rwxr-xr-x 1 root root 68656 Sep 20 2022 chgrp -rwxr-xr-x 1 root root 64496 Sep 20 2022 chmod -rwxr-xr-x 1 root root 72752 Sep 20 2022 chown -rwxr-xr-x 1 root root 151152 Sep 20 2022 cp -rwxr-xr-x 1 root root 125640 Jan 5 2023 dash -rwxr-xr-x 1 root root 121904 Sep 20 2022 date -rwxr-xr-x 1 root root 89240 Sep 20 2022 dd -rwxr-xr-x 1 root root 102200 Sep 20 2022 df -rwxr-xr-x 1 root root 151344 Sep 20 2022 dir -rwxr-xr-x 1 root root 88656 Mar 22 2023 dmesg lrwxrwxrwx 1 root root 8 Dec 19 2022 dnsdomainname -> hostname lrwxrwxrwx 1 root root 8 Dec 19 2022 domainname -> hostname -rwxr-xr-x 1 root root 43856 Sep 20 2022 echo -rwxr-xr-x 1 root root 41 Jan 24 2023 egrep -rwxr-xr-x 1 root root 35664 Sep 20 2022 false -rwxr-xr-x 1 root root 41 Jan 24 2023 fgrep -rwxr-xr-x 1 root root 85600 Mar 22 2023 findmnt -rwsr-xr-x 1 root root 35128 Mar 22 2023 fusermount -rwxr-xr-x 1 root root 203152 Jan 24 2023 grep -rwxr-xr-x 2 root root 2346 Apr 9 2022 gunzip -rwxr-xr-x 1 root root 6447 Apr 9 2022 gzexe -rwxr-xr-x 1 root root 98136 Apr 9 2022 gzip -rwxr-xr-x 1 root root 22680 Dec 19 2022 hostname -rwxr-xr-x 1 root root 72824 Sep 20 2022 ln -rwxr-xr-x 1 root root 53024 Mar 23 2023 login -rwxr-xr-x 1 root root 151344 Sep 20 2022 ls -rwxr-xr-x 1 root root 207168 Mar 22 2023 lsblk -rwxr-xr-x 1 root root 97552 Sep 20 2022 mkdir -rwxr-xr-x 1 root root 72912 Sep 20 2022 mknod -rwxr-xr-x 1 root root 43952 Sep 20 2022 mktemp -rwxr-xr-x 1 root root 59712 Mar 22 2023 more -rwsr-xr-x 1 root root 59704 Mar 22 2023 mount -rwxr-xr-x 1 root root 18744 Mar 22 2023 mountpoint -rwxr-xr-x 1 root root 142968 Sep 20 2022 mv lrwxrwxrwx 1 root root 8 Dec 19 2022 nisdomainname -> hostname lrwxrwxrwx 1 root root 14 Apr 2 2023 pidof -> /sbin/killall5 -rwxr-xr-x 1 root root 43952 Sep 20 2022 pwd lrwxrwxrwx 1 root root 4 Feb 12 2023 rbash -> bash -rwxr-xr-x 1 root root 52112 Sep 20 2022 readlink -rwxr-xr-x 1 root root 72752 Sep 20 2022 rm -rwxr-xr-x 1 root root 56240 Sep 20 2022 rmdir -rwxr-xr-x 1 root root 27560 Nov 2 2022 run-parts -rwxr-xr-x 1 root root 126424 Jan 5 2023 sed lrwxrwxrwx 1 root root 4 Jan 5 2023 sh -> dash -rwxr-xr-x 1 root root 43888 Sep 20 2022 sleep -rwxr-xr-x 1 root root 85008 Sep 20 2022 stty -rwsr-xr-x 1 root root 72000 Mar 22 2023 su -rwxr-xr-x 1 root root 39824 Sep 20 2022 sync -rwxr-xr-x 1 root root 531984 Apr 6 2023 tar -rwxr-xr-x 1 root root 14520 Nov 2 2022 tempfile -rwxr-xr-x 1 root root 109616 Sep 20 2022 touch -rwxr-xr-x 1 root root 35664 Sep 20 2022 true -rwxr-xr-x 1 root root 14568 Mar 22 2023 ulockmgr_server -rwsr-xr-x 1 root root 35128 Mar 22 2023 umount -rwxr-xr-x 1 root root 43888 Sep 20 2022 uname -rwxr-xr-x 2 root root 2346 Apr 9 2022 uncompress -rwxr-xr-x 1 root root 151344 Sep 20 2022 vdir -rwxr-xr-x 1 root root 72024 Mar 22 2023 wdctl lrwxrwxrwx 1 root root 8 Dec 19 2022 ypdomainname -> hostname -rwxr-xr-x 1 root root 1984 Apr 9 2022 zcat -rwxr-xr-x 1 root root 1678 Apr 9 2022 zcmp -rwxr-xr-x 1 root root 6460 Apr 9 2022 zdiff -rwxr-xr-x 1 root root 29 Apr 9 2022 zegrep -rwxr-xr-x 1 root root 29 Apr 9 2022 zfgrep -rwxr-xr-x 1 root root 2081 Apr 9 2022 zforce -rwxr-xr-x 1 root root 8103 Apr 9 2022 zgrep -rwxr-xr-x 1 root root 2206 Apr 9 2022 zless -rwxr-xr-x 1 root root 1842 Apr 9 2022 zmore -rwxr-xr-x 1 root root 4577 Apr 9 2022 znew I: user script /srv/workspace/pbuilder/178780/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: debhelper-compat (= 13), pybuild-plugin-pyproject, python3-all, python3-configargparse (>= 1.0), python3-cryptography, python3-flask-basicauth (>= 0.2.0), python3-flask-cors, python3-geventhttpclient (>= 2.0.8), python3-mock, python3-msgpack (>= 0.6.2), python3-psutil (>= 5.6.7), python3-pyquery (>= 1.4.3), python3-pytest, python3-requests (>= 2.9.1), python3-retry, python3-roundrobin, python3-setuptools, python3-typing-extensions, python3-zmq (>= 16.0.2) dpkg-deb: building package 'pbuilder-satisfydepends-dummy' in '/tmp/satisfydepends-aptitude/pbuilder-satisfydepends-dummy.deb'. Selecting previously unselected package pbuilder-satisfydepends-dummy. (Reading database ... 19596 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 debhelper-compat (= 13); however: Package debhelper-compat is not installed. pbuilder-satisfydepends-dummy depends on pybuild-plugin-pyproject; however: Package pybuild-plugin-pyproject is not installed. pbuilder-satisfydepends-dummy depends on python3-all; however: Package python3-all is not installed. pbuilder-satisfydepends-dummy depends on python3-configargparse (>= 1.0); however: Package python3-configargparse is not installed. pbuilder-satisfydepends-dummy depends on python3-cryptography; however: Package python3-cryptography is not installed. pbuilder-satisfydepends-dummy depends on python3-flask-basicauth (>= 0.2.0); however: Package python3-flask-basicauth is not installed. pbuilder-satisfydepends-dummy depends on python3-flask-cors; however: Package python3-flask-cors is not installed. pbuilder-satisfydepends-dummy depends on python3-geventhttpclient (>= 2.0.8); however: Package python3-geventhttpclient is not installed. pbuilder-satisfydepends-dummy depends on python3-mock; however: Package python3-mock is not installed. pbuilder-satisfydepends-dummy depends on python3-msgpack (>= 0.6.2); however: Package python3-msgpack is not installed. pbuilder-satisfydepends-dummy depends on python3-psutil (>= 5.6.7); however: Package python3-psutil is not installed. pbuilder-satisfydepends-dummy depends on python3-pyquery (>= 1.4.3); however: Package python3-pyquery is not installed. pbuilder-satisfydepends-dummy depends on python3-pytest; however: Package python3-pytest is not installed. pbuilder-satisfydepends-dummy depends on python3-requests (>= 2.9.1); however: Package python3-requests is not installed. pbuilder-satisfydepends-dummy depends on python3-retry; however: Package python3-retry is not installed. pbuilder-satisfydepends-dummy depends on python3-roundrobin; however: Package python3-roundrobin is not installed. pbuilder-satisfydepends-dummy depends on python3-setuptools; however: Package python3-setuptools is not installed. pbuilder-satisfydepends-dummy depends on python3-typing-extensions; however: Package python3-typing-extensions is not installed. pbuilder-satisfydepends-dummy depends on python3-zmq (>= 16.0.2); however: Package python3-zmq 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} bsdextrautils{a} ca-certificates{a} debhelper{a} dh-autoreconf{a} dh-python{a} dh-strip-nondeterminism{a} dwz{a} file{a} fonts-font-awesome{a} fonts-lato{a} gettext{a} gettext-base{a} groff-base{a} intltool-debian{a} libarchive-zip-perl{a} libbsd0{a} libc-ares2{a} libdebhelper-perl{a} libelf1{a} libev4{a} libexpat1{a} libfile-stripnondeterminism-perl{a} libicu72{a} libjs-jquery{a} libjs-sphinxdoc{a} libjs-underscore{a} libmagic-mgc{a} libmagic1{a} libnorm1{a} libpgm-5.3-0{a} libpipeline1{a} libpython3-stdlib{a} libpython3.11-minimal{a} libpython3.11-stdlib{a} libreadline8{a} libsodium23{a} libsub-override-perl{a} libtool{a} libuchardet0{a} libxml2{a} libxslt1.1{a} libzmq5{a} m4{a} man-db{a} media-types{a} openssl{a} po-debconf{a} pybuild-plugin-pyproject{a} python3{a} python3-all{a} python3-attr{a} python3-brotli{a} python3-build{a} python3-certifi{a} python3-cffi-backend{a} python3-chardet{a} python3-charset-normalizer{a} python3-click{a} python3-colorama{a} python3-configargparse{a} python3-cryptography{a} python3-cssselect{a} python3-decorator{a} python3-distutils{a} python3-flask{a} python3-flask-basicauth{a} python3-flask-cors{a} python3-gevent{a} python3-geventhttpclient{a} python3-greenlet{a} python3-idna{a} python3-importlib-metadata{a} python3-iniconfig{a} python3-installer{a} python3-itsdangerous{a} python3-jinja2{a} python3-lib2to3{a} python3-lxml{a} python3-markupsafe{a} python3-minimal{a} python3-mock{a} python3-more-itertools{a} python3-msgpack{a} python3-packaging{a} python3-pbr{a} python3-pep517{a} python3-pkg-resources{a} python3-pluggy{a} python3-psutil{a} python3-py{a} python3-pyquery{a} python3-pytest{a} python3-requests{a} python3-retry{a} python3-roundrobin{a} python3-setuptools{a} python3-six{a} python3-toml{a} python3-tomli{a} python3-typing-extensions{a} python3-urllib3{a} python3-webob{a} python3-werkzeug{a} python3-wheel{a} python3-zipp{a} python3-zmq{a} python3-zope.event{a} python3-zope.interface{a} python3.11{a} python3.11-minimal{a} readline-common{a} sensible-utils{a} sphinx-rtd-theme-common{a} The following packages are RECOMMENDED but will NOT be installed: curl javascript-common libarchive-cpio-perl libltdl-dev libmail-sendmail-perl lynx python3-asgiref python3-babel python3-blinker python3-bs4 python3-dotenv python3-html5lib python3-openssl python3-pygments python3-pyinotify python3-simplejson wget 0 packages upgraded, 117 newly installed, 0 to remove and 0 not upgraded. Need to get 39.3 MB of archives. After unpacking 149 MB will be used. Writing extended state information... Get: 1 http://deb.debian.org/debian bookworm/main amd64 fonts-lato all 2.0-2.1 [2696 kB] Get: 2 http://deb.debian.org/debian bookworm/main amd64 libpython3.11-minimal amd64 3.11.2-6 [813 kB] Get: 3 http://deb.debian.org/debian bookworm/main amd64 libexpat1 amd64 2.5.0-1 [99.3 kB] Get: 4 http://deb.debian.org/debian bookworm/main amd64 python3.11-minimal amd64 3.11.2-6 [2064 kB] Get: 5 http://deb.debian.org/debian bookworm/main amd64 python3-minimal amd64 3.11.2-1+b1 [26.3 kB] Get: 6 http://deb.debian.org/debian bookworm/main amd64 media-types all 10.0.0 [26.1 kB] Get: 7 http://deb.debian.org/debian bookworm/main amd64 readline-common all 8.2-1.3 [69.0 kB] Get: 8 http://deb.debian.org/debian bookworm/main amd64 libreadline8 amd64 8.2-1.3 [166 kB] Get: 9 http://deb.debian.org/debian bookworm/main amd64 libpython3.11-stdlib amd64 3.11.2-6 [1796 kB] Get: 10 http://deb.debian.org/debian bookworm/main amd64 python3.11 amd64 3.11.2-6 [572 kB] Get: 11 http://deb.debian.org/debian bookworm/main amd64 libpython3-stdlib amd64 3.11.2-1+b1 [9312 B] Get: 12 http://deb.debian.org/debian bookworm/main amd64 python3 amd64 3.11.2-1+b1 [26.3 kB] Get: 13 http://deb.debian.org/debian bookworm/main amd64 sensible-utils all 0.0.17+nmu1 [19.0 kB] Get: 14 http://deb.debian.org/debian bookworm/main amd64 openssl amd64 3.0.8-1 [1407 kB] Get: 15 http://deb.debian.org/debian bookworm/main amd64 ca-certificates all 20230311 [153 kB] Get: 16 http://deb.debian.org/debian bookworm/main amd64 libmagic-mgc amd64 1:5.44-3 [305 kB] Get: 17 http://deb.debian.org/debian bookworm/main amd64 libmagic1 amd64 1:5.44-3 [104 kB] Get: 18 http://deb.debian.org/debian bookworm/main amd64 file amd64 1:5.44-3 [42.5 kB] Get: 19 http://deb.debian.org/debian bookworm/main amd64 gettext-base amd64 0.21-12 [160 kB] Get: 20 http://deb.debian.org/debian bookworm/main amd64 libuchardet0 amd64 0.0.7-1 [67.8 kB] Get: 21 http://deb.debian.org/debian bookworm/main amd64 groff-base amd64 1.22.4-10 [916 kB] Get: 22 http://deb.debian.org/debian bookworm/main amd64 bsdextrautils amd64 2.38.1-5+b1 [86.6 kB] Get: 23 http://deb.debian.org/debian bookworm/main amd64 libpipeline1 amd64 1.5.7-1 [38.5 kB] Get: 24 http://deb.debian.org/debian bookworm/main amd64 man-db amd64 2.11.2-2 [1386 kB] Get: 25 http://deb.debian.org/debian bookworm/main amd64 m4 amd64 1.4.19-3 [287 kB] Get: 26 http://deb.debian.org/debian bookworm/main amd64 autoconf all 2.71-3 [332 kB] Get: 27 http://deb.debian.org/debian bookworm/main amd64 autotools-dev all 20220109.1 [51.6 kB] Get: 28 http://deb.debian.org/debian bookworm/main amd64 automake all 1:1.16.5-1.3 [823 kB] Get: 29 http://deb.debian.org/debian bookworm/main amd64 autopoint all 0.21-12 [495 kB] Get: 30 http://deb.debian.org/debian bookworm/main amd64 libdebhelper-perl all 13.11.4 [81.2 kB] Get: 31 http://deb.debian.org/debian bookworm/main amd64 libtool all 2.4.7-5 [517 kB] Get: 32 http://deb.debian.org/debian bookworm/main amd64 dh-autoreconf all 20 [17.1 kB] Get: 33 http://deb.debian.org/debian bookworm/main amd64 libarchive-zip-perl all 1.68-1 [104 kB] Get: 34 http://deb.debian.org/debian bookworm/main amd64 libsub-override-perl all 0.09-4 [9304 B] Get: 35 http://deb.debian.org/debian bookworm/main amd64 libfile-stripnondeterminism-perl all 1.13.1-1 [19.4 kB] Get: 36 http://deb.debian.org/debian bookworm/main amd64 dh-strip-nondeterminism all 1.13.1-1 [8620 B] Get: 37 http://deb.debian.org/debian bookworm/main amd64 libelf1 amd64 0.188-2.1 [174 kB] Get: 38 http://deb.debian.org/debian bookworm/main amd64 dwz amd64 0.15-1 [109 kB] Get: 39 http://deb.debian.org/debian bookworm/main amd64 libicu72 amd64 72.1-3 [9376 kB] Get: 40 http://deb.debian.org/debian bookworm/main amd64 libxml2 amd64 2.9.14+dfsg-1.1+b3 [687 kB] Get: 41 http://deb.debian.org/debian bookworm/main amd64 gettext amd64 0.21-12 [1300 kB] Get: 42 http://deb.debian.org/debian bookworm/main amd64 intltool-debian all 0.35.0+20060710.6 [22.9 kB] Get: 43 http://deb.debian.org/debian bookworm/main amd64 po-debconf all 1.0.21+nmu1 [248 kB] Get: 44 http://deb.debian.org/debian bookworm/main amd64 debhelper all 13.11.4 [942 kB] Get: 45 http://deb.debian.org/debian bookworm/main amd64 python3-lib2to3 all 3.11.2-2 [76.2 kB] Get: 46 http://deb.debian.org/debian bookworm/main amd64 python3-distutils all 3.11.2-2 [131 kB] Get: 47 http://deb.debian.org/debian bookworm/main amd64 dh-python all 5.20230130 [104 kB] Get: 48 http://deb.debian.org/debian bookworm/main amd64 fonts-font-awesome all 5.0.10+really4.7.0~dfsg-4.1 [517 kB] Get: 49 http://deb.debian.org/debian bookworm/main amd64 libbsd0 amd64 0.11.7-2 [117 kB] Get: 50 http://deb.debian.org/debian bookworm/main amd64 libc-ares2 amd64 1.18.1-2 [102 kB] Get: 51 http://deb.debian.org/debian bookworm/main amd64 libev4 amd64 1:4.33-1 [43.2 kB] Get: 52 http://deb.debian.org/debian bookworm/main amd64 libjs-jquery all 3.6.1+dfsg+~3.5.14-1 [326 kB] Get: 53 http://deb.debian.org/debian bookworm/main amd64 libjs-underscore all 1.13.4~dfsg+~1.11.4-3 [116 kB] Get: 54 http://deb.debian.org/debian bookworm/main amd64 libjs-sphinxdoc all 5.3.0-4 [130 kB] Get: 55 http://deb.debian.org/debian bookworm/main amd64 libnorm1 amd64 1.5.9+dfsg-2 [221 kB] Get: 56 http://deb.debian.org/debian bookworm/main amd64 libpgm-5.3-0 amd64 5.3.128~dfsg-2 [161 kB] Get: 57 http://deb.debian.org/debian bookworm/main amd64 libsodium23 amd64 1.0.18-1 [161 kB] Get: 58 http://deb.debian.org/debian bookworm/main amd64 libxslt1.1 amd64 1.1.35-1 [242 kB] Get: 59 http://deb.debian.org/debian bookworm/main amd64 libzmq5 amd64 4.3.4-6 [273 kB] Get: 60 http://deb.debian.org/debian bookworm/main amd64 python3-typing-extensions all 4.4.0-1 [45.2 kB] Get: 61 http://deb.debian.org/debian bookworm/main amd64 python3-more-itertools all 8.10.0-2 [53.0 kB] Get: 62 http://deb.debian.org/debian bookworm/main amd64 python3-zipp all 1.0.0-6 [6696 B] Get: 63 http://deb.debian.org/debian bookworm/main amd64 python3-importlib-metadata all 4.12.0-1 [24.9 kB] Get: 64 http://deb.debian.org/debian bookworm/main amd64 python3-packaging all 23.0-1 [32.5 kB] Get: 65 http://deb.debian.org/debian bookworm/main amd64 python3-tomli all 2.0.1-2 [17.9 kB] Get: 66 http://deb.debian.org/debian bookworm/main amd64 python3-pep517 all 0.13.0-2 [17.4 kB] Get: 67 http://deb.debian.org/debian bookworm/main amd64 python3-toml all 0.10.2-1 [16.2 kB] Get: 68 http://deb.debian.org/debian bookworm/main amd64 python3-wheel all 0.38.4-2 [30.8 kB] Get: 69 http://deb.debian.org/debian bookworm/main amd64 python3-build all 0.9.0-1 [20.7 kB] Get: 70 http://deb.debian.org/debian bookworm/main amd64 python3-installer all 0.6.0+dfsg1-1 [18.1 kB] Get: 71 http://deb.debian.org/debian bookworm/main amd64 pybuild-plugin-pyproject all 5.20230130 [9092 B] Get: 72 http://deb.debian.org/debian bookworm/main amd64 python3-all amd64 3.11.2-1+b1 [1056 B] Get: 73 http://deb.debian.org/debian bookworm/main amd64 python3-attr all 22.2.0-1 [65.4 kB] Get: 74 http://deb.debian.org/debian bookworm/main amd64 python3-brotli amd64 1.0.9-2+b6 [281 kB] Get: 75 http://deb.debian.org/debian bookworm/main amd64 python3-certifi all 2022.9.24-1 [153 kB] Get: 76 http://deb.debian.org/debian bookworm/main amd64 python3-cffi-backend amd64 1.15.1-5+b1 [84.6 kB] Get: 77 http://deb.debian.org/debian bookworm/main amd64 python3-pkg-resources all 66.1.1-1 [296 kB] Get: 78 http://deb.debian.org/debian bookworm/main amd64 python3-chardet all 5.1.0+dfsg-2 [110 kB] Get: 79 http://deb.debian.org/debian bookworm/main amd64 python3-charset-normalizer all 3.0.1-2 [49.3 kB] Get: 80 http://deb.debian.org/debian bookworm/main amd64 python3-colorama all 0.4.6-2 [36.8 kB] Get: 81 http://deb.debian.org/debian bookworm/main amd64 python3-click all 8.1.3-2 [92.2 kB] Get: 82 http://deb.debian.org/debian bookworm/main amd64 python3-configargparse all 1.5.3-1 [26.1 kB] Get: 83 http://deb.debian.org/debian bookworm/main amd64 python3-cryptography amd64 38.0.4-3 [666 kB] Get: 84 http://deb.debian.org/debian bookworm/main amd64 python3-cssselect all 1.2.0-2 [21.6 kB] Get: 85 http://deb.debian.org/debian bookworm/main amd64 python3-decorator all 5.1.1-3 [14.9 kB] Get: 86 http://deb.debian.org/debian bookworm/main amd64 python3-itsdangerous all 2.1.2-3 [17.0 kB] Get: 87 http://deb.debian.org/debian bookworm/main amd64 python3-markupsafe amd64 2.1.2-1+b1 [13.2 kB] Get: 88 http://deb.debian.org/debian bookworm/main amd64 python3-jinja2 all 3.1.2-1 [119 kB] Get: 89 http://deb.debian.org/debian bookworm/main amd64 python3-werkzeug all 2.2.2-2 [205 kB] Get: 90 http://deb.debian.org/debian bookworm/main amd64 python3-flask all 2.2.2-2 [105 kB] Get: 91 http://deb.debian.org/debian bookworm/main amd64 python3-flask-basicauth all 0.2.0-3 [26.2 kB] Get: 92 http://deb.debian.org/debian bookworm/main amd64 python3-six all 1.16.0-4 [17.5 kB] Get: 93 http://deb.debian.org/debian bookworm/main amd64 sphinx-rtd-theme-common all 1.2.0+dfsg-1 [997 kB] Get: 94 http://deb.debian.org/debian bookworm/main amd64 python3-flask-cors all 3.0.10-2 [43.3 kB] Get: 95 http://deb.debian.org/debian bookworm/main amd64 python3-greenlet amd64 2.0.2-1 [142 kB] Get: 96 http://deb.debian.org/debian bookworm/main amd64 python3-zope.event all 4.4-3 [9420 B] Get: 97 http://deb.debian.org/debian bookworm/main amd64 python3-zope.interface amd64 5.5.2-1+b1 [152 kB] Get: 98 http://deb.debian.org/debian bookworm/main amd64 python3-gevent amd64 22.10.2-3 [748 kB] Get: 99 http://deb.debian.org/debian bookworm/main amd64 python3-geventhttpclient amd64 2.0.8-1+b1 [38.9 kB] Get: 100 http://deb.debian.org/debian bookworm/main amd64 python3-idna all 3.3-1 [39.4 kB] Get: 101 http://deb.debian.org/debian bookworm/main amd64 python3-iniconfig all 1.1.1-2 [6396 B] Get: 102 http://deb.debian.org/debian bookworm/main amd64 python3-lxml amd64 4.9.2-1+b1 [1194 kB] Get: 103 http://deb.debian.org/debian bookworm/main amd64 python3-setuptools all 66.1.1-1 [521 kB] Get: 104 http://deb.debian.org/debian bookworm/main amd64 python3-pbr all 5.10.0-2 [61.4 kB] Get: 105 http://deb.debian.org/debian bookworm/main amd64 python3-mock all 4.0.3-4 [64.0 kB] Get: 106 http://deb.debian.org/debian bookworm/main amd64 python3-msgpack amd64 1.0.3-2+b1 [67.3 kB] Get: 107 http://deb.debian.org/debian bookworm/main amd64 python3-pluggy all 1.0.0+repack-1 [19.7 kB] Get: 108 http://deb.debian.org/debian bookworm/main amd64 python3-psutil amd64 5.9.4-1+b1 [189 kB] Get: 109 http://deb.debian.org/debian bookworm/main amd64 python3-py all 1.11.0-1 [89.2 kB] Get: 110 http://deb.debian.org/debian bookworm/main amd64 python3-webob all 1:1.8.6-3 [87.8 kB] Get: 111 http://deb.debian.org/debian bookworm/main amd64 python3-pyquery all 1.4.3-1 [23.1 kB] Get: 112 http://deb.debian.org/debian bookworm/main amd64 python3-pytest all 7.2.1-2 [236 kB] Get: 113 http://deb.debian.org/debian bookworm/main amd64 python3-urllib3 all 1.26.12-1 [117 kB] Get: 114 http://deb.debian.org/debian bookworm/main amd64 python3-requests all 2.28.1+dfsg-1 [67.9 kB] Get: 115 http://deb.debian.org/debian bookworm/main amd64 python3-retry all 0.9.2-2 [7020 B] Get: 116 http://deb.debian.org/debian bookworm/main amd64 python3-roundrobin all 0.0.4-2 [4324 B] Get: 117 http://deb.debian.org/debian bookworm/main amd64 python3-zmq amd64 24.0.1-4+b1 [263 kB] Fetched 39.3 MB in 1s (30.3 MB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package fonts-lato. (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 ... 19596 files and directories currently installed.) Preparing to unpack .../fonts-lato_2.0-2.1_all.deb ... Unpacking fonts-lato (2.0-2.1) ... Selecting previously unselected package libpython3.11-minimal:amd64. Preparing to unpack .../libpython3.11-minimal_3.11.2-6_amd64.deb ... Unpacking libpython3.11-minimal:amd64 (3.11.2-6) ... Selecting previously unselected package libexpat1:amd64. Preparing to unpack .../libexpat1_2.5.0-1_amd64.deb ... Unpacking libexpat1:amd64 (2.5.0-1) ... Selecting previously unselected package python3.11-minimal. Preparing to unpack .../python3.11-minimal_3.11.2-6_amd64.deb ... Unpacking python3.11-minimal (3.11.2-6) ... Setting up libpython3.11-minimal:amd64 (3.11.2-6) ... Setting up libexpat1:amd64 (2.5.0-1) ... Setting up python3.11-minimal (3.11.2-6) ... 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 ... 19938 files and directories currently installed.) Preparing to unpack .../0-python3-minimal_3.11.2-1+b1_amd64.deb ... Unpacking python3-minimal (3.11.2-1+b1) ... Selecting previously unselected package media-types. Preparing to unpack .../1-media-types_10.0.0_all.deb ... Unpacking media-types (10.0.0) ... Selecting previously unselected package readline-common. Preparing to unpack .../2-readline-common_8.2-1.3_all.deb ... Unpacking readline-common (8.2-1.3) ... Selecting previously unselected package libreadline8:amd64. Preparing to unpack .../3-libreadline8_8.2-1.3_amd64.deb ... Unpacking libreadline8:amd64 (8.2-1.3) ... Selecting previously unselected package libpython3.11-stdlib:amd64. Preparing to unpack .../4-libpython3.11-stdlib_3.11.2-6_amd64.deb ... Unpacking libpython3.11-stdlib:amd64 (3.11.2-6) ... Selecting previously unselected package python3.11. Preparing to unpack .../5-python3.11_3.11.2-6_amd64.deb ... Unpacking python3.11 (3.11.2-6) ... Selecting previously unselected package libpython3-stdlib:amd64. Preparing to unpack .../6-libpython3-stdlib_3.11.2-1+b1_amd64.deb ... Unpacking libpython3-stdlib:amd64 (3.11.2-1+b1) ... Setting up python3-minimal (3.11.2-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 ... 20372 files and directories currently installed.) Preparing to unpack .../000-python3_3.11.2-1+b1_amd64.deb ... Unpacking python3 (3.11.2-1+b1) ... Selecting previously unselected package sensible-utils. Preparing to unpack .../001-sensible-utils_0.0.17+nmu1_all.deb ... Unpacking sensible-utils (0.0.17+nmu1) ... Selecting previously unselected package openssl. Preparing to unpack .../002-openssl_3.0.8-1_amd64.deb ... Unpacking openssl (3.0.8-1) ... Selecting previously unselected package ca-certificates. Preparing to unpack .../003-ca-certificates_20230311_all.deb ... Unpacking ca-certificates (20230311) ... Selecting previously unselected package libmagic-mgc. Preparing to unpack .../004-libmagic-mgc_1%3a5.44-3_amd64.deb ... Unpacking libmagic-mgc (1:5.44-3) ... Selecting previously unselected package libmagic1:amd64. Preparing to unpack .../005-libmagic1_1%3a5.44-3_amd64.deb ... Unpacking libmagic1:amd64 (1:5.44-3) ... Selecting previously unselected package file. Preparing to unpack .../006-file_1%3a5.44-3_amd64.deb ... Unpacking file (1:5.44-3) ... Selecting previously unselected package gettext-base. Preparing to unpack .../007-gettext-base_0.21-12_amd64.deb ... Unpacking gettext-base (0.21-12) ... Selecting previously unselected package libuchardet0:amd64. Preparing to unpack .../008-libuchardet0_0.0.7-1_amd64.deb ... Unpacking libuchardet0:amd64 (0.0.7-1) ... Selecting previously unselected package groff-base. Preparing to unpack .../009-groff-base_1.22.4-10_amd64.deb ... Unpacking groff-base (1.22.4-10) ... Selecting previously unselected package bsdextrautils. Preparing to unpack .../010-bsdextrautils_2.38.1-5+b1_amd64.deb ... Unpacking bsdextrautils (2.38.1-5+b1) ... Selecting previously unselected package libpipeline1:amd64. Preparing to unpack .../011-libpipeline1_1.5.7-1_amd64.deb ... Unpacking libpipeline1:amd64 (1.5.7-1) ... Selecting previously unselected package man-db. Preparing to unpack .../012-man-db_2.11.2-2_amd64.deb ... Unpacking man-db (2.11.2-2) ... Selecting previously unselected package m4. Preparing to unpack .../013-m4_1.4.19-3_amd64.deb ... Unpacking m4 (1.4.19-3) ... Selecting previously unselected package autoconf. Preparing to unpack .../014-autoconf_2.71-3_all.deb ... Unpacking autoconf (2.71-3) ... Selecting previously unselected package autotools-dev. Preparing to unpack .../015-autotools-dev_20220109.1_all.deb ... Unpacking autotools-dev (20220109.1) ... Selecting previously unselected package automake. Preparing to unpack .../016-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 .../017-autopoint_0.21-12_all.deb ... Unpacking autopoint (0.21-12) ... Selecting previously unselected package libdebhelper-perl. Preparing to unpack .../018-libdebhelper-perl_13.11.4_all.deb ... Unpacking libdebhelper-perl (13.11.4) ... Selecting previously unselected package libtool. Preparing to unpack .../019-libtool_2.4.7-5_all.deb ... Unpacking libtool (2.4.7-5) ... Selecting previously unselected package dh-autoreconf. Preparing to unpack .../020-dh-autoreconf_20_all.deb ... Unpacking dh-autoreconf (20) ... Selecting previously unselected package libarchive-zip-perl. Preparing to unpack .../021-libarchive-zip-perl_1.68-1_all.deb ... Unpacking libarchive-zip-perl (1.68-1) ... Selecting previously unselected package libsub-override-perl. Preparing to unpack .../022-libsub-override-perl_0.09-4_all.deb ... Unpacking libsub-override-perl (0.09-4) ... Selecting previously unselected package libfile-stripnondeterminism-perl. Preparing to unpack .../023-libfile-stripnondeterminism-perl_1.13.1-1_all.deb ... Unpacking libfile-stripnondeterminism-perl (1.13.1-1) ... Selecting previously unselected package dh-strip-nondeterminism. Preparing to unpack .../024-dh-strip-nondeterminism_1.13.1-1_all.deb ... Unpacking dh-strip-nondeterminism (1.13.1-1) ... Selecting previously unselected package libelf1:amd64. Preparing to unpack .../025-libelf1_0.188-2.1_amd64.deb ... Unpacking libelf1:amd64 (0.188-2.1) ... Selecting previously unselected package dwz. Preparing to unpack .../026-dwz_0.15-1_amd64.deb ... Unpacking dwz (0.15-1) ... Selecting previously unselected package libicu72:amd64. Preparing to unpack .../027-libicu72_72.1-3_amd64.deb ... Unpacking libicu72:amd64 (72.1-3) ... Selecting previously unselected package libxml2:amd64. Preparing to unpack .../028-libxml2_2.9.14+dfsg-1.1+b3_amd64.deb ... Unpacking libxml2:amd64 (2.9.14+dfsg-1.1+b3) ... Selecting previously unselected package gettext. Preparing to unpack .../029-gettext_0.21-12_amd64.deb ... Unpacking gettext (0.21-12) ... Selecting previously unselected package intltool-debian. Preparing to unpack .../030-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 .../031-po-debconf_1.0.21+nmu1_all.deb ... Unpacking po-debconf (1.0.21+nmu1) ... Selecting previously unselected package debhelper. Preparing to unpack .../032-debhelper_13.11.4_all.deb ... Unpacking debhelper (13.11.4) ... Selecting previously unselected package python3-lib2to3. Preparing to unpack .../033-python3-lib2to3_3.11.2-2_all.deb ... Unpacking python3-lib2to3 (3.11.2-2) ... Selecting previously unselected package python3-distutils. Preparing to unpack .../034-python3-distutils_3.11.2-2_all.deb ... Unpacking python3-distutils (3.11.2-2) ... Selecting previously unselected package dh-python. Preparing to unpack .../035-dh-python_5.20230130_all.deb ... Unpacking dh-python (5.20230130) ... Selecting previously unselected package fonts-font-awesome. Preparing to unpack .../036-fonts-font-awesome_5.0.10+really4.7.0~dfsg-4.1_all.deb ... Unpacking fonts-font-awesome (5.0.10+really4.7.0~dfsg-4.1) ... Selecting previously unselected package libbsd0:amd64. Preparing to unpack .../037-libbsd0_0.11.7-2_amd64.deb ... Unpacking libbsd0:amd64 (0.11.7-2) ... Selecting previously unselected package libc-ares2:amd64. Preparing to unpack .../038-libc-ares2_1.18.1-2_amd64.deb ... Unpacking libc-ares2:amd64 (1.18.1-2) ... Selecting previously unselected package libev4:amd64. Preparing to unpack .../039-libev4_1%3a4.33-1_amd64.deb ... Unpacking libev4:amd64 (1:4.33-1) ... Selecting previously unselected package libjs-jquery. Preparing to unpack .../040-libjs-jquery_3.6.1+dfsg+~3.5.14-1_all.deb ... Unpacking libjs-jquery (3.6.1+dfsg+~3.5.14-1) ... Selecting previously unselected package libjs-underscore. Preparing to unpack .../041-libjs-underscore_1.13.4~dfsg+~1.11.4-3_all.deb ... Unpacking libjs-underscore (1.13.4~dfsg+~1.11.4-3) ... Selecting previously unselected package libjs-sphinxdoc. Preparing to unpack .../042-libjs-sphinxdoc_5.3.0-4_all.deb ... Unpacking libjs-sphinxdoc (5.3.0-4) ... Selecting previously unselected package libnorm1:amd64. Preparing to unpack .../043-libnorm1_1.5.9+dfsg-2_amd64.deb ... Unpacking libnorm1:amd64 (1.5.9+dfsg-2) ... Selecting previously unselected package libpgm-5.3-0:amd64. Preparing to unpack .../044-libpgm-5.3-0_5.3.128~dfsg-2_amd64.deb ... Unpacking libpgm-5.3-0:amd64 (5.3.128~dfsg-2) ... Selecting previously unselected package libsodium23:amd64. Preparing to unpack .../045-libsodium23_1.0.18-1_amd64.deb ... Unpacking libsodium23:amd64 (1.0.18-1) ... Selecting previously unselected package libxslt1.1:amd64. Preparing to unpack .../046-libxslt1.1_1.1.35-1_amd64.deb ... Unpacking libxslt1.1:amd64 (1.1.35-1) ... Selecting previously unselected package libzmq5:amd64. Preparing to unpack .../047-libzmq5_4.3.4-6_amd64.deb ... Unpacking libzmq5:amd64 (4.3.4-6) ... Selecting previously unselected package python3-typing-extensions. Preparing to unpack .../048-python3-typing-extensions_4.4.0-1_all.deb ... Unpacking python3-typing-extensions (4.4.0-1) ... Selecting previously unselected package python3-more-itertools. Preparing to unpack .../049-python3-more-itertools_8.10.0-2_all.deb ... Unpacking python3-more-itertools (8.10.0-2) ... Selecting previously unselected package python3-zipp. Preparing to unpack .../050-python3-zipp_1.0.0-6_all.deb ... Unpacking python3-zipp (1.0.0-6) ... Selecting previously unselected package python3-importlib-metadata. Preparing to unpack .../051-python3-importlib-metadata_4.12.0-1_all.deb ... Unpacking python3-importlib-metadata (4.12.0-1) ... Selecting previously unselected package python3-packaging. Preparing to unpack .../052-python3-packaging_23.0-1_all.deb ... Unpacking python3-packaging (23.0-1) ... Selecting previously unselected package python3-tomli. Preparing to unpack .../053-python3-tomli_2.0.1-2_all.deb ... Unpacking python3-tomli (2.0.1-2) ... Selecting previously unselected package python3-pep517. Preparing to unpack .../054-python3-pep517_0.13.0-2_all.deb ... Unpacking python3-pep517 (0.13.0-2) ... Selecting previously unselected package python3-toml. Preparing to unpack .../055-python3-toml_0.10.2-1_all.deb ... Unpacking python3-toml (0.10.2-1) ... Selecting previously unselected package python3-wheel. Preparing to unpack .../056-python3-wheel_0.38.4-2_all.deb ... Unpacking python3-wheel (0.38.4-2) ... Selecting previously unselected package python3-build. Preparing to unpack .../057-python3-build_0.9.0-1_all.deb ... Unpacking python3-build (0.9.0-1) ... Selecting previously unselected package python3-installer. Preparing to unpack .../058-python3-installer_0.6.0+dfsg1-1_all.deb ... Unpacking python3-installer (0.6.0+dfsg1-1) ... Selecting previously unselected package pybuild-plugin-pyproject. Preparing to unpack .../059-pybuild-plugin-pyproject_5.20230130_all.deb ... Unpacking pybuild-plugin-pyproject (5.20230130) ... Selecting previously unselected package python3-all. Preparing to unpack .../060-python3-all_3.11.2-1+b1_amd64.deb ... Unpacking python3-all (3.11.2-1+b1) ... Selecting previously unselected package python3-attr. Preparing to unpack .../061-python3-attr_22.2.0-1_all.deb ... Unpacking python3-attr (22.2.0-1) ... Selecting previously unselected package python3-brotli. Preparing to unpack .../062-python3-brotli_1.0.9-2+b6_amd64.deb ... Unpacking python3-brotli (1.0.9-2+b6) ... Selecting previously unselected package python3-certifi. Preparing to unpack .../063-python3-certifi_2022.9.24-1_all.deb ... Unpacking python3-certifi (2022.9.24-1) ... Selecting previously unselected package python3-cffi-backend:amd64. Preparing to unpack .../064-python3-cffi-backend_1.15.1-5+b1_amd64.deb ... Unpacking python3-cffi-backend:amd64 (1.15.1-5+b1) ... Selecting previously unselected package python3-pkg-resources. Preparing to unpack .../065-python3-pkg-resources_66.1.1-1_all.deb ... Unpacking python3-pkg-resources (66.1.1-1) ... Selecting previously unselected package python3-chardet. Preparing to unpack .../066-python3-chardet_5.1.0+dfsg-2_all.deb ... Unpacking python3-chardet (5.1.0+dfsg-2) ... Selecting previously unselected package python3-charset-normalizer. Preparing to unpack .../067-python3-charset-normalizer_3.0.1-2_all.deb ... Unpacking python3-charset-normalizer (3.0.1-2) ... Selecting previously unselected package python3-colorama. Preparing to unpack .../068-python3-colorama_0.4.6-2_all.deb ... Unpacking python3-colorama (0.4.6-2) ... Selecting previously unselected package python3-click. Preparing to unpack .../069-python3-click_8.1.3-2_all.deb ... Unpacking python3-click (8.1.3-2) ... Selecting previously unselected package python3-configargparse. Preparing to unpack .../070-python3-configargparse_1.5.3-1_all.deb ... Unpacking python3-configargparse (1.5.3-1) ... Selecting previously unselected package python3-cryptography. Preparing to unpack .../071-python3-cryptography_38.0.4-3_amd64.deb ... Unpacking python3-cryptography (38.0.4-3) ... Selecting previously unselected package python3-cssselect. Preparing to unpack .../072-python3-cssselect_1.2.0-2_all.deb ... Unpacking python3-cssselect (1.2.0-2) ... Selecting previously unselected package python3-decorator. Preparing to unpack .../073-python3-decorator_5.1.1-3_all.deb ... Unpacking python3-decorator (5.1.1-3) ... Selecting previously unselected package python3-itsdangerous. Preparing to unpack .../074-python3-itsdangerous_2.1.2-3_all.deb ... Unpacking python3-itsdangerous (2.1.2-3) ... Selecting previously unselected package python3-markupsafe. Preparing to unpack .../075-python3-markupsafe_2.1.2-1+b1_amd64.deb ... Unpacking python3-markupsafe (2.1.2-1+b1) ... Selecting previously unselected package python3-jinja2. Preparing to unpack .../076-python3-jinja2_3.1.2-1_all.deb ... Unpacking python3-jinja2 (3.1.2-1) ... Selecting previously unselected package python3-werkzeug. Preparing to unpack .../077-python3-werkzeug_2.2.2-2_all.deb ... Unpacking python3-werkzeug (2.2.2-2) ... Selecting previously unselected package python3-flask. Preparing to unpack .../078-python3-flask_2.2.2-2_all.deb ... Unpacking python3-flask (2.2.2-2) ... Selecting previously unselected package python3-flask-basicauth. Preparing to unpack .../079-python3-flask-basicauth_0.2.0-3_all.deb ... Unpacking python3-flask-basicauth (0.2.0-3) ... Selecting previously unselected package python3-six. Preparing to unpack .../080-python3-six_1.16.0-4_all.deb ... Unpacking python3-six (1.16.0-4) ... Selecting previously unselected package sphinx-rtd-theme-common. Preparing to unpack .../081-sphinx-rtd-theme-common_1.2.0+dfsg-1_all.deb ... Unpacking sphinx-rtd-theme-common (1.2.0+dfsg-1) ... Selecting previously unselected package python3-flask-cors. Preparing to unpack .../082-python3-flask-cors_3.0.10-2_all.deb ... Unpacking python3-flask-cors (3.0.10-2) ... Selecting previously unselected package python3-greenlet. Preparing to unpack .../083-python3-greenlet_2.0.2-1_amd64.deb ... Unpacking python3-greenlet (2.0.2-1) ... Selecting previously unselected package python3-zope.event. Preparing to unpack .../084-python3-zope.event_4.4-3_all.deb ... Unpacking python3-zope.event (4.4-3) ... Selecting previously unselected package python3-zope.interface. Preparing to unpack .../085-python3-zope.interface_5.5.2-1+b1_amd64.deb ... Unpacking python3-zope.interface (5.5.2-1+b1) ... Selecting previously unselected package python3-gevent. Preparing to unpack .../086-python3-gevent_22.10.2-3_amd64.deb ... Unpacking python3-gevent (22.10.2-3) ... Selecting previously unselected package python3-geventhttpclient. Preparing to unpack .../087-python3-geventhttpclient_2.0.8-1+b1_amd64.deb ... Unpacking python3-geventhttpclient (2.0.8-1+b1) ... Selecting previously unselected package python3-idna. Preparing to unpack .../088-python3-idna_3.3-1_all.deb ... Unpacking python3-idna (3.3-1) ... Selecting previously unselected package python3-iniconfig. Preparing to unpack .../089-python3-iniconfig_1.1.1-2_all.deb ... Unpacking python3-iniconfig (1.1.1-2) ... Selecting previously unselected package python3-lxml:amd64. Preparing to unpack .../090-python3-lxml_4.9.2-1+b1_amd64.deb ... Unpacking python3-lxml:amd64 (4.9.2-1+b1) ... Selecting previously unselected package python3-setuptools. Preparing to unpack .../091-python3-setuptools_66.1.1-1_all.deb ... Unpacking python3-setuptools (66.1.1-1) ... Selecting previously unselected package python3-pbr. Preparing to unpack .../092-python3-pbr_5.10.0-2_all.deb ... Unpacking python3-pbr (5.10.0-2) ... Selecting previously unselected package python3-mock. Preparing to unpack .../093-python3-mock_4.0.3-4_all.deb ... Unpacking python3-mock (4.0.3-4) ... Selecting previously unselected package python3-msgpack. Preparing to unpack .../094-python3-msgpack_1.0.3-2+b1_amd64.deb ... Unpacking python3-msgpack (1.0.3-2+b1) ... Selecting previously unselected package python3-pluggy. Preparing to unpack .../095-python3-pluggy_1.0.0+repack-1_all.deb ... Unpacking python3-pluggy (1.0.0+repack-1) ... Selecting previously unselected package python3-psutil. Preparing to unpack .../096-python3-psutil_5.9.4-1+b1_amd64.deb ... Unpacking python3-psutil (5.9.4-1+b1) ... Selecting previously unselected package python3-py. Preparing to unpack .../097-python3-py_1.11.0-1_all.deb ... Unpacking python3-py (1.11.0-1) ... Selecting previously unselected package python3-webob. Preparing to unpack .../098-python3-webob_1%3a1.8.6-3_all.deb ... Unpacking python3-webob (1:1.8.6-3) ... Selecting previously unselected package python3-pyquery. Preparing to unpack .../099-python3-pyquery_1.4.3-1_all.deb ... Unpacking python3-pyquery (1.4.3-1) ... Selecting previously unselected package python3-pytest. Preparing to unpack .../100-python3-pytest_7.2.1-2_all.deb ... Unpacking python3-pytest (7.2.1-2) ... Selecting previously unselected package python3-urllib3. Preparing to unpack .../101-python3-urllib3_1.26.12-1_all.deb ... Unpacking python3-urllib3 (1.26.12-1) ... Selecting previously unselected package python3-requests. Preparing to unpack .../102-python3-requests_2.28.1+dfsg-1_all.deb ... Unpacking python3-requests (2.28.1+dfsg-1) ... Selecting previously unselected package python3-retry. Preparing to unpack .../103-python3-retry_0.9.2-2_all.deb ... Unpacking python3-retry (0.9.2-2) ... Selecting previously unselected package python3-roundrobin. Preparing to unpack .../104-python3-roundrobin_0.0.4-2_all.deb ... Unpacking python3-roundrobin (0.0.4-2) ... Selecting previously unselected package python3-zmq. Preparing to unpack .../105-python3-zmq_24.0.1-4+b1_amd64.deb ... Unpacking python3-zmq (24.0.1-4+b1) ... Setting up media-types (10.0.0) ... Setting up libpipeline1:amd64 (1.5.7-1) ... Setting up fonts-lato (2.0-2.1) ... Setting up libsodium23:amd64 (1.0.18-1) ... Setting up libicu72:amd64 (72.1-3) ... Setting up bsdextrautils (2.38.1-5+b1) ... Setting up libmagic-mgc (1:5.44-3) ... Setting up libarchive-zip-perl (1.68-1) ... Setting up libpgm-5.3-0:amd64 (5.3.128~dfsg-2) ... Setting up libev4:amd64 (1:4.33-1) ... Setting up libdebhelper-perl (13.11.4) ... Setting up libnorm1:amd64 (1.5.9+dfsg-2) ... Setting up libmagic1:amd64 (1:5.44-3) ... Setting up gettext-base (0.21-12) ... Setting up m4 (1.4.19-3) ... Setting up libc-ares2:amd64 (1.18.1-2) ... Setting up file (1:5.44-3) ... Setting up autotools-dev (20220109.1) ... Setting up autopoint (0.21-12) ... Setting up autoconf (2.71-3) ... Setting up sensible-utils (0.0.17+nmu1) ... Setting up libuchardet0:amd64 (0.0.7-1) ... Setting up libsub-override-perl (0.09-4) ... Setting up libjs-jquery (3.6.1+dfsg+~3.5.14-1) ... Setting up openssl (3.0.8-1) ... Setting up libbsd0:amd64 (0.11.7-2) ... Setting up libelf1:amd64 (0.188-2.1) ... Setting up readline-common (8.2-1.3) ... Setting up libxml2:amd64 (2.9.14+dfsg-1.1+b3) ... Setting up fonts-font-awesome (5.0.10+really4.7.0~dfsg-4.1) ... Setting up sphinx-rtd-theme-common (1.2.0+dfsg-1) ... Setting up libjs-underscore (1.13.4~dfsg+~1.11.4-3) ... 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 libfile-stripnondeterminism-perl (1.13.1-1) ... Setting up gettext (0.21-12) ... Setting up libzmq5:amd64 (4.3.4-6) ... Setting up libtool (2.4.7-5) ... Setting up libreadline8:amd64 (8.2-1.3) ... Setting up intltool-debian (0.35.0+20060710.6) ... Setting up dh-autoreconf (20) ... Setting up ca-certificates (20230311) ... Updating certificates in /etc/ssl/certs... 140 added, 0 removed; done. Setting up libjs-sphinxdoc (5.3.0-4) ... Setting up dh-strip-nondeterminism (1.13.1-1) ... Setting up dwz (0.15-1) ... Setting up groff-base (1.22.4-10) ... Setting up libxslt1.1:amd64 (1.1.35-1) ... Setting up po-debconf (1.0.21+nmu1) ... Setting up libpython3.11-stdlib:amd64 (3.11.2-6) ... Setting up man-db (2.11.2-2) ... Not building database; man-db/auto-update is not 'true'. Setting up libpython3-stdlib:amd64 (3.11.2-1+b1) ... Setting up python3.11 (3.11.2-6) ... Setting up debhelper (13.11.4) ... Setting up python3 (3.11.2-1+b1) ... Setting up python3-roundrobin (0.0.4-2) ... Setting up python3-markupsafe (2.1.2-1+b1) ... Setting up python3-psutil (5.9.4-1+b1) ... Setting up python3-six (1.16.0-4) ... Setting up python3-decorator (5.1.1-3) ... Setting up python3-jinja2 (3.1.2-1) ... Setting up python3-packaging (23.0-1) ... Setting up python3-certifi (2022.9.24-1) ... Setting up python3-werkzeug (2.2.2-2) ... Setting up python3-brotli (1.0.9-2+b6) ... Setting up python3-greenlet (2.0.2-1) ... Setting up python3-idna (3.3-1) ... Setting up python3-typing-extensions (4.4.0-1) ... Setting up python3-toml (0.10.2-1) ... Setting up python3-installer (0.6.0+dfsg1-1) ... Setting up python3-urllib3 (1.26.12-1) ... Setting up python3-pluggy (1.0.0+repack-1) ... Setting up python3-lxml:amd64 (4.9.2-1+b1) ... Setting up python3-msgpack (1.0.3-2+b1) ... Setting up python3-cssselect (1.2.0-2) ... Setting up python3-lib2to3 (3.11.2-2) ... Setting up python3-cffi-backend:amd64 (1.15.1-5+b1) ... Setting up python3-webob (1:1.8.6-3) ... Setting up python3-pkg-resources (66.1.1-1) ... Setting up python3-distutils (3.11.2-2) ... Setting up dh-python (5.20230130) ... Setting up python3-more-itertools (8.10.0-2) ... Setting up python3-configargparse (1.5.3-1) ... Setting up python3-iniconfig (1.1.1-2) ... Setting up python3-attr (22.2.0-1) ... Setting up python3-setuptools (66.1.1-1) ... Setting up python3-tomli (2.0.1-2) ... Setting up python3-py (1.11.0-1) ... Setting up python3-colorama (0.4.6-2) ... Setting up python3-zope.event (4.4-3) ... Setting up python3-zope.interface (5.5.2-1+b1) ... Setting up python3-pbr (5.10.0-2) ... Setting up python3-pyquery (1.4.3-1) ... Setting up python3-charset-normalizer (3.0.1-2) ... Setting up python3-pytest (7.2.1-2) ... Setting up python3-itsdangerous (2.1.2-3) ... Setting up python3-all (3.11.2-1+b1) ... Setting up python3-gevent (22.10.2-3) ... Setting up python3-zipp (1.0.0-6) ... Setting up python3-click (8.1.3-2) ... Setting up python3-wheel (0.38.4-2) ... Setting up python3-mock (4.0.3-4) ... Setting up python3-chardet (5.1.0+dfsg-2) ... Setting up python3-zmq (24.0.1-4+b1) ... Setting up python3-cryptography (38.0.4-3) ... Setting up python3-requests (2.28.1+dfsg-1) ... Setting up python3-retry (0.9.2-2) ... Setting up python3-geventhttpclient (2.0.8-1+b1) ... Setting up python3-importlib-metadata (4.12.0-1) ... Setting up python3-flask (2.2.2-2) ... Setting up python3-flask-cors (3.0.10-2) ... Setting up python3-pep517 (0.13.0-2) ... Setting up python3-flask-basicauth (0.2.0-3) ... Setting up python3-build (0.9.0-1) ... Setting up pybuild-plugin-pyproject (5.20230130) ... Processing triggers for libc-bin (2.36-9) ... Processing triggers for ca-certificates (20230311) ... 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 Reading package lists... Building dependency tree... Reading state information... fakeroot is already the newest version (1.31-1.2). 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. I: Building the package I: Running cd /build/locust-2.12.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 > ../locust_2.12.1-1_source.changes dpkg-buildpackage: info: source package locust dpkg-buildpackage: info: source version 2.12.1-1 dpkg-buildpackage: info: source distribution unstable dpkg-buildpackage: info: source changed by Sandro Tosi dpkg-source --before-build . dpkg-buildpackage: info: host architecture amd64 dpkg-source: info: using options from locust-2.12.1/debian/source/options: --extend-diff-ignore=^[^/]+.egg-info/ fakeroot debian/rules clean dh clean --with python3 --buildsystem=pybuild dh_auto_clean -O--buildsystem=pybuild dh_autoreconf_clean -O--buildsystem=pybuild debian/rules override_dh_clean make[1]: Entering directory '/build/locust-2.12.1' rm -f locust/_version.py dh_clean make[1]: Leaving directory '/build/locust-2.12.1' debian/rules build dh build --with python3 --buildsystem=pybuild dh_update_autotools_config -O--buildsystem=pybuild dh_autoreconf -O--buildsystem=pybuild dh_auto_configure -O--buildsystem=pybuild debian/rules execute_before_dh_auto_build make[1]: Entering directory '/build/locust-2.12.1' echo "version = ''" > locust/_version.py make[1]: Leaving directory '/build/locust-2.12.1' dh_auto_build -O--buildsystem=pybuild I: pybuild plugin_pyproject:107: Building wheel for python3.11 with "build" module I: pybuild base:240: python3.11 -m build --skip-dependency-check --no-isolation --wheel --outdir /build/locust-2.12.1/.pybuild/cpython3_3.11_locust * Building wheel... /usr/lib/python3/dist-packages/setuptools/config/setupcfg.py:515: SetuptoolsDeprecationWarning: The license_file parameter is deprecated, use license_files instead. warnings.warn(msg, warning_class) running bdist_wheel running build running build_py creating build creating build/lib creating build/lib/locust copying locust/_version.py -> build/lib/locust copying locust/web.py -> build/lib/locust copying locust/stats.py -> build/lib/locust copying locust/shape.py -> build/lib/locust copying locust/runners.py -> build/lib/locust copying locust/main.py -> build/lib/locust copying locust/log.py -> build/lib/locust copying locust/input_events.py -> build/lib/locust copying locust/html.py -> build/lib/locust copying locust/exception.py -> build/lib/locust copying locust/event.py -> build/lib/locust copying locust/env.py -> build/lib/locust copying locust/dispatch.py -> build/lib/locust copying locust/debug.py -> build/lib/locust copying locust/clients.py -> build/lib/locust copying locust/argument_parser.py -> build/lib/locust copying locust/__main__.py -> build/lib/locust copying locust/__init__.py -> build/lib/locust creating build/lib/locust/util copying locust/util/timespan.py -> build/lib/locust/util copying locust/util/rounding.py -> build/lib/locust/util copying locust/util/load_locustfile.py -> build/lib/locust/util copying locust/util/exception_handler.py -> build/lib/locust/util copying locust/util/deprecation.py -> build/lib/locust/util copying locust/util/cache.py -> build/lib/locust/util copying locust/util/__init__.py -> build/lib/locust/util creating build/lib/locust/user copying locust/user/wait_time.py -> build/lib/locust/user copying locust/user/users.py -> build/lib/locust/user copying locust/user/task.py -> build/lib/locust/user copying locust/user/sequential_taskset.py -> build/lib/locust/user copying locust/user/inspectuser.py -> build/lib/locust/user copying locust/user/__init__.py -> build/lib/locust/user creating build/lib/locust/test copying locust/test/util.py -> build/lib/locust/test copying locust/test/testcases.py -> build/lib/locust/test copying locust/test/test_zmqrpc.py -> build/lib/locust/test copying locust/test/test_web.py -> build/lib/locust/test copying locust/test/test_wait_time.py -> build/lib/locust/test copying locust/test/test_util.py -> build/lib/locust/test copying locust/test/test_users.py -> build/lib/locust/test copying locust/test/test_taskratio.py -> build/lib/locust/test copying locust/test/test_tags.py -> build/lib/locust/test copying locust/test/test_stats.py -> build/lib/locust/test copying locust/test/test_sequential_taskset.py -> build/lib/locust/test copying locust/test/test_runners.py -> build/lib/locust/test copying locust/test/test_parser.py -> build/lib/locust/test copying locust/test/test_old_wait_api.py -> build/lib/locust/test copying locust/test/test_main.py -> build/lib/locust/test copying locust/test/test_log.py -> build/lib/locust/test copying locust/test/test_locust_class.py -> build/lib/locust/test copying locust/test/test_load_locustfile.py -> build/lib/locust/test copying locust/test/test_http.py -> build/lib/locust/test copying locust/test/test_fasthttp.py -> build/lib/locust/test copying locust/test/test_env.py -> build/lib/locust/test copying locust/test/test_dispatch.py -> build/lib/locust/test copying locust/test/mock_logging.py -> build/lib/locust/test copying locust/test/mock_locustfile.py -> build/lib/locust/test copying locust/test/fake_module2_for_env_test.py -> build/lib/locust/test copying locust/test/fake_module1_for_env_test.py -> build/lib/locust/test copying locust/test/__init__.py -> build/lib/locust/test creating build/lib/locust/rpc copying locust/rpc/zmqrpc.py -> build/lib/locust/rpc copying locust/rpc/protocol.py -> build/lib/locust/rpc copying locust/rpc/__init__.py -> build/lib/locust/rpc creating build/lib/locust/contrib copying locust/contrib/fasthttp.py -> build/lib/locust/contrib copying locust/contrib/__init__.py -> build/lib/locust/contrib running egg_info creating locust.egg-info writing locust.egg-info/PKG-INFO writing dependency_links to locust.egg-info/dependency_links.txt writing entry points to locust.egg-info/entry_points.txt writing requirements to locust.egg-info/requires.txt writing top-level names to locust.egg-info/top_level.txt writing manifest file 'locust.egg-info/SOURCES.txt' reading manifest file 'locust.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' adding license file 'LICENSE' writing manifest file 'locust.egg-info/SOURCES.txt' /usr/lib/python3/dist-packages/setuptools/command/build_py.py:202: SetuptoolsDeprecationWarning: Installing 'locust.static' as data is deprecated, please list it in `packages`. !! ############################ # Package would be ignored # ############################ Python recognizes 'locust.static' as an importable package, but it is not listed in the `packages` configuration of setuptools. 'locust.static' has been automatically added to the distribution only because it may contain data files, but this behavior is likely to change in future versions of setuptools (and therefore is considered deprecated). Please make sure that 'locust.static' is included as a package by using the `packages` configuration field or the proper discovery methods (for example by using `find_namespace_packages(...)`/`find_namespace:` instead of `find_packages(...)`/`find:`). You can read more about "package discovery" and "data files" on setuptools documentation page. !! check.warn(importable) /usr/lib/python3/dist-packages/setuptools/command/build_py.py:202: SetuptoolsDeprecationWarning: Installing 'locust.static.css' as data is deprecated, please list it in `packages`. !! ############################ # Package would be ignored # ############################ Python recognizes 'locust.static.css' as an importable package, but it is not listed in the `packages` configuration of setuptools. 'locust.static.css' has been automatically added to the distribution only because it may contain data files, but this behavior is likely to change in future versions of setuptools (and therefore is considered deprecated). Please make sure that 'locust.static.css' is included as a package by using the `packages` configuration field or the proper discovery methods (for example by using `find_namespace_packages(...)`/`find_namespace:` instead of `find_packages(...)`/`find:`). You can read more about "package discovery" and "data files" on setuptools documentation page. !! check.warn(importable) /usr/lib/python3/dist-packages/setuptools/command/build_py.py:202: SetuptoolsDeprecationWarning: Installing 'locust.static.img' as data is deprecated, please list it in `packages`. !! ############################ # Package would be ignored # ############################ Python recognizes 'locust.static.img' as an importable package, but it is not listed in the `packages` configuration of setuptools. 'locust.static.img' has been automatically added to the distribution only because it may contain data files, but this behavior is likely to change in future versions of setuptools (and therefore is considered deprecated). Please make sure that 'locust.static.img' is included as a package by using the `packages` configuration field or the proper discovery methods (for example by using `find_namespace_packages(...)`/`find_namespace:` instead of `find_packages(...)`/`find:`). You can read more about "package discovery" and "data files" on setuptools documentation page. !! check.warn(importable) /usr/lib/python3/dist-packages/setuptools/command/build_py.py:202: SetuptoolsDeprecationWarning: Installing 'locust.static.sass' as data is deprecated, please list it in `packages`. !! ############################ # Package would be ignored # ############################ Python recognizes 'locust.static.sass' as an importable package, but it is not listed in the `packages` configuration of setuptools. 'locust.static.sass' has been automatically added to the distribution only because it may contain data files, but this behavior is likely to change in future versions of setuptools (and therefore is considered deprecated). Please make sure that 'locust.static.sass' is included as a package by using the `packages` configuration field or the proper discovery methods (for example by using `find_namespace_packages(...)`/`find_namespace:` instead of `find_packages(...)`/`find:`). You can read more about "package discovery" and "data files" on setuptools documentation page. !! check.warn(importable) /usr/lib/python3/dist-packages/setuptools/command/build_py.py:202: SetuptoolsDeprecationWarning: Installing 'locust.templates' as data is deprecated, please list it in `packages`. !! ############################ # Package would be ignored # ############################ Python recognizes 'locust.templates' as an importable package, but it is not listed in the `packages` configuration of setuptools. 'locust.templates' has been automatically added to the distribution only because it may contain data files, but this behavior is likely to change in future versions of setuptools (and therefore is considered deprecated). Please make sure that 'locust.templates' is included as a package by using the `packages` configuration field or the proper discovery methods (for example by using `find_namespace_packages(...)`/`find_namespace:` instead of `find_packages(...)`/`find:`). You can read more about "package discovery" and "data files" on setuptools documentation page. !! check.warn(importable) copying locust/py.typed -> build/lib/locust creating build/lib/locust/static copying locust/static/chart.js -> build/lib/locust/static copying locust/static/echarts.common.min.js -> build/lib/locust/static copying locust/static/jquery-1.11.3.min.js -> build/lib/locust/static copying locust/static/jquery.jqote2.min.js -> build/lib/locust/static copying locust/static/jquery.tools.min.js -> build/lib/locust/static copying locust/static/locust.js -> build/lib/locust/static copying locust/static/tasks.js -> build/lib/locust/static copying locust/static/vintage.js -> build/lib/locust/static creating build/lib/locust/static/css copying locust/static/css/application.css -> build/lib/locust/static/css copying locust/static/css/application.css.map -> build/lib/locust/static/css copying locust/static/css/tables.css -> build/lib/locust/static/css copying locust/static/css/tables.css.map -> build/lib/locust/static/css creating build/lib/locust/static/img copying locust/static/img/favicon.ico -> build/lib/locust/static/img copying locust/static/img/logo.png -> build/lib/locust/static/img copying locust/static/img/ui-screenshot-charts.png -> build/lib/locust/static/img copying locust/static/img/ui-screenshot-start-test.png -> build/lib/locust/static/img copying locust/static/img/ui-screenshot-stats.png -> build/lib/locust/static/img copying locust/static/img/ui-screenshot-workers.png -> build/lib/locust/static/img creating build/lib/locust/static/sass copying locust/static/sass/_base.sass -> build/lib/locust/static/sass copying locust/static/sass/_mixins.sass -> build/lib/locust/static/sass copying locust/static/sass/application.sass -> build/lib/locust/static/sass copying locust/static/sass/tables.sass -> build/lib/locust/static/sass creating build/lib/locust/templates copying locust/templates/index.html -> build/lib/locust/templates copying locust/templates/report.html -> build/lib/locust/templates copying locust/templates/stats_data.html -> build/lib/locust/templates installing to build/bdist.linux-x86_64/wheel running install running install_lib creating build/bdist.linux-x86_64 creating build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/locust creating build/bdist.linux-x86_64/wheel/locust/templates copying build/lib/locust/templates/stats_data.html -> build/bdist.linux-x86_64/wheel/locust/templates copying build/lib/locust/templates/report.html -> build/bdist.linux-x86_64/wheel/locust/templates copying build/lib/locust/templates/index.html -> build/bdist.linux-x86_64/wheel/locust/templates creating build/bdist.linux-x86_64/wheel/locust/static creating build/bdist.linux-x86_64/wheel/locust/static/sass copying build/lib/locust/static/sass/tables.sass -> build/bdist.linux-x86_64/wheel/locust/static/sass copying build/lib/locust/static/sass/application.sass -> build/bdist.linux-x86_64/wheel/locust/static/sass copying build/lib/locust/static/sass/_mixins.sass -> build/bdist.linux-x86_64/wheel/locust/static/sass copying build/lib/locust/static/sass/_base.sass -> build/bdist.linux-x86_64/wheel/locust/static/sass creating build/bdist.linux-x86_64/wheel/locust/static/img copying build/lib/locust/static/img/ui-screenshot-workers.png -> build/bdist.linux-x86_64/wheel/locust/static/img copying build/lib/locust/static/img/ui-screenshot-stats.png -> build/bdist.linux-x86_64/wheel/locust/static/img copying build/lib/locust/static/img/ui-screenshot-start-test.png -> build/bdist.linux-x86_64/wheel/locust/static/img copying build/lib/locust/static/img/ui-screenshot-charts.png -> build/bdist.linux-x86_64/wheel/locust/static/img copying build/lib/locust/static/img/logo.png -> build/bdist.linux-x86_64/wheel/locust/static/img copying build/lib/locust/static/img/favicon.ico -> build/bdist.linux-x86_64/wheel/locust/static/img creating build/bdist.linux-x86_64/wheel/locust/static/css copying build/lib/locust/static/css/tables.css.map -> build/bdist.linux-x86_64/wheel/locust/static/css copying build/lib/locust/static/css/tables.css -> build/bdist.linux-x86_64/wheel/locust/static/css copying build/lib/locust/static/css/application.css.map -> build/bdist.linux-x86_64/wheel/locust/static/css copying build/lib/locust/static/css/application.css -> build/bdist.linux-x86_64/wheel/locust/static/css copying build/lib/locust/static/vintage.js -> build/bdist.linux-x86_64/wheel/locust/static copying build/lib/locust/static/tasks.js -> build/bdist.linux-x86_64/wheel/locust/static copying build/lib/locust/static/locust.js -> build/bdist.linux-x86_64/wheel/locust/static copying build/lib/locust/static/jquery.tools.min.js -> build/bdist.linux-x86_64/wheel/locust/static copying build/lib/locust/static/jquery.jqote2.min.js -> build/bdist.linux-x86_64/wheel/locust/static copying build/lib/locust/static/jquery-1.11.3.min.js -> build/bdist.linux-x86_64/wheel/locust/static copying build/lib/locust/static/echarts.common.min.js -> build/bdist.linux-x86_64/wheel/locust/static copying build/lib/locust/static/chart.js -> build/bdist.linux-x86_64/wheel/locust/static copying build/lib/locust/py.typed -> build/bdist.linux-x86_64/wheel/locust creating build/bdist.linux-x86_64/wheel/locust/contrib copying build/lib/locust/contrib/__init__.py -> build/bdist.linux-x86_64/wheel/locust/contrib copying build/lib/locust/contrib/fasthttp.py -> build/bdist.linux-x86_64/wheel/locust/contrib creating build/bdist.linux-x86_64/wheel/locust/rpc copying build/lib/locust/rpc/__init__.py -> build/bdist.linux-x86_64/wheel/locust/rpc copying build/lib/locust/rpc/protocol.py -> build/bdist.linux-x86_64/wheel/locust/rpc copying build/lib/locust/rpc/zmqrpc.py -> build/bdist.linux-x86_64/wheel/locust/rpc creating build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/__init__.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/fake_module1_for_env_test.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/fake_module2_for_env_test.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/mock_locustfile.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/mock_logging.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_dispatch.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_env.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_fasthttp.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_http.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_load_locustfile.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_locust_class.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_log.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_main.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_old_wait_api.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_parser.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_runners.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_sequential_taskset.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_stats.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_tags.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_taskratio.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_users.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_util.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_wait_time.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_web.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/test_zmqrpc.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/testcases.py -> build/bdist.linux-x86_64/wheel/locust/test copying build/lib/locust/test/util.py -> build/bdist.linux-x86_64/wheel/locust/test creating build/bdist.linux-x86_64/wheel/locust/user copying build/lib/locust/user/__init__.py -> build/bdist.linux-x86_64/wheel/locust/user copying build/lib/locust/user/inspectuser.py -> build/bdist.linux-x86_64/wheel/locust/user copying build/lib/locust/user/sequential_taskset.py -> build/bdist.linux-x86_64/wheel/locust/user copying build/lib/locust/user/task.py -> build/bdist.linux-x86_64/wheel/locust/user copying build/lib/locust/user/users.py -> build/bdist.linux-x86_64/wheel/locust/user copying build/lib/locust/user/wait_time.py -> build/bdist.linux-x86_64/wheel/locust/user creating build/bdist.linux-x86_64/wheel/locust/util copying build/lib/locust/util/__init__.py -> build/bdist.linux-x86_64/wheel/locust/util copying build/lib/locust/util/cache.py -> build/bdist.linux-x86_64/wheel/locust/util copying build/lib/locust/util/deprecation.py -> build/bdist.linux-x86_64/wheel/locust/util copying build/lib/locust/util/exception_handler.py -> build/bdist.linux-x86_64/wheel/locust/util copying build/lib/locust/util/load_locustfile.py -> build/bdist.linux-x86_64/wheel/locust/util copying build/lib/locust/util/rounding.py -> build/bdist.linux-x86_64/wheel/locust/util copying build/lib/locust/util/timespan.py -> build/bdist.linux-x86_64/wheel/locust/util copying build/lib/locust/__init__.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/__main__.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/argument_parser.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/clients.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/debug.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/dispatch.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/env.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/event.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/exception.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/html.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/input_events.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/log.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/main.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/runners.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/shape.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/stats.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/web.py -> build/bdist.linux-x86_64/wheel/locust copying build/lib/locust/_version.py -> build/bdist.linux-x86_64/wheel/locust running install_egg_info Copying locust.egg-info to build/bdist.linux-x86_64/wheel/locust-0.0.0.egg-info running install_scripts creating build/bdist.linux-x86_64/wheel/locust-0.0.0.dist-info/WHEEL creating '/build/locust-2.12.1/.pybuild/cpython3_3.11_locust/.tmp-htbcdn_c/locust-0.0.0-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it adding 'locust/__init__.py' adding 'locust/__main__.py' adding 'locust/_version.py' adding 'locust/argument_parser.py' adding 'locust/clients.py' adding 'locust/debug.py' adding 'locust/dispatch.py' adding 'locust/env.py' adding 'locust/event.py' adding 'locust/exception.py' adding 'locust/html.py' adding 'locust/input_events.py' adding 'locust/log.py' adding 'locust/main.py' adding 'locust/py.typed' adding 'locust/runners.py' adding 'locust/shape.py' adding 'locust/stats.py' adding 'locust/web.py' adding 'locust/contrib/__init__.py' adding 'locust/contrib/fasthttp.py' adding 'locust/rpc/__init__.py' adding 'locust/rpc/protocol.py' adding 'locust/rpc/zmqrpc.py' adding 'locust/static/chart.js' adding 'locust/static/echarts.common.min.js' adding 'locust/static/jquery-1.11.3.min.js' adding 'locust/static/jquery.jqote2.min.js' adding 'locust/static/jquery.tools.min.js' adding 'locust/static/locust.js' adding 'locust/static/tasks.js' adding 'locust/static/vintage.js' adding 'locust/static/css/application.css' adding 'locust/static/css/application.css.map' adding 'locust/static/css/tables.css' adding 'locust/static/css/tables.css.map' adding 'locust/static/img/favicon.ico' adding 'locust/static/img/logo.png' adding 'locust/static/img/ui-screenshot-charts.png' adding 'locust/static/img/ui-screenshot-start-test.png' adding 'locust/static/img/ui-screenshot-stats.png' adding 'locust/static/img/ui-screenshot-workers.png' adding 'locust/static/sass/_base.sass' adding 'locust/static/sass/_mixins.sass' adding 'locust/static/sass/application.sass' adding 'locust/static/sass/tables.sass' adding 'locust/templates/index.html' adding 'locust/templates/report.html' adding 'locust/templates/stats_data.html' adding 'locust/test/__init__.py' adding 'locust/test/fake_module1_for_env_test.py' adding 'locust/test/fake_module2_for_env_test.py' adding 'locust/test/mock_locustfile.py' adding 'locust/test/mock_logging.py' adding 'locust/test/test_dispatch.py' adding 'locust/test/test_env.py' adding 'locust/test/test_fasthttp.py' adding 'locust/test/test_http.py' adding 'locust/test/test_load_locustfile.py' adding 'locust/test/test_locust_class.py' adding 'locust/test/test_log.py' adding 'locust/test/test_main.py' adding 'locust/test/test_old_wait_api.py' adding 'locust/test/test_parser.py' adding 'locust/test/test_runners.py' adding 'locust/test/test_sequential_taskset.py' adding 'locust/test/test_stats.py' adding 'locust/test/test_tags.py' adding 'locust/test/test_taskratio.py' adding 'locust/test/test_users.py' adding 'locust/test/test_util.py' adding 'locust/test/test_wait_time.py' adding 'locust/test/test_web.py' adding 'locust/test/test_zmqrpc.py' adding 'locust/test/testcases.py' adding 'locust/test/util.py' adding 'locust/user/__init__.py' adding 'locust/user/inspectuser.py' adding 'locust/user/sequential_taskset.py' adding 'locust/user/task.py' adding 'locust/user/users.py' adding 'locust/user/wait_time.py' adding 'locust/util/__init__.py' adding 'locust/util/cache.py' adding 'locust/util/deprecation.py' adding 'locust/util/exception_handler.py' adding 'locust/util/load_locustfile.py' adding 'locust/util/rounding.py' adding 'locust/util/timespan.py' adding 'locust-0.0.0.dist-info/LICENSE' adding 'locust-0.0.0.dist-info/METADATA' adding 'locust-0.0.0.dist-info/WHEEL' adding 'locust-0.0.0.dist-info/entry_points.txt' adding 'locust-0.0.0.dist-info/top_level.txt' adding 'locust-0.0.0.dist-info/RECORD' removing build/bdist.linux-x86_64/wheel Successfully built locust-0.0.0-py3-none-any.whl I: pybuild plugin_pyproject:119: Unpacking wheel built for python3.11 with "installer" module debian/rules override_dh_auto_test make[1]: Entering directory '/build/locust-2.12.1' # examples/test_data_management.py - attempted network access during pytest collection phase # TestMasterWorkerRunners times out after a long time http_proxy= https_proxy= PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/build/locust-2.12.1/debian PYBUILD_SYSTEM=custom PYBUILD_TEST_ARGS="PYTHONPATH={build_dir} {interpreter} -m pytest -v --ignore=examples/test_data_management.py -k 'not TestMasterWorkerRunners'" dh_auto_test I: pybuild base:240: PYTHONPATH=/build/locust-2.12.1/.pybuild/cpython3_3.11_locust/build python3.11 -m pytest -v --ignore=examples/test_data_management.py -k 'not TestMasterWorkerRunners' ============================= test session starts ============================== platform linux -- Python 3.11.2, pytest-7.2.1, pluggy-1.0.0+repack -- /usr/bin/python3.11 cachedir: .pytest_cache rootdir: /build/locust-2.12.1 collecting ... collected 517 items / 15 deselected / 502 selected locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_ramp_up_users_to_3_workers_with_spawn_rate_of_0_5 PASSED [ 0%] locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_ramp_up_users_to_3_workers_with_spawn_rate_of_1 PASSED [ 0%] locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_ramp_up_users_to_3_workers_with_spawn_rate_of_2 PASSED [ 0%] locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_ramp_up_users_to_3_workers_with_spawn_rate_of_2_4 PASSED [ 0%] locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_ramp_up_users_to_3_workers_with_spawn_rate_of_3 PASSED [ 0%] locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_ramp_up_users_to_3_workers_with_spawn_rate_of_4 PASSED [ 1%] locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_ramp_up_users_to_3_workers_with_spawn_rate_of_9 PASSED [ 1%] locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_ramp_up_users_to_4_workers_with_spawn_rate_of_1 PASSED [ 1%] locust/test/test_dispatch.py::TestRampUpUsersFromZero::test_users_are_distributed_evenly_across_hosts PASSED [ 1%] locust/test/test_dispatch.py::TestWaitBetweenDispatch::test_wait_between_dispatch PASSED [ 1%] locust/test/test_dispatch.py::TestRampDownUsersToZero::test_ramp_down_users_to_3_workers_with_spawn_rate_of_0_5 PASSED [ 2%] locust/test/test_dispatch.py::TestRampDownUsersToZero::test_ramp_down_users_to_3_workers_with_spawn_rate_of_1 PASSED [ 2%] locust/test/test_dispatch.py::TestRampDownUsersToZero::test_ramp_down_users_to_3_workers_with_spawn_rate_of_2 PASSED [ 2%] locust/test/test_dispatch.py::TestRampDownUsersToZero::test_ramp_down_users_to_3_workers_with_spawn_rate_of_2_4 PASSED [ 2%] locust/test/test_dispatch.py::TestRampDownUsersToZero::test_ramp_down_users_to_3_workers_with_spawn_rate_of_3 PASSED [ 2%] locust/test/test_dispatch.py::TestRampDownUsersToZero::test_ramp_down_users_to_3_workers_with_spawn_rate_of_4 PASSED [ 3%] locust/test/test_dispatch.py::TestRampDownUsersToZero::test_ramp_down_users_to_3_workers_with_spawn_rate_of_9 PASSED [ 3%] locust/test/test_dispatch.py::TestRampDownUsersToZero::test_ramp_down_users_to_4_workers_with_spawn_rate_of_1 PASSED [ 3%] locust/test/test_dispatch.py::TestRampUpThenDownThenUp::test_ramp_up_then_down_then_up PASSED [ 3%] locust/test/test_dispatch.py::TestDispatchUsersToWorkersHavingTheSameUsersAsTheTarget::test_dispatch_users_to_3_workers PASSED [ 3%] locust/test/test_dispatch.py::TestDistributionIsRespectedDuringDispatch::test_dispatch_75_users_to_4_workers_with_spawn_rate_of_5 PASSED [ 4%] locust/test/test_dispatch.py::TestLargeScale::test_distribute_users FAILED [ 4%] locust/test/test_dispatch.py::TestLargeScale::test_ramp_down_from_100_000_to_0_users_with_50_user_classes_and_1000_workers_and_5000_spawn_rate PASSED [ 4%] locust/test/test_dispatch.py::TestLargeScale::test_ramp_up_from_0_to_100_000_users_with_50_user_classes_and_1000_workers_and_5000_spawn_rate FAILED [ 4%] locust/test/test_dispatch.py::TestSmallConsecutiveRamping::test_consecutive_ramp_up_and_ramp_down PASSED [ 4%] locust/test/test_dispatch.py::TestRampingMiscellaneous::test_spawn_rate_greater_than_target_user_count PASSED [ 5%] locust/test/test_dispatch.py::TestRemoveWorker::test_remove_last_worker PASSED [ 5%] locust/test/test_dispatch.py::TestRemoveWorker::test_remove_two_workers_between_two_ramp_ups PASSED [ 5%] locust/test/test_dispatch.py::TestRemoveWorker::test_remove_two_workers_during_ramp_down PASSED [ 5%] locust/test/test_dispatch.py::TestRemoveWorker::test_remove_two_workers_during_ramp_up PASSED [ 5%] locust/test/test_dispatch.py::TestRemoveWorker::test_remove_worker_between_two_ramp_ups PASSED [ 6%] locust/test/test_dispatch.py::TestRemoveWorker::test_remove_worker_during_ramp_down PASSED [ 6%] locust/test/test_dispatch.py::TestRemoveWorker::test_remove_worker_during_ramp_up PASSED [ 6%] locust/test/test_dispatch.py::TestRemoveWorker::test_remove_worker_during_ramp_up_with_fixed_user PASSED [ 6%] locust/test/test_dispatch.py::TestAddWorker::test_add_two_workers_between_two_ramp_ups PASSED [ 6%] locust/test/test_dispatch.py::TestAddWorker::test_add_two_workers_during_ramp_down PASSED [ 7%] locust/test/test_dispatch.py::TestAddWorker::test_add_two_workers_during_ramp_up PASSED [ 7%] locust/test/test_dispatch.py::TestAddWorker::test_add_worker_between_two_ramp_ups PASSED [ 7%] locust/test/test_dispatch.py::TestAddWorker::test_add_worker_during_ramp_down PASSED [ 7%] locust/test/test_dispatch.py::TestAddWorker::test_add_worker_during_ramp_up PASSED [ 7%] locust/test/test_dispatch.py::TestAddWorker::test_add_worker_during_ramp_up_with_fixed_user PASSED [ 8%] locust/test/test_dispatch.py::TestRampUpUsersFromZeroWithFixed::test_ramp_up_2_weigted_user_with_1_fixed_user PASSED [ 8%] locust/test/test_dispatch.py::TestRampUpUsersFromZeroWithFixed::test_ramp_up_only_fixed_users PASSED [ 8%] locust/test/test_dispatch.py::TestRampUpUsersFromZeroWithFixed::test_ramp_up_partially_ramp_down_and_rump_up_to_target PASSED [ 8%] locust/test/test_dispatch.py::TestRampUpUsersFromZeroWithFixed::test_ramp_up_ramp_down_and_rump_up_again PASSED [ 8%] locust/test/test_dispatch.py::TestRampUpUsersFromZeroWithFixed::test_ramp_up_various_count_weigted_and_fixed_users PASSED [ 9%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_add_worker_during_ramp_up_custom_classes PASSED [ 9%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_ramp_down_custom_user_classes_respect_weighting PASSED [ 9%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_ramp_up_different_users_each_dispatch_multiple_worker PASSED [ 9%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_ramp_up_different_users_for_each_dispatch PASSED [ 9%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_ramp_up_first_half_user1_second_half_user2 PASSED [ 10%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_ramp_up_first_one_user_then_all_classes PASSED [ 10%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_ramp_up_one_user_class_multiple_worker PASSED [ 10%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_ramp_up_only_one_kind_of_user PASSED [ 10%] locust/test/test_dispatch.py::TestRampUpDifferentUsers::test_remove_worker_during_ramp_up_custom_classes PASSED [ 10%] locust/test/test_env.py::TestEnvironment::test_all_user_classes_with_zero_weight_raises_exception PASSED [ 11%] locust/test/test_env.py::TestEnvironment::test_assign_equal_weights PASSED [ 11%] locust/test/test_env.py::TestEnvironment::test_shape_class_attribute PASSED [ 11%] locust/test/test_env.py::TestEnvironment::test_user_classes_count PASSED [ 11%] locust/test/test_env.py::TestEnvironment::test_user_classes_with_same_name_is_error PASSED [ 11%] locust/test/test_env.py::TestEnvironment::test_user_classes_with_zero_weight_are_removed PASSED [ 12%] locust/test/test_fasthttp.py::TestFastHttpSession::test_204 PASSED [ 12%] locust/test/test_fasthttp.py::TestFastHttpSession::test_404 PASSED [ 12%] locust/test/test_fasthttp.py::TestFastHttpSession::test_catch_response_default_fail PASSED [ 12%] locust/test/test_fasthttp.py::TestFastHttpSession::test_catch_response_default_success PASSED [ 12%] locust/test/test_fasthttp.py::TestFastHttpSession::test_catch_response_fail_successful_request PASSED [ 13%] locust/test/test_fasthttp.py::TestFastHttpSession::test_catch_response_multiple_failure_and_success PASSED [ 13%] locust/test/test_fasthttp.py::TestFastHttpSession::test_catch_response_pass_failed_request PASSED [ 13%] locust/test/test_fasthttp.py::TestFastHttpSession::test_catch_response_pass_failed_request_with_other_exception_within_block PASSED [ 13%] locust/test/test_fasthttp.py::TestFastHttpSession::test_connection_error PASSED [ 13%] locust/test/test_fasthttp.py::TestFastHttpSession::test_cookie PASSED [ 14%] locust/test/test_fasthttp.py::TestFastHttpSession::test_custom_ssl_context_fail_with_bad_context PASSED [ 14%] locust/test/test_fasthttp.py::TestFastHttpSession::test_custom_ssl_context_passed_correct_to_client_pool PASSED [ 14%] locust/test/test_fasthttp.py::TestFastHttpSession::test_delete PASSED [ 14%] locust/test/test_fasthttp.py::TestFastHttpSession::test_error_message_with_name_replacement PASSED [ 14%] locust/test/test_fasthttp.py::TestFastHttpSession::test_get PASSED [ 15%] locust/test/test_fasthttp.py::TestFastHttpSession::test_head PASSED [ 15%] locust/test/test_fasthttp.py::TestFastHttpSession::test_json_payload PASSED [ 15%] locust/test/test_fasthttp.py::TestFastHttpSession::test_options PASSED [ 15%] locust/test/test_fasthttp.py::TestFastHttpSession::test_patch PASSED [ 15%] locust/test/test_fasthttp.py::TestFastHttpSession::test_post_redirect PASSED [ 16%] locust/test/test_fasthttp.py::TestFastHttpSession::test_slow_redirect PASSED [ 16%] locust/test/test_fasthttp.py::TestFastHttpSession::test_streaming_response PASSED [ 16%] locust/test/test_fasthttp.py::TestRequestStatsWithWebserver::test_request_connection_error PASSED [ 16%] locust/test/test_fasthttp.py::TestRequestStatsWithWebserver::test_request_stats_content_length PASSED [ 16%] locust/test/test_fasthttp.py::TestRequestStatsWithWebserver::test_request_stats_named_endpoint PASSED [ 17%] locust/test/test_fasthttp.py::TestRequestStatsWithWebserver::test_request_stats_no_content_length PASSED [ 17%] locust/test/test_fasthttp.py::TestRequestStatsWithWebserver::test_request_stats_no_content_length_streaming PASSED [ 17%] locust/test/test_fasthttp.py::TestRequestStatsWithWebserver::test_request_stats_put PASSED [ 17%] locust/test/test_fasthttp.py::TestRequestStatsWithWebserver::test_request_stats_query_variables PASSED [ 17%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_allow_redirects_override PASSED [ 18%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_class_context PASSED [ 18%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_basic_auth PASSED [ 18%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_delete PASSED [ 18%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_get PASSED [ 18%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_get_absolute_url PASSED [ 19%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_head PASSED [ 19%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_pool_concurrency FAILED [ 19%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_pool_per_user_instance PASSED [ 19%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_post PASSED [ 19%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_put PASSED [ 20%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_request_headers PASSED [ 20%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_get_request PASSED [ 20%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_is_abstract PASSED [ 20%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_log_request_name_argument PASSED [ 20%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_max_redirect_setting PASSED [ 21%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_network_timeout_setting PASSED [ 21%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_redirect_url_original_path_as_name PASSED [ 21%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_shared_client_pool PASSED [ 21%] locust/test/test_fasthttp.py::TestFastHttpUserClass::test_slow_redirect PASSED [ 21%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_catch_response PASSED [ 22%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_catch_response_allow_404 PASSED [ 22%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_catch_response_connection_error_fail PASSED [ 22%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_catch_response_connection_error_success PASSED [ 22%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_catch_response_http_fail PASSED [ 22%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_catch_response_http_manual_fail PASSED [ 23%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_catch_response_http_manual_success PASSED [ 23%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_catch_response_missing_with_block PASSED [ 23%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_deprecated_request_events PASSED [ 23%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_interrupt_taskset_with_catch_response PASSED [ 23%] locust/test/test_fasthttp.py::TestFastHttpCatchResponse::test_missing_catch_response_true PASSED [ 24%] locust/test/test_fasthttp.py::TestFastHttpSsl::test_ssl_request_insecure PASSED [ 24%] locust/test/test_http.py::TestHttpSession::test_catch_response_default_fail PASSED [ 24%] locust/test/test_http.py::TestHttpSession::test_catch_response_default_success PASSED [ 24%] locust/test/test_http.py::TestHttpSession::test_catch_response_fail_successful_request PASSED [ 24%] locust/test/test_http.py::TestHttpSession::test_catch_response_fail_successful_request_with_non_string_error_message PASSED [ 25%] locust/test/test_http.py::TestHttpSession::test_catch_response_missing_with_block PASSED [ 25%] locust/test/test_http.py::TestHttpSession::test_catch_response_multiple_failure_and_success PASSED [ 25%] locust/test/test_http.py::TestHttpSession::test_catch_response_pass_failed_request PASSED [ 25%] locust/test/test_http.py::TestHttpSession::test_catch_response_pass_failed_request_with_other_exception_within_block PASSED [ 25%] locust/test/test_http.py::TestHttpSession::test_catch_response_response_error PASSED [ 26%] locust/test/test_http.py::TestHttpSession::test_catch_response_timeout PASSED [ 26%] locust/test/test_http.py::TestHttpSession::test_connection_error PASSED [ 26%] locust/test/test_http.py::TestHttpSession::test_context_in_success PASSED [ 26%] locust/test/test_http.py::TestHttpSession::test_cookie PASSED [ 26%] locust/test/test_http.py::TestHttpSession::test_delete PASSED [ 27%] locust/test/test_http.py::TestHttpSession::test_deprecated_request_events PASSED [ 27%] locust/test/test_http.py::TestHttpSession::test_error_message PASSED [ 27%] locust/test/test_http.py::TestHttpSession::test_error_message_with_name_replacement PASSED [ 27%] locust/test/test_http.py::TestHttpSession::test_get PASSED [ 27%] locust/test/test_http.py::TestHttpSession::test_get_with_params PASSED [ 28%] locust/test/test_http.py::TestHttpSession::test_head PASSED [ 28%] locust/test/test_http.py::TestHttpSession::test_missing_catch_response_true PASSED [ 28%] locust/test/test_http.py::TestHttpSession::test_options PASSED [ 28%] locust/test/test_http.py::TestHttpSession::test_post_redirect PASSED [ 28%] locust/test/test_http.py::TestHttpSession::test_response_parameter PASSED [ 29%] locust/test/test_http.py::TestHttpSession::test_slow_redirect PASSED [ 29%] locust/test/test_http.py::TestHttpSession::test_streaming_response PASSED [ 29%] locust/test/test_http.py::TestHttpSession::test_user_context PASSED [ 29%] locust/test/test_http.py::TestHttpSession::test_wrong_url PASSED [ 29%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_command_line_arguments_override_config_file PASSED [ 30%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_create_environment PASSED [ 30%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_is_user_class PASSED [ 30%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_load_locust_file_from_absolute_path PASSED [ 30%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_load_locust_file_from_relative_path PASSED [ 30%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_load_locust_file_with_a_dot_in_filename PASSED [ 31%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_locustfile_can_be_set_in_config_file PASSED [ 31%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_return_docstring_and_user_classes PASSED [ 31%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_specify_config_file PASSED [ 31%] locust/test/test_load_locustfile.py::TestLoadLocustfile::test_with_shape_class PASSED [ 31%] locust/test/test_locust_class.py::TestTaskSet::test_on_start PASSED [ 32%] locust/test/test_locust_class.py::TestTaskSet::test_on_start_interrupt PASSED [ 32%] locust/test/test_locust_class.py::TestTaskSet::test_on_stop_interrupt PASSED [ 32%] locust/test/test_locust_class.py::TestTaskSet::test_on_stop_interrupt_reschedule PASSED [ 32%] locust/test/test_locust_class.py::TestTaskSet::test_on_stop_when_locust_stops PASSED [ 32%] locust/test/test_locust_class.py::TestTaskSet::test_parent_attribute PASSED [ 33%] locust/test/test_locust_class.py::TestTaskSet::test_schedule_task PASSED [ 33%] locust/test/test_locust_class.py::TestTaskSet::test_schedule_task_bound_method PASSED [ 33%] locust/test/test_locust_class.py::TestTaskSet::test_sub_taskset PASSED [ 33%] locust/test/test_locust_class.py::TestTaskSet::test_sub_taskset_tasks_decorator PASSED [ 33%] locust/test/test_locust_class.py::TestTaskSet::test_task_decorator_on_taskset PASSED [ 34%] locust/test/test_locust_class.py::TestTaskSet::test_task_decorator_ratio PASSED [ 34%] locust/test/test_locust_class.py::TestTaskSet::test_task_decorator_with_or_without_argument PASSED [ 34%] locust/test/test_locust_class.py::TestTaskSet::test_task_ratio PASSED [ 34%] locust/test/test_locust_class.py::TestTaskSet::test_tasks_missing_from_user_gives_user_friendly_exception PASSED [ 34%] locust/test/test_locust_class.py::TestTaskSet::test_tasks_missing_gives_user_friendly_exception PASSED [ 35%] locust/test/test_locust_class.py::TestTaskSet::test_tasks_on_abstract_locust PASSED [ 35%] locust/test/test_locust_class.py::TestTaskSet::test_tasks_on_locust PASSED [ 35%] locust/test/test_locust_class.py::TestTaskSet::test_taskset_inheritance PASSED [ 35%] locust/test/test_locust_class.py::TestTaskSet::test_taskset_on_abstract_locust PASSED [ 35%] locust/test/test_locust_class.py::TestTaskSet::test_user_is_read_only PASSED [ 36%] locust/test/test_locust_class.py::TestTaskSet::test_wait_function PASSED [ 36%] locust/test/test_locust_class.py::TestLocustClass::test_deprecated_locust_class PASSED [ 36%] locust/test/test_locust_class.py::TestLocustClass::test_locust_forced_stop PASSED [ 36%] locust/test/test_locust_class.py::TestLocustClass::test_locust_graceful_stop PASSED [ 36%] locust/test/test_locust_class.py::TestLocustClass::test_locust_on_start PASSED [ 37%] locust/test/test_locust_class.py::TestLocustClass::test_locust_on_stop PASSED [ 37%] locust/test/test_locust_class.py::TestLocustClass::test_locust_start PASSED [ 37%] locust/test/test_locust_class.py::TestLocustClass::test_locust_wait PASSED [ 37%] locust/test/test_locust_class.py::TestWebLocustClass::test_client_basic_auth PASSED [ 37%] locust/test/test_locust_class.py::TestWebLocustClass::test_client_delete PASSED [ 38%] locust/test/test_locust_class.py::TestWebLocustClass::test_client_get PASSED [ 38%] locust/test/test_locust_class.py::TestWebLocustClass::test_client_get_absolute_url PASSED [ 38%] locust/test/test_locust_class.py::TestWebLocustClass::test_client_head PASSED [ 38%] locust/test/test_locust_class.py::TestWebLocustClass::test_client_post PASSED [ 38%] locust/test/test_locust_class.py::TestWebLocustClass::test_client_put PASSED [ 39%] locust/test/test_locust_class.py::TestWebLocustClass::test_client_request_headers PASSED [ 39%] locust/test/test_locust_class.py::TestWebLocustClass::test_get_request PASSED [ 39%] locust/test/test_locust_class.py::TestWebLocustClass::test_log_request_name_argument PASSED [ 39%] locust/test/test_locust_class.py::TestWebLocustClass::test_redirect_url_original_path_as_name PASSED [ 39%] locust/test/test_locust_class.py::TestCatchResponse::test_catch_response PASSED [ 40%] locust/test/test_locust_class.py::TestCatchResponse::test_catch_response_allow_404 PASSED [ 40%] locust/test/test_locust_class.py::TestCatchResponse::test_catch_response_connection_error_fail PASSED [ 40%] locust/test/test_locust_class.py::TestCatchResponse::test_catch_response_connection_error_success PASSED [ 40%] locust/test/test_locust_class.py::TestCatchResponse::test_catch_response_http_fail PASSED [ 40%] locust/test/test_locust_class.py::TestCatchResponse::test_catch_response_http_manual_fail PASSED [ 41%] locust/test/test_locust_class.py::TestCatchResponse::test_catch_response_http_manual_success PASSED [ 41%] locust/test/test_locust_class.py::TestCatchResponse::test_interrupt_taskset_with_catch_response PASSED [ 41%] locust/test/test_log.py::TestGreenletExceptionLogger::test_greenlet_exception_logger PASSED [ 41%] locust/test/test_log.py::TestLoggingOptions::test_log_to_file FAILED [ 41%] locust/test/test_log.py::TestLoggingOptions::test_logging_output FAILED [ 42%] locust/test/test_log.py::TestLoggingOptions::test_skip_logging FAILED [ 42%] locust/test/test_main.py::ProcessIntegrationTest::test_help_arg FAILED [ 42%] locust/test/test_main.py::StandaloneIntegrationTests::test_autostart_mutliple_locustfiles_with_shape FAILED [ 42%] locust/test/test_main.py::StandaloneIntegrationTests::test_autostart_w_load_shape FAILED [ 42%] locust/test/test_main.py::StandaloneIntegrationTests::test_autostart_w_run_time FAILED [ 43%] locust/test/test_main.py::StandaloneIntegrationTests::test_autostart_wo_run_time FAILED [ 43%] locust/test/test_main.py::StandaloneIntegrationTests::test_command_line_user_selection FAILED [ 43%] locust/test/test_main.py::StandaloneIntegrationTests::test_custom_arguments FAILED [ 43%] locust/test/test_main.py::StandaloneIntegrationTests::test_custom_arguments_in_file FAILED [ 43%] locust/test/test_main.py::StandaloneIntegrationTests::test_custom_exit_code FAILED [ 44%] locust/test/test_main.py::StandaloneIntegrationTests::test_default_headless_spawn_options FAILED [ 44%] locust/test/test_main.py::StandaloneIntegrationTests::test_default_headless_spawn_options_with_shape FAILED [ 44%] locust/test/test_main.py::StandaloneIntegrationTests::test_error_when_duplicate_shape_class_names FAILED [ 44%] locust/test/test_main.py::StandaloneIntegrationTests::test_error_when_duplicate_userclass_names FAILED [ 44%] locust/test/test_main.py::StandaloneIntegrationTests::test_error_when_locustfiles_directory_is_empty FAILED [ 45%] locust/test/test_main.py::StandaloneIntegrationTests::test_error_when_no_tasks_match_tags FAILED [ 45%] locust/test/test_main.py::StandaloneIntegrationTests::test_headless_spawn_options_wo_run_time FAILED [ 45%] locust/test/test_main.py::StandaloneIntegrationTests::test_help_arg FAILED [ 45%] locust/test/test_main.py::StandaloneIntegrationTests::test_html_report_option FAILED [ 45%] locust/test/test_main.py::StandaloneIntegrationTests::test_input FAILED [ 46%] locust/test/test_main.py::StandaloneIntegrationTests::test_no_error_when_same_userclass_in_two_files FAILED [ 46%] locust/test/test_main.py::StandaloneIntegrationTests::test_run_autostart_with_multiple_locustfiles FAILED [ 46%] locust/test/test_main.py::StandaloneIntegrationTests::test_run_headless_with_multiple_locustfiles FAILED [ 46%] locust/test/test_main.py::StandaloneIntegrationTests::test_run_headless_with_multiple_locustfiles_with_shape FAILED [ 46%] locust/test/test_main.py::StandaloneIntegrationTests::test_run_with_userclass_picker FAILED [ 47%] locust/test/test_main.py::StandaloneIntegrationTests::test_spawing_with_fixed_multiple_locustfiles FAILED [ 47%] locust/test/test_main.py::StandaloneIntegrationTests::test_spawning_with_fixed FAILED [ 47%] locust/test/test_main.py::StandaloneIntegrationTests::test_web_options FAILED [ 47%] locust/test/test_main.py::StandaloneIntegrationTests::test_webserver FAILED [ 47%] locust/test/test_main.py::StandaloneIntegrationTests::test_webserver_multiple_locustfiles FAILED [ 48%] locust/test/test_main.py::StandaloneIntegrationTests::test_webserver_multiple_locustfiles_in_directory FAILED [ 48%] locust/test/test_main.py::StandaloneIntegrationTests::test_webserver_multiple_locustfiles_with_shape FAILED [ 48%] locust/test/test_main.py::DistributedIntegrationTests::test_distributed FAILED [ 48%] locust/test/test_main.py::DistributedIntegrationTests::test_distributed_events FAILED [ 48%] locust/test/test_main.py::DistributedIntegrationTests::test_distributed_report_timeout_expired FAILED [ 49%] locust/test/test_main.py::DistributedIntegrationTests::test_distributed_tags FAILED [ 49%] locust/test/test_main.py::DistributedIntegrationTests::test_expect_workers FAILED [ 49%] locust/test/test_main.py::DistributedIntegrationTests::test_help_arg FAILED [ 49%] locust/test/test_main.py::DistributedIntegrationTests::test_worker_indexes FAILED [ 49%] locust/test/test_parser.py::TestParser::test_default PASSED [ 50%] locust/test/test_parser.py::TestParser::test_parameter_parsing PASSED [ 50%] locust/test/test_parser.py::TestParser::test_reset_stats PASSED [ 50%] locust/test/test_parser.py::TestParser::test_skip_log_setup PASSED [ 50%] locust/test/test_parser.py::TestParser::test_web_auth PASSED [ 50%] locust/test/test_parser.py::TestArgumentParser::test_csv_full_history_requires_csv PASSED [ 50%] locust/test/test_parser.py::TestArgumentParser::test_custom_argument PASSED [ 51%] locust/test/test_parser.py::TestArgumentParser::test_custom_argument_help_message PASSED [ 51%] locust/test/test_parser.py::TestArgumentParser::test_custom_argument_included_in_web_ui PASSED [ 51%] locust/test/test_parser.py::TestArgumentParser::test_parse_locustfile PASSED [ 51%] locust/test/test_parser.py::TestArgumentParser::test_parse_locustfile_empty_directory_error PASSED [ 51%] locust/test/test_parser.py::TestArgumentParser::test_parse_locustfile_invalid_directory_error PASSED [ 52%] locust/test/test_parser.py::TestArgumentParser::test_parse_locustfile_multiple_files PASSED [ 52%] locust/test/test_parser.py::TestArgumentParser::test_parse_locustfile_with_directory PASSED [ 52%] locust/test/test_parser.py::TestArgumentParser::test_parse_locustfile_with_directory_ignores_invalid_filenames PASSED [ 52%] locust/test/test_parser.py::TestArgumentParser::test_parse_locustfile_with_nested_directory PASSED [ 52%] locust/test/test_parser.py::TestArgumentParser::test_parse_options PASSED [ 53%] locust/test/test_parser.py::TestArgumentParser::test_unknown_command_line_arg PASSED [ 53%] locust/test/test_parser.py::TestFindLocustfiles::test_find_locustfiles_error_for_invalid_file_extension PASSED [ 53%] locust/test/test_parser.py::TestFindLocustfiles::test_find_locustfiles_error_if_directory_doesnt_exist PASSED [ 53%] locust/test/test_parser.py::TestFindLocustfiles::test_find_locustfiles_error_if_invalid_directory PASSED [ 53%] locust/test/test_parser.py::TestFindLocustfiles::test_find_locustfiles_error_if_multiple_values_for_directory PASSED [ 54%] locust/test/test_parser.py::TestFindLocustfiles::test_find_locustfiles_ignores_invalid_files_in_directory PASSED [ 54%] locust/test/test_parser.py::TestFindLocustfiles::test_find_locustfiles_with_is_directory PASSED [ 54%] locust/test/test_parser.py::TestFindLocustfiles::test_find_locustfiles_with_multiple_locustfiles PASSED [ 54%] locust/test/test_parser.py::TestLocustfileIsDirectory::test_locustfile_is_directory_false_if_file_and_directory_share_the_same_name PASSED [ 54%] locust/test/test_parser.py::TestLocustfileIsDirectory::test_locustfile_is_directory_multiple_locustfiles PASSED [ 55%] locust/test/test_parser.py::TestLocustfileIsDirectory::test_locustfile_is_directory_single_locustfile PASSED [ 55%] locust/test/test_parser.py::TestLocustfileIsDirectory::test_locustfile_is_directory_single_locustfile_without_file_extension PASSED [ 55%] locust/test/test_parser.py::TestLocustfileIsDirectory::test_locustfile_is_directory_true_if_directory PASSED [ 55%] locust/test/test_runners.py::TestLocustRunner::test_attributes_populated_when_calling_start PASSED [ 55%] locust/test/test_runners.py::TestLocustRunner::test_can_call_stop_endpoint_if_currently_swarming PASSED [ 56%] locust/test/test_runners.py::TestLocustRunner::test_change_user_count_during_spawning PASSED [ 56%] locust/test/test_runners.py::TestLocustRunner::test_cpu_warning FAILED [ 56%] locust/test/test_runners.py::TestLocustRunner::test_custom_message PASSED [ 56%] locust/test/test_runners.py::TestLocustRunner::test_host_class_attribute_from_web PASSED [ 56%] locust/test/test_runners.py::TestLocustRunner::test_kill_locusts PASSED [ 57%] locust/test/test_runners.py::TestLocustRunner::test_no_reset_stats PASSED [ 57%] locust/test/test_runners.py::TestLocustRunner::test_reset_stats PASSED [ 57%] locust/test/test_runners.py::TestLocustRunner::test_runner_quit_can_run_on_stop_for_multiple_users_concurrently PASSED [ 57%] locust/test/test_runners.py::TestLocustRunner::test_runner_reference_on_environment PASSED [ 57%] locust/test/test_runners.py::TestLocustRunner::test_start_event PASSED [ 58%] locust/test/test_runners.py::TestLocustRunner::test_stop_event PASSED [ 58%] locust/test/test_runners.py::TestLocustRunner::test_stop_event_quit PASSED [ 58%] locust/test/test_runners.py::TestLocustRunner::test_stop_event_stop_and_quit PASSED [ 58%] locust/test/test_runners.py::TestLocustRunner::test_stop_users_count PASSED [ 58%] locust/test/test_runners.py::TestLocustRunner::test_stop_users_with_spawn_rate FAILED [ 59%] locust/test/test_runners.py::TestLocustRunner::test_stopping_event PASSED [ 59%] locust/test/test_runners.py::TestLocustRunner::test_swarm_endpoint_is_non_blocking PASSED [ 59%] locust/test/test_runners.py::TestLocustRunner::test_target_user_count_is_set_before_ramp_up PASSED [ 59%] locust/test/test_runners.py::TestLocustRunner::test_undefined_custom_message PASSED [ 59%] locust/test/test_runners.py::TestLocustRunner::test_user_classes_count PASSED [ 60%] locust/test/test_runners.py::TestLocustRunner::test_user_count_starts_from_specified_amount_when_creating_new_test_after_previous_step_has_been_stopped PASSED [ 60%] locust/test/test_runners.py::TestLocustRunner::test_users_can_call_runner_quit_without_deadlocking PASSED [ 60%] locust/test/test_runners.py::TestMasterRunner::test_attributes_populated_when_calling_start FAILED [ 60%] locust/test/test_runners.py::TestMasterRunner::test_custom_message_receive PASSED [ 60%] locust/test/test_runners.py::TestMasterRunner::test_custom_message_send PASSED [ 61%] locust/test/test_runners.py::TestMasterRunner::test_custom_shape_scale_down FAILED [ 61%] locust/test/test_runners.py::TestMasterRunner::test_custom_shape_scale_up FAILED [ 61%] locust/test/test_runners.py::TestMasterRunner::test_exception_in_task PASSED [ 61%] locust/test/test_runners.py::TestMasterRunner::test_exception_is_caught PASSED [ 61%] locust/test/test_runners.py::TestMasterRunner::test_last_worker_missing_stops_test FAILED [ 62%] locust/test/test_runners.py::TestMasterRunner::test_last_worker_quitting_stops_test FAILED [ 62%] locust/test/test_runners.py::TestMasterRunner::test_master_current_response_times PASSED [ 62%] locust/test/test_runners.py::TestMasterRunner::test_master_discard_first_client_ready FAILED [ 62%] locust/test/test_runners.py::TestMasterRunner::test_master_marks_downed_workers_as_missing FAILED [ 62%] locust/test/test_runners.py::TestMasterRunner::test_master_reset_connection FAILED [ 63%] locust/test/test_runners.py::TestMasterRunner::test_master_total_stats PASSED [ 63%] locust/test/test_runners.py::TestMasterRunner::test_master_total_stats_with_none_response_times PASSED [ 63%] locust/test/test_runners.py::TestMasterRunner::test_rebalance_locust_users_on_worker_connect FAILED [ 63%] locust/test/test_runners.py::TestMasterRunner::test_reset_connection_after_RPCError FAILED [ 63%] locust/test/test_runners.py::TestMasterRunner::test_sends_spawn_data_to_ready_running_spawning_workers PASSED [ 64%] locust/test/test_runners.py::TestMasterRunner::test_spawn_correct_worker_indexes FAILED [ 64%] locust/test/test_runners.py::TestMasterRunner::test_spawn_fewer_locusts_than_workers FAILED [ 64%] locust/test/test_runners.py::TestMasterRunner::test_spawn_uneven_locusts FAILED [ 64%] locust/test/test_runners.py::TestMasterRunner::test_spawn_zero_locusts PASSED [ 64%] locust/test/test_runners.py::TestMasterRunner::test_start_event FAILED [ 65%] locust/test/test_runners.py::TestMasterRunner::test_stop_event FAILED [ 65%] locust/test/test_runners.py::TestMasterRunner::test_stop_event_quit FAILED [ 65%] locust/test/test_runners.py::TestMasterRunner::test_undefined_custom_message_receive PASSED [ 65%] locust/test/test_runners.py::TestMasterRunner::test_wait_for_workers_report_after_ramp_up PASSED [ 65%] locust/test/test_runners.py::TestMasterRunner::test_worker_connect FAILED [ 66%] locust/test/test_runners.py::TestMasterRunner::test_worker_connect_with_special_versions FAILED [ 66%] locust/test/test_runners.py::TestMasterRunner::test_worker_missing_after_heartbeat_dead_interval FAILED [ 66%] locust/test/test_runners.py::TestMasterRunner::test_worker_sends_bad_message_to_master FAILED [ 66%] locust/test/test_runners.py::TestMasterRunner::test_worker_stats_report_median PASSED [ 66%] locust/test/test_runners.py::TestMasterRunner::test_worker_stats_report_with_none_response_times PASSED [ 67%] locust/test/test_runners.py::TestWorkerRunner::test_change_user_count_during_spawning PASSED [ 67%] locust/test/test_runners.py::TestWorkerRunner::test_computed_properties PASSED [ 67%] locust/test/test_runners.py::TestWorkerRunner::test_custom_message_receive PASSED [ 67%] locust/test/test_runners.py::TestWorkerRunner::test_custom_message_send PASSED [ 67%] locust/test/test_runners.py::TestWorkerRunner::test_reset_rpc_connection_to_master PASSED [ 68%] locust/test/test_runners.py::TestWorkerRunner::test_spawn_message_with_older_timestamp_is_rejected PASSED [ 68%] locust/test/test_runners.py::TestWorkerRunner::test_start_event PASSED [ 68%] locust/test/test_runners.py::TestWorkerRunner::test_stop_event PASSED [ 68%] locust/test/test_runners.py::TestWorkerRunner::test_undefined_custom_message_receive PASSED [ 68%] locust/test/test_runners.py::TestWorkerRunner::test_worker_connect_failure PASSED [ 69%] locust/test/test_runners.py::TestWorkerRunner::test_worker_connect_success PASSED [ 69%] locust/test/test_runners.py::TestWorkerRunner::test_worker_heartbeat_messages_sent_to_master PASSED [ 69%] locust/test/test_runners.py::TestWorkerRunner::test_worker_messages_sent_to_master PASSED [ 69%] locust/test/test_runners.py::TestWorkerRunner::test_worker_stop_timeout PASSED [ 69%] locust/test/test_runners.py::TestWorkerRunner::test_worker_without_stop_timeout PASSED [ 70%] locust/test/test_runners.py::TestMessageSerializing::test_message_serialize PASSED [ 70%] locust/test/test_runners.py::TestStopTimeout::test_gracefully_handle_exceptions_in_listener PASSED [ 70%] locust/test/test_runners.py::TestStopTimeout::test_kill_locusts_with_stop_timeout FAILED [ 70%] locust/test/test_runners.py::TestStopTimeout::test_stop_timeout FAILED [ 70%] locust/test/test_runners.py::TestStopTimeout::test_stop_timeout_during_on_start PASSED [ 71%] locust/test/test_runners.py::TestStopTimeout::test_stop_timeout_exit_during_wait PASSED [ 71%] locust/test/test_runners.py::TestStopTimeout::test_stop_timeout_with_interrupt PASSED [ 71%] locust/test/test_runners.py::TestStopTimeout::test_stop_timeout_with_interrupt_no_reschedule PASSED [ 71%] locust/test/test_runners.py::TestStopTimeout::test_stop_timeout_with_ramp_down FAILED [ 71%] locust/test/test_runners.py::TestStopTimeout::test_users_can_call_runner_quit_with_stop_timeout PASSED [ 72%] locust/test/test_sequential_taskset.py::TestTaskSet::test_task_sequence_multiple_iterations PASSED [ 72%] locust/test/test_sequential_taskset.py::TestTaskSet::test_task_sequence_with_inheritance PASSED [ 72%] locust/test/test_sequential_taskset.py::TestTaskSet::test_task_sequence_with_list PASSED [ 72%] locust/test/test_sequential_taskset.py::TestTaskSet::test_task_sequence_with_methods PASSED [ 72%] locust/test/test_sequential_taskset.py::TestTaskSet::test_task_sequence_with_methods_and_list PASSED [ 73%] locust/test/test_stats.py::TestRequestStats::test_aggregation PASSED [ 73%] locust/test/test_stats.py::TestRequestStats::test_aggregation_last_request_timestamp PASSED [ 73%] locust/test/test_stats.py::TestRequestStats::test_aggregation_min_response_time PASSED [ 73%] locust/test/test_stats.py::TestRequestStats::test_aggregation_with_decimal_rounding PASSED [ 73%] locust/test/test_stats.py::TestRequestStats::test_aggregation_with_rounding PASSED [ 74%] locust/test/test_stats.py::TestRequestStats::test_avg PASSED [ 74%] locust/test/test_stats.py::TestRequestStats::test_avg_only_none PASSED [ 74%] locust/test/test_stats.py::TestRequestStats::test_current_fail_per_sec PASSED [ 74%] locust/test/test_stats.py::TestRequestStats::test_current_rps PASSED [ 74%] locust/test/test_stats.py::TestRequestStats::test_custom_percentile_list PASSED [ 75%] locust/test/test_stats.py::TestRequestStats::test_error_grouping PASSED [ 75%] locust/test/test_stats.py::TestRequestStats::test_error_grouping_errors_with_memory_addresses PASSED [ 75%] locust/test/test_stats.py::TestRequestStats::test_median PASSED [ 75%] locust/test/test_stats.py::TestRequestStats::test_median_out_of_min_max_bounds PASSED [ 75%] locust/test/test_stats.py::TestRequestStats::test_num_reqs_fails PASSED [ 76%] locust/test/test_stats.py::TestRequestStats::test_percentile PASSED [ 76%] locust/test/test_stats.py::TestRequestStats::test_percentile_rounded_down PASSED [ 76%] locust/test/test_stats.py::TestRequestStats::test_percentile_rounded_up PASSED [ 76%] locust/test/test_stats.py::TestRequestStats::test_reset PASSED [ 76%] locust/test/test_stats.py::TestRequestStats::test_reset_min_response_time PASSED [ 77%] locust/test/test_stats.py::TestRequestStats::test_rps_less_than_one_second PASSED [ 77%] locust/test/test_stats.py::TestRequestStats::test_serialize_through_message PASSED [ 77%] locust/test/test_stats.py::TestRequestStats::test_total_content_length PASSED [ 77%] locust/test/test_stats.py::TestRequestStats::test_total_rps PASSED [ 77%] locust/test/test_stats.py::TestStatsPrinting::test_print_error_report PASSED [ 78%] locust/test/test_stats.py::TestStatsPrinting::test_print_percentile_stats PASSED [ 78%] locust/test/test_stats.py::TestStatsPrinting::test_print_stats PASSED [ 78%] locust/test/test_stats.py::TestCsvStats::test_csv_stats_on_master_from_aggregated_stats PASSED [ 78%] locust/test/test_stats.py::TestCsvStats::test_csv_stats_writer PASSED [ 78%] locust/test/test_stats.py::TestCsvStats::test_csv_stats_writer_full_history FAILED [ 79%] locust/test/test_stats.py::TestCsvStats::test_requests_csv_quote_escaping PASSED [ 79%] locust/test/test_stats.py::TestCsvStats::test_stats_history FAILED [ 79%] locust/test/test_stats.py::TestCsvStats::test_user_count_in_csv_history_stats FAILED [ 79%] locust/test/test_stats.py::TestCsvStats::test_write_csv_files PASSED [ 79%] locust/test/test_stats.py::TestCsvStats::test_write_csv_files_full_history PASSED [ 80%] locust/test/test_stats.py::TestStatsEntryResponseTimesCache::test_diff_response_times_dicts PASSED [ 80%] locust/test/test_stats.py::TestStatsEntryResponseTimesCache::test_get_current_response_time_percentile PASSED [ 80%] locust/test/test_stats.py::TestStatsEntryResponseTimesCache::test_get_current_response_time_percentile_outside_cache_window PASSED [ 80%] locust/test/test_stats.py::TestStatsEntryResponseTimesCache::test_latest_total_response_times_pruned PASSED [ 80%] locust/test/test_stats.py::TestStatsEntryResponseTimesCache::test_response_times_cached PASSED [ 81%] locust/test/test_stats.py::TestStatsEntryResponseTimesCache::test_response_times_not_cached_if_not_enabled PASSED [ 81%] locust/test/test_stats.py::TestStatsEntry::test_fail_ratio_with_all_failures PASSED [ 81%] locust/test/test_stats.py::TestStatsEntry::test_fail_ratio_with_half_failures PASSED [ 81%] locust/test/test_stats.py::TestStatsEntry::test_fail_ratio_with_no_failures PASSED [ 81%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_connection_error PASSED [ 82%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_stats_content_length PASSED [ 82%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_stats_named_endpoint PASSED [ 82%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_stats_named_endpoint_rename_request PASSED [ 82%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_stats_named_endpoint_request_name PASSED [ 82%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_stats_no_content_length PASSED [ 83%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_stats_no_content_length_streaming PASSED [ 83%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_stats_put PASSED [ 83%] locust/test/test_stats.py::TestRequestStatsWithWebserver::test_request_stats_query_variables PASSED [ 83%] locust/test/test_stats.py::TestInspectUser::test_get_task_ratio_relative PASSED [ 83%] locust/test/test_stats.py::TestInspectUser::test_get_task_ratio_total PASSED [ 84%] locust/test/test_tags.py::TestTags::test_env_exclude_tags PASSED [ 84%] locust/test/test_tags.py::TestTags::test_env_include_tags PASSED [ 84%] locust/test/test_tags.py::TestTags::test_exclude_tags_under_user PASSED [ 84%] locust/test/test_tags.py::TestTags::test_excluding_tags PASSED [ 84%] locust/test/test_tags.py::TestTags::test_excluding_tags_with_weights PASSED [ 85%] locust/test/test_tags.py::TestTags::test_excluding_tasksets PASSED [ 85%] locust/test/test_tags.py::TestTags::test_include_tags_under_user PASSED [ 85%] locust/test/test_tags.py::TestTags::test_including_and_excluding PASSED [ 85%] locust/test/test_tags.py::TestTags::test_including_tags PASSED [ 85%] locust/test/test_tags.py::TestTags::test_including_tags_with_weights PASSED [ 86%] locust/test/test_tags.py::TestTags::test_including_tasksets PASSED [ 86%] locust/test/test_tags.py::TestTags::test_tagged_tasks_shared_across_tasksets PASSED [ 86%] locust/test/test_tags.py::TestTags::test_tagging PASSED [ 86%] locust/test/test_tags.py::TestTags::test_tagging_taskset PASSED [ 86%] locust/test/test_tags.py::TestTags::test_tagging_without_args_fails PASSED [ 87%] locust/test/test_taskratio.py::TestTaskRatio::test_task_ratio_command PASSED [ 87%] locust/test/test_taskratio.py::TestTaskRatio::test_task_ratio_command_with_locust_weight PASSED [ 87%] locust/test/test_users.py::TestUserClass::test_fullname_class_scoped PASSED [ 87%] locust/test/test_users.py::TestUserClass::test_fullname_function_scoped PASSED [ 87%] locust/test/test_users.py::TestUserClass::test_fullname_module_scoped PASSED [ 88%] locust/test/test_users.py::TestHttpUserWithWebserver::test_pool_manager_per_user_instance PASSED [ 88%] locust/test/test_users.py::TestHttpUserWithWebserver::test_shared_pool_manager PASSED [ 88%] locust/test/test_util.py::TestParseTimespan::test_parse_timespan PASSED [ 88%] locust/test/test_util.py::TestParseTimespan::test_parse_timespan_invalid_values PASSED [ 88%] locust/test/test_util.py::TestRounding::test_rounding_down PASSED [ 89%] locust/test/test_util.py::TestRounding::test_rounding_up PASSED [ 89%] locust/test/test_wait_time.py::TestWaitTime::test_between PASSED [ 89%] locust/test/test_wait_time.py::TestWaitTime::test_constant PASSED [ 89%] locust/test/test_wait_time.py::TestWaitTime::test_constant_throughput PASSED [ 89%] locust/test/test_wait_time.py::TestWaitTime::test_default_wait_time PASSED [ 90%] locust/test/test_web.py::TestWebUI::test_exceptions PASSED [ 90%] locust/test/test_web.py::TestWebUI::test_exceptions_csv PASSED [ 90%] locust/test/test_web.py::TestWebUI::test_failure_stats_csv PASSED [ 90%] locust/test/test_web.py::TestWebUI::test_host_value_from_multiple_user_classes PASSED [ 90%] locust/test/test_web.py::TestWebUI::test_host_value_from_multiple_user_classes_different_hosts PASSED [ 91%] locust/test/test_web.py::TestWebUI::test_host_value_from_user_class PASSED [ 91%] locust/test/test_web.py::TestWebUI::test_index PASSED [ 91%] locust/test/test_web.py::TestWebUI::test_index_with_spawn_options PASSED [ 91%] locust/test/test_web.py::TestWebUI::test_report_download PASSED [ 91%] locust/test/test_web.py::TestWebUI::test_report_exceptions PASSED [ 92%] locust/test/test_web.py::TestWebUI::test_report_host PASSED [ 92%] locust/test/test_web.py::TestWebUI::test_report_host2 PASSED [ 92%] locust/test/test_web.py::TestWebUI::test_report_page PASSED [ 92%] locust/test/test_web.py::TestWebUI::test_report_page_empty_stats PASSED [ 92%] locust/test/test_web.py::TestWebUI::test_request_stats_csv PASSED [ 93%] locust/test/test_web.py::TestWebUI::test_request_stats_full_history_csv_not_present PASSED [ 93%] locust/test/test_web.py::TestWebUI::test_request_stats_with_errors PASSED [ 93%] locust/test/test_web.py::TestWebUI::test_reset_stats PASSED [ 93%] locust/test/test_web.py::TestWebUI::test_stats PASSED [ 93%] locust/test/test_web.py::TestWebUI::test_stats_cache PASSED [ 94%] locust/test/test_web.py::TestWebUI::test_stats_no_data PASSED [ 94%] locust/test/test_web.py::TestWebUI::test_stats_rounding PASSED [ 94%] locust/test/test_web.py::TestWebUI::test_swarm_custom_argument PASSED [ 94%] locust/test/test_web.py::TestWebUI::test_swarm_defaults_to_all_available_userclasses_when_userclass_picker_is_active_and_no_userclass_in_payload PASSED [ 94%] locust/test/test_web.py::TestWebUI::test_swarm_error_when_userclass_picker_is_active_but_no_available_userclasses PASSED [ 95%] locust/test/test_web.py::TestWebUI::test_swarm_host_value_not_specified PASSED [ 95%] locust/test/test_web.py::TestWebUI::test_swarm_host_value_specified PASSED [ 95%] locust/test/test_web.py::TestWebUI::test_swarm_multiple_userclasses_specified PASSED [ 95%] locust/test/test_web.py::TestWebUI::test_swarm_run_time PASSED [ 95%] locust/test/test_web.py::TestWebUI::test_swarm_run_time_empty_input PASSED [ 96%] locust/test/test_web.py::TestWebUI::test_swarm_run_time_invalid_input PASSED [ 96%] locust/test/test_web.py::TestWebUI::test_swarm_shape_class_defaults_to_none_when_userclass_picker_is_active PASSED [ 96%] locust/test/test_web.py::TestWebUI::test_swarm_shape_class_specified PASSED [ 96%] locust/test/test_web.py::TestWebUI::test_swarm_updates_parsed_options_when_multiple_userclasses_specified PASSED [ 96%] locust/test/test_web.py::TestWebUI::test_swarm_updates_parsed_options_when_single_userclass_specified PASSED [ 97%] locust/test/test_web.py::TestWebUI::test_swarm_userclass_shapeclass_ignored_when_userclass_picker_is_inactive PASSED [ 97%] locust/test/test_web.py::TestWebUI::test_swarm_userclass_specified PASSED [ 97%] locust/test/test_web.py::TestWebUI::test_swarm_uses_pre_selected_user_classes_when_empty_payload_and_test_is_already_running_with_class_picker PASSED [ 97%] locust/test/test_web.py::TestWebUI::test_web_ui_no_runner PASSED [ 97%] locust/test/test_web.py::TestWebUI::test_web_ui_reference_on_environment PASSED [ 98%] locust/test/test_web.py::TestWebUIAuth::test_index_with_basic_auth_enabled_blank_credentials PASSED [ 98%] locust/test/test_web.py::TestWebUIAuth::test_index_with_basic_auth_enabled_correct_credentials PASSED [ 98%] locust/test/test_web.py::TestWebUIAuth::test_index_with_basic_auth_enabled_incorrect_credentials PASSED [ 98%] locust/test/test_web.py::TestWebUIWithTLS::test_index_with_https PASSED [ 98%] locust/test/test_web.py::TestWebUIFullHistory::test_request_stats_full_history_csv PASSED [ 99%] locust/test/test_zmqrpc.py::ZMQRPC_tests::test_client_recv PASSED [ 99%] locust/test/test_zmqrpc.py::ZMQRPC_tests::test_client_retry PASSED [ 99%] locust/test/test_zmqrpc.py::ZMQRPC_tests::test_client_send PASSED [ 99%] locust/test/test_zmqrpc.py::ZMQRPC_tests::test_constructor PASSED [ 99%] locust/test/test_zmqrpc.py::ZMQRPC_tests::test_rpc_error PASSED [100%] =================================== FAILURES =================================== _____________________ TestLargeScale.test_distribute_users _____________________ self = def test_distribute_users(self): for user_classes in [self.weighted_user_classes, self.fixed_user_classes_1M, self.mixed_users]: workers = [WorkerNode(str(i)) for i in range(10_000)] target_user_count = 1_000_000 users_dispatcher = UsersDispatcher(worker_nodes=workers, user_classes=user_classes) ts = time.perf_counter() users_on_workers, user_gen, worker_gen, active_users = users_dispatcher._distribute_users( target_user_count=target_user_count ) delta = time.perf_counter() - ts # Because tests are run with coverage, the code will be slower. # We set the pass criterion to 7000ms, but in real life, the # `_distribute_users` method runs faster than this. > self.assertLessEqual(1000 * delta, 7000) E AssertionError: 8192.842537988327 not less than or equal to 7000 locust/test/test_dispatch.py:2072: AssertionError _ TestLargeScale.test_ramp_up_from_0_to_100_000_users_with_50_user_classes_and_1000_workers_and_5000_spawn_rate _ self = def test_ramp_up_from_0_to_100_000_users_with_50_user_classes_and_1000_workers_and_5000_spawn_rate(self): for user_classes in [ self.weighted_user_classes, self.fixed_user_classes_1M, self.fixed_user_classes_10k, self.mixed_users, ]: workers = [WorkerNode(str(i)) for i in range(1000)] target_user_count = 100_000 users_dispatcher = UsersDispatcher(worker_nodes=workers, user_classes=user_classes) users_dispatcher.new_dispatch(target_user_count=target_user_count, spawn_rate=5_000) users_dispatcher._wait_between_dispatch = 0 all_dispatched_users = list(users_dispatcher) tol = 0.2 > self.assertTrue( all( dispatch_iteration_duration <= tol for dispatch_iteration_duration in users_dispatcher.dispatch_iteration_durations ), "One or more dispatch took more than {:.0f}s to compute (max = {}ms)".format( tol * 1000, 1000 * max(users_dispatcher.dispatch_iteration_durations) ), ) E AssertionError: False is not true : One or more dispatch took more than 200s to compute (max = 257.9829110036371ms) locust/test/test_dispatch.py:2094: AssertionError ______________ TestFastHttpUserClass.test_client_pool_concurrency ______________ self = def test_client_pool_concurrency(self): class MyUser(FastHttpUser): host = "http://127.0.0.1:%i" % self.port @task def t(self): def concurrent_request(url): response = self.client.get(url) assert response.status_code == 200 pool = gevent.pool.Pool() urls = ["/slow?delay=0.2"] * 20 # these urls are all the same, but they could be different for url in urls: pool.spawn(concurrent_request, url) pool.join() user = MyUser(self.environment) before_requests = time.time() user.t() after_requests = time.time() expected_delta = 0.4 # 20 requests with concurrency 10 and response time 0.2 > self.assertAlmostEqual(before_requests + expected_delta, after_requests, delta=0.1) E AssertionError: 1716551667.3420594 != 1716551667.485948 within 0.1 delta (0.1438887119293213 difference) locust/test/test_fasthttp.py:578: AssertionError _____________________ TestLoggingOptions.test_log_to_file ______________________ self = def test_log_to_file(self): with temporary_file( textwrap.dedent( """ import logging from locust import User, task, constant class MyUser(User): wait_time = constant(2) @task def my_task(self): print("running my_task") logging.info("custom log message") """ ) ) as file_path: with temporary_file("", suffix=".log") as log_file_path: try: > output = subprocess.check_output( [ "locust", "-f", file_path, "-u", "1", "-r", "1", "-t", "1", "--headless", "--logfile", log_file_path, ], stderr=subprocess.STDOUT, timeout=10, text=True, ) locust/test/test_log.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:413: in check_output with Popen(*popenargs, stdout=PIPE, **kwargs) as process: /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmprju7nia5_locustfile.py', '-u', '1', '-r', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = -1, errwrite = 78, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ____________________ TestLoggingOptions.test_logging_output ____________________ self = def test_logging_output(self): with temporary_file( textwrap.dedent( """ import logging from locust import User, task, constant custom_logger = logging.getLogger("custom_logger") class MyUser(User): wait_time = constant(2) @task def my_task(self): print("running my_task") logging.info("custom log message") custom_logger.info("test") """ ) ) as file_path: > output = subprocess.check_output( [ "locust", "-f", file_path, "-u", "1", "-r", "1", "-t", "1", "--headless", ], stderr=subprocess.STDOUT, timeout=10, text=True, ) locust/test/test_log.py:57: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:413: in check_output with Popen(*popenargs, stdout=PIPE, **kwargs) as process: /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmpl3y3xvq2_locustfile.py', '-u', '1', '-r', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = -1, errwrite = 78, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _____________________ TestLoggingOptions.test_skip_logging _____________________ self = def test_skip_logging(self): with temporary_file( textwrap.dedent( """ from locust import User, task, constant class MyUser(User): wait_time = constant(2) @task def my_task(self): print("running my_task") """ ) ) as file_path: > output = subprocess.check_output( [ "locust", "-f", file_path, "-u", "1", "-r", "1", "-t", "1", "--headless", "--skip-log-setup", ], stderr=subprocess.STDOUT, timeout=10, text=True, ) locust/test/test_log.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:413: in check_output with Popen(*popenargs, stdout=PIPE, **kwargs) as process: /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmptsnszj15_locustfile.py', '-u', '1', '-r', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = -1, errwrite = 78, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _____________________ ProcessIntegrationTest.test_help_arg _____________________ self = def test_help_arg(self): > output = subprocess.check_output( ["locust", "--help"], stderr=subprocess.STDOUT, timeout=5, text=True, ).strip() locust/test/test_main.py:51: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:413: in check_output with Popen(*popenargs, stdout=PIPE, **kwargs) as process: /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '--help'], executable = 'locust', preexec_fn = None close_fds = True, pass_fds = (), cwd = None, env = None universal_newlines = None, startupinfo = None, creationflags = 0, shell = False p2cread = -1, p2cwrite = -1, c2pread = 11, c2pwrite = 78, errread = -1 errwrite = 78, restore_signals = True, gid = None, gids = None, uid = None umask = -1, start_new_session = False, process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError __ StandaloneIntegrationTests.test_autostart_mutliple_locustfiles_with_shape ___ self = def test_autostart_mutliple_locustfiles_with_shape(self): port = get_free_tcp_port() content = textwrap.dedent( """ from locust import User, task, between class TestUser2(User): wait_time = between(2, 4) @task def my_task(self): print("running my_task() again") """ ) with mock_locustfile(content=content) as mocked1: with temporary_file( content=textwrap.dedent( """ from locust import User, task, between, LoadTestShape class LoadTestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return (10, 1) return None class TestUser(User): wait_time = between(2, 4) @task def my_task(self): print("running my_task()") """ ) ) as mocked2: > proc = subprocess.Popen( [ "locust", "-f", f"{mocked1.file_path},{mocked2}", "--web-port", str(port), "--autostart", "--autoquit", "2", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:655: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551699_125029_96984.py,/tmp/tmpqcx1wb82_locustfile.py', '--web-port', '59179', '--autostart', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ____________ StandaloneIntegrationTests.test_autostart_w_load_shape ____________ self = def test_autostart_w_load_shape(self): port = get_free_tcp_port() with mock_locustfile( content=MOCK_LOCUSTFILE_CONTENT + textwrap.dedent( """ from locust import LoadTestShape class LoadTestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return (10, 1) return None """ ) ) as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--web-port", str(port), "--autostart", "--autoquit", "2", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:588: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551699_4155607_54545.py', '--web-port', '40495', '--autostart', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _____________ StandaloneIntegrationTests.test_autostart_w_run_time _____________ self = def test_autostart_w_run_time(self): port = get_free_tcp_port() with mock_locustfile() as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--web-port", str(port), "-t", "2", "--autostart", "--autoquit", "1", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:499: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551699_681133_73856.py', '--web-port', '58293', '-t', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ____________ StandaloneIntegrationTests.test_autostart_wo_run_time _____________ self = def test_autostart_wo_run_time(self): port = get_free_tcp_port() with mock_locustfile() as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--web-port", str(port), "--autostart", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:467: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551700_1839473_64209.py', '--web-port', '47195', '--autostart'] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _________ StandaloneIntegrationTests.test_command_line_user_selection __________ self = def test_command_line_user_selection(self): LOCUSTFILE_CONTENT = textwrap.dedent( """ from locust import User, task, constant class User1(User): wait_time = constant(1) @task def t(self): print("User1 is running") class User2(User): wait_time = constant(1) @task def t(self): print("User2 is running") class User3(User): wait_time = constant(1) @task def t(self): print("User3 is running") """ ) with mock_locustfile(content=LOCUSTFILE_CONTENT) as mocked: proc = subprocess.Popen( " ".join( [ "locust", "-f", mocked.file_path, "--headless", "--run-time", "2s", "-u", "5", "-r", "10", "User2", "User3", ] ), stderr=STDOUT, stdout=PIPE, shell=True, text=True, ) output = proc.communicate()[0] self.assertNotIn("User1 is running", output) > self.assertIn("User2 is running", output) E AssertionError: 'User2 is running' not found in '/build/locust-2.12.1/debian/locust: 2: from: not found\n/build/locust-2.12.1/debian/locust: 5: Syntax error: end of file unexpected\n' locust/test/test_main.py:936: AssertionError _______________ StandaloneIntegrationTests.test_custom_arguments _______________ self = def test_custom_arguments(self): port = get_free_tcp_port() with temporary_file( content=textwrap.dedent( """ from locust import User, task, constant, events @events.init_command_line_parser.add_listener def _(parser, **kw): parser.add_argument("--custom-string-arg") class TestUser(User): wait_time = constant(10) @task def my_task(self): print(self.environment.parsed_options.custom_string_arg) """ ) ) as file_path: # print(subprocess.check_output(["cat", file_path])) > proc = subprocess.Popen( ["locust", "-f", file_path, "--custom-string-arg", "command_line_value", "--web-port", str(port)], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:84: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmp3vr4c5hy_locustfile.py', '--custom-string-arg', 'command_line_value', '--web-port', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ___________ StandaloneIntegrationTests.test_custom_arguments_in_file ___________ self = def test_custom_arguments_in_file(self): with temporary_file( content=textwrap.dedent( """ from locust import User, task, constant, events @events.init_command_line_parser.add_listener def _(parser, **kw): parser.add_argument("--custom-string-arg") class TestUser(User): wait_time = constant(10) @task def my_task(self): print(self.environment.parsed_options.custom_string_arg) """ ) ) as file_path: try: with open("locust.conf", "w") as conf_file: conf_file.write("custom-string-arg config_file_value") > proc = subprocess.Popen( ["locust", "-f", file_path, "--autostart"], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:126: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmpqywkykgi_locustfile.py', '--autostart'] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _______________ StandaloneIntegrationTests.test_custom_exit_code _______________ self = def test_custom_exit_code(self): with temporary_file( content=textwrap.dedent( """ from locust import User, task, constant, events @events.quitting.add_listener def _(environment, **kw): environment.process_exit_code = 42 @events.quit.add_listener def _(exit_code, **kw): print(f"Exit code in quit event {exit_code}") class TestUser(User): wait_time = constant(3) @task def my_task(self): print("running my_task()") """ ) ) as file_path: > proc = subprocess.Popen(["locust", "-f", file_path], stdout=PIPE, stderr=PIPE, text=True) locust/test/test_main.py:160: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmp9fty3kfm_locustfile.py'], executable = 'locust' preexec_fn = None, close_fds = True, pass_fds = (), cwd = None, env = None universal_newlines = None, startupinfo = None, creationflags = 0, shell = False p2cread = -1, p2cwrite = -1, c2pread = 11, c2pwrite = 78, errread = 79 errwrite = 80, restore_signals = True, gid = None, gids = None, uid = None umask = -1, start_new_session = False, process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ________ StandaloneIntegrationTests.test_default_headless_spawn_options ________ self = def test_default_headless_spawn_options(self): with mock_locustfile() as mocked: > output = subprocess.check_output( [ "locust", "-f", mocked.file_path, "--host", "https://test.com/", "--run-time", "1s", "--headless", "--loglevel", "DEBUG", "--exit-code-on-error", "0", ], stderr=subprocess.STDOUT, timeout=3, text=True, ).strip() locust/test/test_main.py:268: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:413: in check_output with Popen(*popenargs, stdout=PIPE, **kwargs) as process: /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551701_4192975_73966.py', '--host', 'https://test.com/', '--run-time', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = -1, errwrite = 78, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError __ StandaloneIntegrationTests.test_default_headless_spawn_options_with_shape ___ self = def test_default_headless_spawn_options_with_shape(self): content = MOCK_LOCUSTFILE_CONTENT + textwrap.dedent( """ class LoadTestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return (10, 1) return None """ ) with mock_locustfile(content=content) as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--host", "https://test.com/", "--headless", "--exit-code-on-error", "0", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:368: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551701_6051211_97361.py', '--host', 'https://test.com/', '--headless', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ____ StandaloneIntegrationTests.test_error_when_duplicate_shape_class_names ____ self = def test_error_when_duplicate_shape_class_names(self): MOCK_LOCUSTFILE_CONTENT_C = MOCK_LOCUSTFILE_CONTENT_A + textwrap.dedent( """ from locust import LoadTestShape class TestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return (10, 1) return None """ ) MOCK_LOCUSTFILE_CONTENT_D = MOCK_LOCUSTFILE_CONTENT_B + textwrap.dedent( """ from locust import LoadTestShape class TestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return (10, 1) return None """ ) with temporary_file(content=MOCK_LOCUSTFILE_CONTENT_C) as file1: with temporary_file(content=MOCK_LOCUSTFILE_CONTENT_D) as file2: > proc = subprocess.Popen(["locust", "-f", f"{file1},{file2}"], stdout=PIPE, stderr=PIPE, text=True) locust/test/test_main.py:1064: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmpc2grttnn_locustfile.py,/tmp/tmpzx2ve7oe_locustfile.py'] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _____ StandaloneIntegrationTests.test_error_when_duplicate_userclass_names _____ self = def test_error_when_duplicate_userclass_names(self): MOCK_LOCUSTFILE_CONTENT_C = textwrap.dedent( """ from locust import User, task, constant, events class TestUser1(User): wait_time = constant(3) @task def my_task(self): print("running my_task()") """ ) with temporary_file(content=MOCK_LOCUSTFILE_CONTENT_A) as file1: with temporary_file(content=MOCK_LOCUSTFILE_CONTENT_C) as file2: > proc = subprocess.Popen(["locust", "-f", f"{file1},{file2}"], stdout=PIPE, stderr=PIPE, text=True) locust/test/test_main.py:1012: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmp9ivqqmp7_locustfile.py,/tmp/tmp7sh0l8bw_locustfile.py'] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError __ StandaloneIntegrationTests.test_error_when_locustfiles_directory_is_empty ___ self = def test_error_when_locustfiles_directory_is_empty(self): with TemporaryDirectory() as temp_dir: > proc = subprocess.Popen(["locust", "-f", temp_dir], stdout=PIPE, stderr=PIPE, text=True) locust/test/test_main.py:1073: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmp_1gzmy_x'], executable = 'locust' preexec_fn = None, close_fds = True, pass_fds = (), cwd = None, env = None universal_newlines = None, startupinfo = None, creationflags = 0, shell = False p2cread = -1, p2cwrite = -1, c2pread = 11, c2pwrite = 78, errread = 79 errwrite = 80, restore_signals = True, gid = None, gids = None, uid = None umask = -1, start_new_session = False, process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ________ StandaloneIntegrationTests.test_error_when_no_tasks_match_tags ________ self = def test_error_when_no_tasks_match_tags(self): content = """ from locust import HttpUser, TaskSet, task, constant, LoadTestShape, tag class MyUser(HttpUser): host = "http://127.0.0.1:8089" wait_time = constant(1) @tag("tag1") @task def task1(self): print("task1") """ with mock_locustfile(content=content) as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--headless", "-t", "1", "--tags", "tag2", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:1092: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551702_5715394_86240.py', '--headless', '-t', '1', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ______ StandaloneIntegrationTests.test_headless_spawn_options_wo_run_time ______ self = def test_headless_spawn_options_wo_run_time(self): with mock_locustfile() as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--host", "https://test.com/", "--headless", "--exit-code-on-error", "0", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:291: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551702_8211079_39192.py', '--host', 'https://test.com/', '--headless', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = 79, errwrite = 80, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ___________________ StandaloneIntegrationTests.test_help_arg ___________________ self = def test_help_arg(self): > output = subprocess.check_output( ["locust", "--help"], stderr=subprocess.STDOUT, timeout=5, text=True, ).strip() locust/test/test_main.py:51: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:413: in check_output with Popen(*popenargs, stdout=PIPE, **kwargs) as process: /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '--help'], executable = 'locust', preexec_fn = None close_fds = True, pass_fds = (), cwd = None, env = None universal_newlines = None, startupinfo = None, creationflags = 0, shell = False p2cread = -1, p2cwrite = -1, c2pread = 11, c2pwrite = 78, errread = -1 errwrite = 78, restore_signals = True, gid = None, gids = None, uid = None umask = -1, start_new_session = False, process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ______________ StandaloneIntegrationTests.test_html_report_option ______________ self = def test_html_report_option(self): with mock_locustfile() as mocked: with temporary_file("", suffix=".html") as html_report_file_path: try: > output = subprocess.check_output( [ "locust", "-f", mocked.file_path, "--host", "https://test.com/", "--run-time", "2s", "--headless", "--exit-code-on-error", "0", "--html", html_report_file_path, ], stderr=subprocess.STDOUT, timeout=10, text=True, ).strip() locust/test/test_main.py:944: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:413: in check_output with Popen(*popenargs, stdout=PIPE, **kwargs) as process: /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551703_20291_1032.py', '--host', 'https://test.com/', '--run-time', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 78, errread = -1, errwrite = 78, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ____________________ StandaloneIntegrationTests.test_input _____________________ self = def test_input(self): LOCUSTFILE_CONTENT = textwrap.dedent( """ from locust import User, TaskSet, task, between class UserSubclass(User): wait_time = between(0.2, 0.8) @task def t(self): print("Test task is running") """ ) with mock_locustfile(content=LOCUSTFILE_CONTENT) as mocked: stdin_m, stdin_s = pty.openpty() stdin = os.fdopen(stdin_m, "wb", 0) proc = subprocess.Popen( " ".join( [ "locust", "-f", mocked.file_path, "--headless", "--run-time", "7s", "-u", "0", "--loglevel", "INFO", ] ), stderr=STDOUT, stdin=stdin_s, stdout=PIPE, shell=True, text=True, ) gevent.sleep(1) stdin.write(b"w") gevent.sleep(1) stdin.write(b"W") gevent.sleep(1) stdin.write(b"s") gevent.sleep(1) stdin.write(b"S") gevent.sleep(1) # This should not do anything since we are already at zero users stdin.write(b"S") gevent.sleep(1) output = proc.communicate()[0] stdin.close() > self.assertIn("Ramping to 1 users at a rate of 100.00 per second", output) E AssertionError: 'Ramping to 1 users at a rate of 100.00 per second' not found in '/build/locust-2.12.1/debian/locust: 2: from: not found\n/build/locust-2.12.1/debian/locust: 5: Syntax error: end of file unexpected\n' locust/test/test_main.py:778: AssertionError __ StandaloneIntegrationTests.test_no_error_when_same_userclass_in_two_files ___ self = def test_no_error_when_same_userclass_in_two_files(self): with temporary_file(content=MOCK_LOCUSTFILE_CONTENT_A) as file1: MOCK_LOCUSTFILE_CONTENT_C = textwrap.dedent( f""" from {os.path.basename(file1)[:-3]} import TestUser1 """ ) print(MOCK_LOCUSTFILE_CONTENT_C) with temporary_file(content=MOCK_LOCUSTFILE_CONTENT_C) as file2: > proc = subprocess.Popen( ["locust", "-f", f"{file1},{file2}", "-t", "1", "--headless"], stdout=PIPE, stderr=PIPE, text=True ) locust/test/test_main.py:1028: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmprz81sf86_locustfile.py,/tmp/tmpkfxi6f9__locustfile.py', '-t', '1', '--headless'] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ----------------------------- Captured stdout call ----------------------------- from tmprz81sf86_locustfile import TestUser1 ___ StandaloneIntegrationTests.test_run_autostart_with_multiple_locustfiles ____ self = def test_run_autostart_with_multiple_locustfiles(self): with TemporaryDirectory() as temp_dir: with mock_locustfile(dir=temp_dir): with temporary_file( content=textwrap.dedent( """ from locust import User, task, constant, events class TestUser(User): wait_time = constant(1) @task def my_task(self): print("running my_task()") """ ), dir=temp_dir, ): > proc = subprocess.Popen( [ "locust", "-f", temp_dir, "--autostart", "-u", "2", "--exit-code-on-error", "0", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:546: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmp1zh74hq7', '--autostart', '-u', '2', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ____ StandaloneIntegrationTests.test_run_headless_with_multiple_locustfiles ____ self = def test_run_headless_with_multiple_locustfiles(self): with TemporaryDirectory() as temp_dir: with mock_locustfile(dir=temp_dir): with temporary_file( content=textwrap.dedent( """ from locust import User, task, constant, events class TestUser(User): wait_time = constant(1) @task def my_task(self): print("running my_task()") """ ), dir=temp_dir, ): > proc = subprocess.Popen( [ "locust", "-f", temp_dir, "--headless", "-u", "2", "--exit-code-on-error", "0", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:330: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmpi1lrxvdg', '--headless', '-u', '2', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _ StandaloneIntegrationTests.test_run_headless_with_multiple_locustfiles_with_shape _ self = def test_run_headless_with_multiple_locustfiles_with_shape(self): content = textwrap.dedent( """ from locust import User, task, between class TestUser2(User): wait_time = between(2, 4) @task def my_task(self): print("running my_task() again") """ ) with mock_locustfile(content=content) as mocked1: with temporary_file( content=textwrap.dedent( """ from locust import User, task, between, LoadTestShape class LoadTestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return (10, 1) return None class TestUser(User): wait_time = between(2, 4) @task def my_task(self): print("running my_task()") """ ) ) as mocked2: > proc = subprocess.Popen( [ "locust", "-f", f"{mocked1.file_path},{mocked2}", "--host", "https://test.com/", "--headless", "--exit-code-on-error", "0", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:433: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551710_1560144_38304.py,/tmp/tmp0yr7sa_z_locustfile.py', '--host', 'https://test.com/', '--headless', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError __________ StandaloneIntegrationTests.test_run_with_userclass_picker ___________ self = def test_run_with_userclass_picker(self): with temporary_file(content=MOCK_LOCUSTFILE_CONTENT_A) as file1: with temporary_file(content=MOCK_LOCUSTFILE_CONTENT_B) as file2: > proc = subprocess.Popen( ["locust", "-f", f"{file1},{file2}", "--class-picker"], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:985: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmp_gyhsou2_locustfile.py,/tmp/tmp2e38278q_locustfile.py', '--class-picker'] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ___ StandaloneIntegrationTests.test_spawing_with_fixed_multiple_locustfiles ____ self = def test_spawing_with_fixed_multiple_locustfiles(self): with mock_locustfile(content=MOCK_LOCUSTFILE_CONTENT_A) as mocked1: with mock_locustfile(content=MOCK_LOCUSTFILE_CONTENT_B) as mocked2: proc = subprocess.Popen( " ".join( [ "locust", "-f", f"{mocked1.file_path},{mocked2.file_path}", "--headless", "--run-time", "5s", "-u", "10", "-r", "10", "--loglevel", "INFO", ] ), stderr=STDOUT, stdout=PIPE, shell=True, text=True, ) output = proc.communicate()[0] > self.assertIn("Ramping to 10 users at a rate of 10.00 per second", output) E AssertionError: 'Ramping to 10 users at a rate of 10.00 per second' not found in '/build/locust-2.12.1/debian/locust: 2: from: not found\n/build/locust-2.12.1/debian/locust: 5: Syntax error: end of file unexpected\n' locust/test/test_main.py:878: AssertionError _____________ StandaloneIntegrationTests.test_spawning_with_fixed ______________ self = def test_spawning_with_fixed(self): LOCUSTFILE_CONTENT = textwrap.dedent( """ from locust import User, task, constant class User1(User): fixed_count = 2 wait_time = constant(1) @task def t(self): print("Test task is running") class User2(User): wait_time = constant(1) @task def t(self): print("Test task is running") class User3(User): wait_time = constant(1) @task def t(self): print("Test task is running") """ ) with mock_locustfile(content=LOCUSTFILE_CONTENT) as mocked: proc = subprocess.Popen( " ".join( [ "locust", "-f", mocked.file_path, "--headless", "--run-time", "5s", "-u", "10", "-r", "10", "--loglevel", "INFO", ] ), stderr=STDOUT, stdout=PIPE, shell=True, text=True, ) output = proc.communicate()[0] > self.assertIn("Ramping to 10 users at a rate of 10.00 per second", output) E AssertionError: 'Ramping to 10 users at a rate of 10.00 per second' not found in '/build/locust-2.12.1/debian/locust: 2: from: not found\n/build/locust-2.12.1/debian/locust: 5: Syntax error: end of file unexpected\n' locust/test/test_main.py:843: AssertionError _________________ StandaloneIntegrationTests.test_web_options __________________ self = def test_web_options(self): port = get_free_tcp_port() if platform.system() == "Darwin": # MacOS only sets up the loopback interface for 127.0.0.1 and not for 127.*.*.* interface = "127.0.0.1" else: interface = "127.0.0.2" with mock_locustfile() as mocked: > proc = subprocess.Popen( ["locust", "-f", mocked.file_path, "--web-host", interface, "--web-port", str(port)], stdout=PIPE, stderr=PIPE, ) locust/test/test_main.py:697: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551710_9397626_96974.py', '--web-host', '127.0.0.2', '--web-port', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError __________________ StandaloneIntegrationTests.test_webserver ___________________ self = def test_webserver(self): with temporary_file( content=textwrap.dedent( """ from locust import User, task, constant, events class TestUser(User): wait_time = constant(3) @task def my_task(self): print("running my_task()") """ ) ) as file_path: > proc = subprocess.Popen(["locust", "-f", file_path], stdout=PIPE, stderr=PIPE, text=True) locust/test/test_main.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmpan69k5fm_locustfile.py'], executable = 'locust' preexec_fn = None, close_fds = True, pass_fds = (), cwd = None, env = None universal_newlines = None, startupinfo = None, creationflags = 0, shell = False p2cread = -1, p2cwrite = -1, c2pread = 11, c2pwrite = 79, errread = 80 errwrite = 81, restore_signals = True, gid = None, gids = None, uid = None umask = -1, start_new_session = False, process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ________ StandaloneIntegrationTests.test_webserver_multiple_locustfiles ________ self = def test_webserver_multiple_locustfiles(self): with mock_locustfile(content=MOCK_LOCUSTFILE_CONTENT_A) as mocked1: with mock_locustfile(content=MOCK_LOCUSTFILE_CONTENT_B) as mocked2: > proc = subprocess.Popen( ["locust", "-f", f"{mocked1.file_path},{mocked2.file_path}"], stdout=PIPE, stderr=PIPE, text=True ) locust/test/test_main.py:196: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551711_4052985_86925.py,/build/locust-2.12.1/locust/test/mock_locustfile_1716551711_4057608_18293.py'] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _ StandaloneIntegrationTests.test_webserver_multiple_locustfiles_in_directory __ self = def test_webserver_multiple_locustfiles_in_directory(self): with TemporaryDirectory() as temp_dir: with mock_locustfile(content=MOCK_LOCUSTFILE_CONTENT_A, dir=temp_dir): with mock_locustfile(content=MOCK_LOCUSTFILE_CONTENT_B, dir=temp_dir): > proc = subprocess.Popen(["locust", "-f", temp_dir], stdout=PIPE, stderr=PIPE, text=True) locust/test/test_main.py:212: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/tmp/tmp81rtjx7p'], executable = 'locust' preexec_fn = None, close_fds = True, pass_fds = (), cwd = None, env = None universal_newlines = None, startupinfo = None, creationflags = 0, shell = False p2cread = -1, p2cwrite = -1, c2pread = 11, c2pwrite = 79, errread = 80 errwrite = 81, restore_signals = True, gid = None, gids = None, uid = None umask = -1, start_new_session = False, process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError __ StandaloneIntegrationTests.test_webserver_multiple_locustfiles_with_shape ___ self = def test_webserver_multiple_locustfiles_with_shape(self): content = textwrap.dedent( """ from locust import User, task, between class TestUser2(User): wait_time = between(2, 4) @task def my_task(self): print("running my_task() again") """ ) with mock_locustfile(content=content) as mocked1: with temporary_file( content=textwrap.dedent( """ from locust import User, task, between, LoadTestShape class LoadTestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return (10, 1) return None class TestUser(User): wait_time = between(2, 4) @task def my_task(self): print("running my_task()") """ ) ) as mocked2: > proc = subprocess.Popen( ["locust", "-f", f"{mocked1.file_path},{mocked2}"], stdout=PIPE, stderr=PIPE, text=True ) locust/test/test_main.py:254: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551711_7671833_35428.py,/tmp/tmplhb54_h5_locustfile.py'] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _________________ DistributedIntegrationTests.test_distributed _________________ self = def test_distributed(self): LOCUSTFILE_CONTENT = textwrap.dedent( """ from locust import User, task, constant class User1(User): wait_time = constant(1) @task def t(self): pass """ ) with mock_locustfile(content=LOCUSTFILE_CONTENT) as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--headless", "--master", "--expect-workers", "1", "-u", "3", "-t", "5s", ], stderr=STDOUT, stdout=PIPE, text=True, ) locust/test/test_main.py:1282: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551711_9707363_76743.py', '--headless', '--master', '--expect-workers', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = -1, errwrite = 79, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _____________ DistributedIntegrationTests.test_distributed_events ______________ self = def test_distributed_events(self): content = ( MOCK_LOCUSTFILE_CONTENT + """ from locust import events from locust.runners import MasterRunner @events.test_start.add_listener def on_test_start(environment, **kwargs): if isinstance(environment.runner, MasterRunner): print("test_start on master") else: print("test_start on worker") @events.test_stop.add_listener def on_test_stop(environment, **kwargs): if isinstance(environment.runner, MasterRunner): print("test_stop on master") else: print("test_stop on worker") """ ) with mock_locustfile(content=content) as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--headless", "--master", "--expect-workers", "1", "-t", "1", "--exit-code-on-error", "0", "-L", "DEBUG", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:1160: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551712_3176918_29574.py', '--headless', '--master', '--expect-workers', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _____ DistributedIntegrationTests.test_distributed_report_timeout_expired ______ self = def test_distributed_report_timeout_expired(self): LOCUSTFILE_CONTENT = textwrap.dedent( """ from locust import User, task, constant class User1(User): wait_time = constant(1) @task def t(self): pass """ ) with mock_locustfile(content=LOCUSTFILE_CONTENT) as mocked, patch_env( "LOCUST_WAIT_FOR_WORKERS_REPORT_AFTER_RAMP_UP", "0.01" ) as _: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--headless", "--master", "--expect-workers", "1", "-u", "3", "-t", "5s", ], stderr=STDOUT, stdout=PIPE, text=True, ) locust/test/test_main.py:1336: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551712_51253_7916.py', '--headless', '--master', '--expect-workers', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = -1, errwrite = 79, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ______________ DistributedIntegrationTests.test_distributed_tags _______________ self = def test_distributed_tags(self): content = """ from locust import HttpUser, TaskSet, task, between, LoadTestShape, tag class SecondUser(HttpUser): host = "http://127.0.0.1:8089" wait_time = between(0, 0.1) @tag("tag1") @task def task1(self): print("task1") @tag("tag2") @task def task2(self): print("task2") """ with mock_locustfile(content=content) as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--headless", "--master", "--expect-workers", "1", "-t", "1", "-u", "2", "--exit-code-on-error", "0", "-L", "DEBUG", "--tags", "tag1", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:1221: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551712_7041698_97935.py', '--headless', '--master', '--expect-workers', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _______________ DistributedIntegrationTests.test_expect_workers ________________ self = def test_expect_workers(self): with mock_locustfile() as mocked: > proc = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--headless", "--master", "--expect-workers", "2", "--expect-workers-max-wait", "1", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:1116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551712_9664903_73428.py', '--headless', '--master', '--expect-workers', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError __________________ DistributedIntegrationTests.test_help_arg ___________________ self = def test_help_arg(self): > output = subprocess.check_output( ["locust", "--help"], stderr=subprocess.STDOUT, timeout=5, text=True, ).strip() locust/test/test_main.py:51: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:413: in check_output with Popen(*popenargs, stdout=PIPE, **kwargs) as process: /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '--help'], executable = 'locust', preexec_fn = None close_fds = True, pass_fds = (), cwd = None, env = None universal_newlines = None, startupinfo = None, creationflags = 0, shell = False p2cread = -1, p2cwrite = -1, c2pread = 11, c2pwrite = 79, errread = -1 errwrite = 79, restore_signals = True, gid = None, gids = None, uid = None umask = -1, start_new_session = False, process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError _______________ DistributedIntegrationTests.test_worker_indexes ________________ self = def test_worker_indexes(self): content = """ from locust import HttpUser, task, between class AnyUser(HttpUser): host = "http://127.0.0.1:8089" wait_time = between(0, 0.1) @task def my_task(self): print("worker index:", self.environment.runner.worker_index) """ with mock_locustfile(content=content) as mocked: > master = subprocess.Popen( [ "locust", "-f", mocked.file_path, "--headless", "--master", "--expect-workers", "2", "-t", "5", "-u", "2", "-L", "DEBUG", ], stdout=PIPE, stderr=PIPE, text=True, ) locust/test/test_main.py:1389: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/gevent/subprocess.py:842: in __init__ self._execute_child(args, executable, preexec_fn, close_fds, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ['locust', '-f', '/build/locust-2.12.1/locust/test/mock_locustfile_1716551713_5529037_40905.py', '--headless', '--master', '--expect-workers', ...] executable = 'locust', preexec_fn = None, close_fds = True, pass_fds = () cwd = None, env = None, universal_newlines = None, startupinfo = None creationflags = 0, shell = False, p2cread = -1, p2cwrite = -1, c2pread = 11 c2pwrite = 79, errread = 80, errwrite = 81, restore_signals = True, gid = None gids = None, uid = None, umask = -1, start_new_session = False process_group = None def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group): """Execute program (POSIX version)""" if PY3 and isinstance(args, (str, bytes)): args = [args] elif not PY3 and isinstance(args, string_types): args = [args] elif isinstance(args, PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = [fsencode(args)] # os.PathLike -> [str] else: args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. unix_shell = ( '/system/bin/sh' if hasattr(sys, 'getandroidapilevel') else '/bin/sh' ) args = [unix_shell, "-c"] + args if executable: args[0] = executable if executable is None: executable = args[0] self._loop.install_sigchld() # For transferring possible exec failure from child to parent # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = self.pipe_cloexec() # errpipe_write must not be in the standard io 0, 1, or 2 fd range. low_fds_to_close = [] while errpipe_write < 3: low_fds_to_close.append(errpipe_write) errpipe_write = os.dup(errpipe_write) for low_fd in low_fds_to_close: os.close(low_fd) try: try: gc_was_enabled = gc.isenabled() # Disable gc to avoid bug where gc -> file_dealloc -> # write to stderr -> hang. http://bugs.python.org/issue1336 gc.disable() try: self.pid = fork_and_watch(self._on_child, self._loop, True, fork) except: if gc_was_enabled: gc.enable() raise if self.pid == 0: # Child # XXX: Technically we're doing a lot of stuff here that # may not be safe to do before a exec(), depending on the OS. # CPython 3 goes to great lengths to precompute a lot # of this info before the fork and pass it all to C functions that # try hard not to call things like malloc(). (Of course, # CPython 2 pretty much did what we're doing.) try: # Close parent's pipe ends if p2cwrite != -1: os.close(p2cwrite) if c2pread != -1: os.close(c2pread) if errread != -1: os.close(errread) os.close(errpipe_read) # When duping fds, if there arises a situation # where one of the fds is either 0, 1 or 2, it # is possible that it is overwritten (#12607). if c2pwrite == 0: c2pwrite = os.dup(c2pwrite) _set_inheritable(c2pwrite, False) while errwrite in (0, 1): errwrite = os.dup(errwrite) _set_inheritable(errwrite, False) # Dup fds for child def _dup2(existing, desired): # dup2() removes the CLOEXEC flag but # we must do it ourselves if dup2() # would be a no-op (issue #10806). if existing == desired: self._set_cloexec_flag(existing, False) elif existing != -1: os.dup2(existing, desired) try: self._remove_nonblock_flag(desired) except OSError: # Ignore EBADF, it may not actually be # open yet. # Tested beginning in 3.7.0b3 test_subprocess.py pass _dup2(p2cread, 0) _dup2(c2pwrite, 1) _dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. if not PY3: closed = set([None]) for fd in [p2cread, c2pwrite, errwrite]: if fd not in closed and fd > 2: os.close(fd) closed.add(fd) # Python 3 (with a working set_inheritable): # We no longer manually close p2cread, # c2pwrite, and errwrite here as # _close_open_fds takes care when it is # not already non-inheritable. if cwd is not None: try: os.chdir(cwd) except OSError as e: e._failed_chdir = True raise # Python 3.9 if umask >= 0: os.umask(umask) # XXX: CPython does _Py_RestoreSignals here. # Then setsid() based on ??? if gids: os.setgroups(gids) if gid: os.setregid(gid, gid) if uid: os.setreuid(uid, uid) if process_group is not None: os.setpgid(0, process_group) if preexec_fn: preexec_fn() # Close all other fds, if asked for. This must be done # after preexec_fn runs. if close_fds: fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) self._close_fds(fds_to_keep, errpipe_write) if restore_signals: # restore the documented signals back to sig_dfl; # not all will be defined on every platform for sig in 'SIGPIPE', 'SIGXFZ', 'SIGXFSZ': sig = getattr(signal, sig, None) if sig is not None: signal.signal(sig, signal.SIG_DFL) if start_new_session: os.setsid() if env is None: os.execvp(executable, args) else: if PY3: # Python 3.6 started testing for # bytes values in the env; it also # started encoding strs using # fsencode and using a lower-level # API that takes a list of keys # and values. We don't have access # to that API, so we go the reverse direction. env = {os.fsdecode(k) if isinstance(k, bytes) else k: os.fsdecode(v) if isinstance(v, bytes) else v for k, v in env.items()} os.execvpe(executable, args, env) except: exc_type, exc_value, tb = sys.exc_info() # Save the traceback and attach it to the exception object exc_lines = traceback.format_exception(exc_type, exc_value, tb) exc_value.child_traceback = ''.join(exc_lines) os.write(errpipe_write, pickle.dumps(exc_value)) finally: # Make sure that the process exits no matter what. # The return code does not matter much as it won't be # reported to the application os._exit(1) # Parent self._child_created = True if gc_was_enabled: gc.enable() finally: # be sure the FD is closed no matter what os.close(errpipe_write) # self._devnull is not always defined. devnull_fd = getattr(self, '_devnull', None) if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) if devnull_fd is not None: os.close(devnull_fd) # Prevent a double close of these fds from __init__ on error. self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising exception errpipe_read = FileObject(errpipe_read, 'rb') data = errpipe_read.read() finally: try: if hasattr(errpipe_read, 'close'): errpipe_read.close() else: os.close(errpipe_read) except OSError: # Especially on PyPy, we sometimes see the above # `os.close(errpipe_read)` raise an OSError. # It's not entirely clear why, but it happens in # InterprocessSignalTests.test_main sometimes, which must mean # we have some sort of race condition. pass finally: errpipe_read = -1 if data != b"": self.wait() child_exception = pickle.loads(data) for fd in (p2cwrite, c2pread, errread): if fd is not None and fd != -1: os.close(fd) if isinstance(child_exception, OSError): child_exception.filename = executable if hasattr(child_exception, '_failed_chdir'): child_exception.filename = cwd > raise child_exception E OSError: [Errno 8] Exec format error: 'locust' /usr/lib/python3/dist-packages/gevent/subprocess.py:1866: OSError ______________________ TestLocustRunner.test_cpu_warning _______________________ self = def test_cpu_warning(self): _monitor_interval = runners.CPU_MONITOR_INTERVAL runners.CPU_MONITOR_INTERVAL = 2.0 try: class CpuUser(User): wait_time = constant(0.001) @task def cpu_task(self): for i in range(1000000): _ = 3 / 2 environment = Environment(user_classes=[CpuUser]) environment._cpu_warning_event_triggered = False def cpu_warning(environment, cpu_usage, **kwargs): environment._cpu_warning_event_triggered = True environment._cpu_usage = cpu_usage environment.events.cpu_warning.add_listener(cpu_warning) runner = LocalRunner(environment) self.assertFalse(runner.cpu_warning_emitted) runner.spawn_users({CpuUser.__name__: 1}, wait=False) sleep(2.5) > self.assertTrue(environment._cpu_warning_event_triggered) E AssertionError: False is not true locust/test/test_runners.py:162: AssertionError _______________ TestLocustRunner.test_stop_users_with_spawn_rate _______________ self = def test_stop_users_with_spawn_rate(self): """ The spawn rate does not have an effect on the rate at which the users are stopped. It is expected that the excess users will be stopped as soon as possible in parallel (while respecting the stop_timeout). """ class MyUser(User): wait_time = constant(1) @task def my_task(self): pass environment = Environment(user_classes=[MyUser]) runner = LocalRunner(environment) # Start load test, wait for users to start, then trigger ramp down ts = time.time() runner.start(10, 10, wait=False) runner.spawning_greenlet.join() delta = time.time() - ts self.assertTrue( 0 <= delta <= 0.05, f"Expected user count to increase to 10 instantaneously, instead it took {delta:f}" ) self.assertTrue( runner.user_count == 10, "User count has not decreased correctly to 2, it is : %i" % runner.user_count ) ts = time.time() runner.start(2, 4, wait=False) runner.spawning_greenlet.join() delta = time.time() - ts > self.assertTrue(0 <= delta <= 1.05, f"Expected user count to decrease to 2 in 1s, instead it took {delta:f}") E AssertionError: False is not true : Expected user count to decrease to 2 in 1s, instead it took 1.076156 locust/test/test_runners.py:482: AssertionError ------------------------------ Captured log call ------------------------------- INFO locust.runners:runners.py:507 Ramping to 10 users at a rate of 10.00 per second INFO locust.runners:runners.py:545 All users spawned: {"MyUser": 10} (10 total users) INFO locust.runners:runners.py:507 Ramping to 2 users at a rate of 4.00 per second INFO locust.runners:runners.py:545 All users spawned: {"MyUser": 2} (2 total users) ________ TestMasterRunner.test_attributes_populated_when_calling_start _________ self = def test_attributes_populated_when_calling_start(self): class MyUser1(User): @task def my_task(self): pass class MyUser2(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[MyUser1, MyUser2]) server.mocked_send(Message("client_ready", __version__, "fake_client1")) master.start(7, 7) > self.assertEqual({"MyUser1": 4, "MyUser2": 3}, master.target_user_classes_count) E AssertionError: {'MyUser1': 4, 'MyUser2': 3} != {} E - {'MyUser1': 4, 'MyUser2': 3} E + {} locust/test/test_runners.py:2903: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected ________________ TestMasterRunner.test_custom_shape_scale_down _________________ self = def test_custom_shape_scale_down(self): class MyUser(User): @task def my_task(self): pass class TestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return 5, 5 elif run_time < 4: return 1, 5 else: return None self.environment.shape_class = TestShape() with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[MyUser]) for i in range(5): server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i)) # Start the shape_worker self.environment.shape_class.reset_time() master.start_shape() sleep(0.5) # Wait for shape_worker to update user_count num_users = sum( sum(msg.data["user_classes_count"].values()) for _, msg in server.outbox if msg.type != "ack" ) > self.assertEqual( 5, num_users, "Total number of users in first stage of shape test is not 5: %i" % num_users ) E AssertionError: 5 != 0 : Total number of users in first stage of shape test is not 5: 0 locust/test/test_runners.py:2777: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client0). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client4). That's not going to work. INFO locust.runners:runners.py:344 Shape test starting. User count and spawn rate are ignored for this type of load test INFO locust.runners:runners.py:352 Shape worker starting INFO locust.runners:runners.py:372 Shape test updating to 5 users at 5.00 spawn rate WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines _________________ TestMasterRunner.test_custom_shape_scale_up __________________ self = def test_custom_shape_scale_up(self): class MyUser(User): @task def my_task(self): pass class TestShape(LoadTestShape): def tick(self): run_time = self.get_run_time() if run_time < 2: return 1, 1 elif run_time < 4: return 2, 2 else: return None self.environment.shape_class = TestShape() with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[MyUser]) for i in range(5): server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i)) # Start the shape_worker self.environment.shape_class.reset_time() master.start_shape() sleep(0.5) # Wait for shape_worker to update user_count num_users = sum( sum(msg.data["user_classes_count"].values()) for _, msg in server.outbox if msg.type != "ack" ) > self.assertEqual( 1, num_users, "Total number of users in first stage of shape test is not 1: %i" % num_users ) E AssertionError: 1 != 0 : Total number of users in first stage of shape test is not 1: 0 locust/test/test_runners.py:2728: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client0). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client4). That's not going to work. INFO locust.runners:runners.py:344 Shape test starting. User count and spawn rate are ignored for this type of load test INFO locust.runners:runners.py:352 Shape worker starting INFO locust.runners:runners.py:372 Shape test updating to 1 users at 1.00 spawn rate WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines _____________ TestMasterRunner.test_last_worker_missing_stops_test _____________ self = @mock.patch("locust.runners.HEARTBEAT_INTERVAL", new=0.1) def test_last_worker_missing_stops_test(self): class TestUser(User): @task def my_task(self): gevent.sleep(600) with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server, patch_env( "LOCUST_WAIT_FOR_WORKERS_REPORT_AFTER_RAMP_UP", "0.1" ): master = self.get_runner(user_classes=[TestUser]) server.mocked_send(Message("client_ready", __version__, "fake_client1")) server.mocked_send(Message("client_ready", __version__, "fake_client2")) server.mocked_send(Message("client_ready", __version__, "fake_client3")) master.start(3, 3) server.mocked_send(Message("spawning", None, "fake_client1")) server.mocked_send(Message("spawning", None, "fake_client2")) server.mocked_send(Message("spawning", None, "fake_client3")) sleep(0.2) server.mocked_send( Message( "heartbeat", {"state": STATE_RUNNING, "current_cpu_usage": 50, "current_memory_usage": 200, "count": 1}, "fake_client1", ) ) server.mocked_send( Message( "heartbeat", {"state": STATE_RUNNING, "current_cpu_usage": 50, "current_memory_usage": 200, "count": 1}, "fake_client2", ) ) server.mocked_send( Message( "heartbeat", {"state": STATE_RUNNING, "current_cpu_usage": 50, "current_memory_usage": 200, "count": 1}, "fake_client3", ) ) sleep(0.2) self.assertEqual(0, len(master.clients.missing)) > self.assertEqual(3, master.worker_count) E AssertionError: 3 != 0 locust/test/test_runners.py:2167: AssertionError ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "/build/locust-2.12.1/locust/runners.py", line 1088, in client_listener self.clients[msg.node_id].state = STATE_SPAWNING ~~~~~~~~~~~~^^^^^^^^^^^^^ File "/build/locust-2.12.1/locust/runners.py", line 644, in __getitem__ return self._worker_nodes[k] ~~~~~~~~~~~~~~~~~~^^^ KeyError: 'fake_client1' 2024-05-24T11:56:00Z >> failed with KeyError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected CRITICAL locust.runners:log.py:74 Unhandled exception in greenlet: >> Traceback (most recent call last): File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "/build/locust-2.12.1/locust/runners.py", line 1088, in client_listener self.clients[msg.node_id].state = STATE_SPAWNING ^^^^^^^^^^^^^^^^^ File "/build/locust-2.12.1/locust/runners.py", line 644, in __getitem__ return self._worker_nodes[k] ^^^^^^^^^^^^^^^^^ KeyError: 'fake_client1' INFO locust.runners:runners.py:372 Shape test updating to 1 users at 5.00 spawn rate WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected INFO locust.runners:runners.py:957 Worker 0 failed to send heartbeat, setting state to missing. INFO locust.runners:runners.py:957 Worker 1 failed to send heartbeat, setting state to missing. INFO locust.runners:runners.py:957 Worker 2 failed to send heartbeat, setting state to missing. INFO locust.runners:runners.py:957 Worker 3 failed to send heartbeat, setting state to missing. INFO locust.runners:runners.py:957 Worker 4 failed to send heartbeat, setting state to missing. INFO locust.runners:runners.py:965 The last worker went missing, stopping test. ____________ TestMasterRunner.test_last_worker_quitting_stops_test _____________ self = def test_last_worker_quitting_stops_test(self): class TestUser(User): @task def my_task(self): gevent.sleep(600) with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server, patch_env( "LOCUST_WAIT_FOR_WORKERS_REPORT_AFTER_RAMP_UP", "0.1" ): master = self.get_runner(user_classes=[TestUser]) server.mocked_send(Message("client_ready", __version__, "fake_client1")) server.mocked_send(Message("client_ready", __version__, "fake_client2")) master.start(1, 2) server.mocked_send(Message("spawning", None, "fake_client1")) server.mocked_send(Message("spawning", None, "fake_client2")) server.mocked_send(Message("quit", None, "fake_client1")) sleep(0.1) > self.assertEqual(1, len(master.clients.all)) E AssertionError: 1 != 0 locust/test/test_runners.py:2114: AssertionError ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "/build/locust-2.12.1/locust/runners.py", line 1088, in client_listener self.clients[msg.node_id].state = STATE_SPAWNING ~~~~~~~~~~~~^^^^^^^^^^^^^ File "/build/locust-2.12.1/locust/runners.py", line 644, in __getitem__ return self._worker_nodes[k] ~~~~~~~~~~~~~~~~~~^^^ KeyError: 'fake_client1' 2024-05-24T11:56:00Z >> failed with KeyError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected CRITICAL locust.runners:log.py:74 Unhandled exception in greenlet: >> Traceback (most recent call last): File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "/build/locust-2.12.1/locust/runners.py", line 1088, in client_listener self.clients[msg.node_id].state = STATE_SPAWNING ^^^^^^^^^^^^^^^^^ File "/build/locust-2.12.1/locust/runners.py", line 644, in __getitem__ return self._worker_nodes[k] ^^^^^^^^^^^^^^^^^ KeyError: 'fake_client1' INFO locust.runners:runners.py:372 Shape test updating to 2 users at 2.00 spawn rate WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected ___________ TestMasterRunner.test_master_discard_first_client_ready ____________ self = def test_master_discard_first_client_ready(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: server.mocked_send(Message("client_ready", __version__, "dummy_client")) # discard first client_ready msg server.queue.get() master = self.get_runner() server.mocked_send(Message("client_ready", __version__, "dummy_client")) > self.assertEqual(1, len(master.clients)) E AssertionError: 1 != 0 locust/test/test_runners.py:3018: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (dummy_client). That's not going to work. _________ TestMasterRunner.test_master_marks_downed_workers_as_missing _________ self = def test_master_marks_downed_workers_as_missing(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", __version__, "fake_client")) sleep(6) # print(master.clients['fake_client'].__dict__) > assert master.clients["fake_client"].state == STATE_MISSING locust/test/test_runners.py:2093: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , k = 'fake_client' def __getitem__(self, k: str) -> WorkerNode: > return self._worker_nodes[k] E KeyError: 'fake_client' locust/runners.py:644: KeyError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client). That's not going to work. WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines INFO locust.runners:runners.py:356 Shape test stopping INFO locust.runners:runners.py:356 Shape test stopping ________________ TestMasterRunner.test_master_reset_connection _________________ self = def test_master_reset_connection(self): """Test that connection will be reset when network issues found""" with mock.patch("locust.runners.FALLBACK_INTERVAL", new=0.1): with mock.patch("locust.rpc.rpc.Server", mocked_rpc(raise_on_close=False)) as server: master = self.get_runner() self.assertEqual(0, len(master.clients)) server.mocked_send(Message("client_ready", NETWORK_BROKEN, "fake_client")) self.assertTrue(master.connection_broken) server.mocked_send(Message("client_ready", __version__, "fake_client")) sleep(1) self.assertFalse(master.connection_broken) > self.assertEqual(1, len(master.clients)) E AssertionError: 1 != 0 locust/test/test_runners.py:2868: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client). That's not going to work. WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines INFO locust.runners:runners.py:983 Resetting RPC server and all worker connections. ________ TestMasterRunner.test_rebalance_locust_users_on_worker_connect ________ self = @mock.patch("locust.runners.HEARTBEAT_INTERVAL", new=600) def test_rebalance_locust_users_on_worker_connect(self): class TestUser(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[TestUser]) server.mocked_send(Message("client_ready", __version__, "zeh_fake_client1")) > self.assertEqual(1, len(master.clients)) E AssertionError: 1 != 0 locust/test/test_runners.py:2442: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (zeh_fake_client1). That's not going to work. ____________ TestMasterRunner.test_reset_connection_after_RPCError _____________ self = def test_reset_connection_after_RPCError(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc(raise_on_close=False)) as server: master = self.get_runner() server.mocked_send(Message("client_ready", __version__, "fake_client")) sleep(0.2) self.assertFalse(master.connection_broken) > self.assertEqual(1, len(master.clients)) E AssertionError: 1 != 0 locust/test/test_runners.py:2877: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client). That's not going to work. WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines ______________ TestMasterRunner.test_spawn_correct_worker_indexes ______________ self = def test_spawn_correct_worker_indexes(self): """ Tests that workers would receive a monotonic sequence of ordinal IDs. """ class TestUser(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[TestUser]) USERS_COUNT = 5 for i in range(USERS_COUNT): server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i)) master.start(USERS_COUNT, USERS_COUNT) > self.assertEqual(USERS_COUNT * 2, len(server.outbox)) E AssertionError: 10 != 0 locust/test/test_runners.py:2684: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client0). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client4). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected ____________ TestMasterRunner.test_spawn_fewer_locusts_than_workers ____________ self = def test_spawn_fewer_locusts_than_workers(self): class TestUser(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[TestUser]) for i in range(5): server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i)) master.start(2, 2) > self.assertEqual(10, len(server.outbox)) E AssertionError: 10 != 0 locust/test/test_runners.py:2657: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client0). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client4). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected __________________ TestMasterRunner.test_spawn_uneven_locusts __________________ self = def test_spawn_uneven_locusts(self): """ Tests that we can accurately spawn a certain number of locusts, even if it's not an even number of the connected workers """ class TestUser(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[TestUser]) for i in range(5): server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i)) master.start(7, 7) > self.assertEqual(10, len(server.outbox)) E AssertionError: 10 != 0 locust/test/test_runners.py:2636: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client0). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client4). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected ______________________ TestMasterRunner.test_start_event _______________________ self = def test_start_event(self): """ Tests that test_start event is fired """ class TestUser(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[TestUser]) run_count = [0] @self.environment.events.test_start.add_listener def on_test_start(*a, **kw): run_count[0] += 1 for i in range(5): server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i)) master.start(7, 7) > self.assertEqual(10, len(server.outbox)) E AssertionError: 10 != 0 locust/test/test_runners.py:2511: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client0). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client4). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected _______________________ TestMasterRunner.test_stop_event _______________________ self = def test_stop_event(self): """ Tests that test_stop event is fired """ class TestUser(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[TestUser]) @self.environment.events.test_stopping.add_listener def on_test_stopping(*_, **__): self.runner_stopping = True @self.environment.events.test_stop.add_listener def on_test_stop(*_, **__): self.runner_stopped = True for i in range(5): server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i)) master.start(7, 7) > self.assertEqual(10, len(server.outbox)) E AssertionError: 10 != 0 locust/test/test_runners.py:2550: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client0). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client4). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected ____________________ TestMasterRunner.test_stop_event_quit _____________________ self = def test_stop_event_quit(self): """ Tests that test_stop event is fired when quit() is called directly """ class TestUser(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[TestUser]) @self.environment.events.test_stopping.add_listener def on_test_stopping(*_, **__): self.runner_stopping = True @self.environment.events.test_stop.add_listener def on_test_stop(*_, **__): self.runner_stopped = True for i in range(5): server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i)) master.start(7, 7) > self.assertEqual(10, len(server.outbox)) E AssertionError: 10 != 0 locust/test/test_runners.py:2589: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client0). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client4). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected _____________________ TestMasterRunner.test_worker_connect _____________________ self = def test_worker_connect(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", __version__, "zeh_fake_client1")) > self.assertEqual(1, len(master.clients)) E AssertionError: 1 != 0 locust/test/test_runners.py:2014: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (zeh_fake_client1). That's not going to work. __________ TestMasterRunner.test_worker_connect_with_special_versions __________ self = def test_worker_connect_with_special_versions(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", None, "1.x_style_client_should_not_be_allowed")) self.assertEqual(1, len(self.mocked_log.error)) self.assertEqual(0, len(master.clients)) server.mocked_send(Message("client_ready", "abcd", "other_version_mismatch_should_just_give_a_warning")) self.assertEqual(1, len(self.mocked_log.warning)) self.assertEqual(1, len(master.clients)) server.mocked_send(Message("client_ready", -1, "version_check_bypass_should_not_warn")) self.assertEqual(1, len(self.mocked_log.warning)) self.assertEqual(2, len(master.clients)) server.mocked_send( Message("client_ready", __version__ + "1", "difference_in_patch_version_should_not_warn") ) self.assertEqual(3, len(master.clients)) > self.assertEqual(1, len(self.mocked_log.warning)) E AssertionError: 1 != 2 locust/test/test_runners.py:2042: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (1.x_style_client_should_not_be_allowed). That's not going to work. WARNING locust.runners:runners.py:1030 A worker (other_version_mismatch_should_just_give_a_warning) running a different version (abcd) connected, master version is INFO locust.runners:runners.py:1041 Worker other_version_mismatch_should_just_give_a_warning (index 0) reported as ready. 1 workers connected. INFO locust.runners:runners.py:1041 Worker version_check_bypass_should_not_warn (index 1) reported as ready. 2 workers connected. WARNING locust.runners:runners.py:1030 A worker (difference_in_patch_version_should_not_warn) running a different version (1) connected, master version is INFO locust.runners:runners.py:1041 Worker difference_in_patch_version_should_not_warn (index 2) reported as ready. 3 workers connected. ______ TestMasterRunner.test_worker_missing_after_heartbeat_dead_interval ______ self = @mock.patch("locust.runners.HEARTBEAT_INTERVAL", new=0.1) @mock.patch("locust.runners.HEARTBEAT_DEAD_INTERNAL", new=-3) def test_worker_missing_after_heartbeat_dead_interval(self): class TestUser(User): @task def my_task(self): gevent.sleep(600) with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server, patch_env( "LOCUST_WAIT_FOR_WORKERS_REPORT_AFTER_RAMP_UP", "0.1" ): master = self.get_runner(user_classes=[TestUser]) server.mocked_send(Message("client_ready", __version__, "fake_client1")) server.mocked_send(Message("client_ready", __version__, "fake_client2")) server.mocked_send(Message("client_ready", __version__, "fake_client3")) master.start(3, 3) server.mocked_send(Message("spawning", None, "fake_client1")) server.mocked_send(Message("spawning", None, "fake_client2")) server.mocked_send(Message("spawning", None, "fake_client3")) sleep(0.1) server.mocked_send( Message( "heartbeat", {"state": STATE_RUNNING, "current_cpu_usage": 50, "current_memory_usage": 200, "count": 1}, "fake_client1", ) ) server.mocked_send( Message( "heartbeat", {"state": STATE_RUNNING, "current_cpu_usage": 50, "current_memory_usage": 200, "count": 1}, "fake_client2", ) ) server.mocked_send( Message( "heartbeat", {"state": STATE_RUNNING, "current_cpu_usage": 50, "current_memory_usage": 200, "count": 1}, "fake_client3", ) ) sleep(0.1) # initially all workers are in active state self.assertEqual(0, len(master.clients.missing)) > self.assertEqual(3, master.worker_count) E AssertionError: 3 != 0 locust/test/test_runners.py:2239: AssertionError ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "/build/locust-2.12.1/locust/runners.py", line 1088, in client_listener self.clients[msg.node_id].state = STATE_SPAWNING ~~~~~~~~~~~~^^^^^^^^^^^^^ File "/build/locust-2.12.1/locust/runners.py", line 644, in __getitem__ return self._worker_nodes[k] ~~~~~~~~~~~~~~~~~~^^^ KeyError: 'fake_client1' 2024-05-24T11:56:16Z >> failed with KeyError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client1). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client2). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (fake_client3). That's not going to work. WARNING locust.runners:runners.py:751 You can't start a distributed test before at least one worker processes has connected CRITICAL locust.runners:log.py:74 Unhandled exception in greenlet: >> Traceback (most recent call last): File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "/build/locust-2.12.1/locust/runners.py", line 1088, in client_listener self.clients[msg.node_id].state = STATE_SPAWNING ^^^^^^^^^^^^^^^^^ File "/build/locust-2.12.1/locust/runners.py", line 644, in __getitem__ return self._worker_nodes[k] ^^^^^^^^^^^^^^^^^ KeyError: 'fake_client1' ___________ TestMasterRunner.test_worker_sends_bad_message_to_master ___________ self = def test_worker_sends_bad_message_to_master(self): """ Validate master sends reconnect message to worker when it receives a bad message. """ class TestUser(User): @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner(user_classes=[TestUser]) server.mocked_send(Message("client_ready", __version__, "zeh_fake_client1")) > self.assertEqual(1, len(master.clients)) E AssertionError: 1 != 0 locust/test/test_runners.py:3036: AssertionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (zeh_fake_client1). That's not going to work. _____________ TestStopTimeout.test_kill_locusts_with_stop_timeout ______________ self = def test_kill_locusts_with_stop_timeout(self): short_time = 0.05 class MyTaskSet(TaskSet): @task def my_task(self): MyTaskSet.state = "first" gevent.sleep(short_time) MyTaskSet.state = "second" # should only run when run time + stop_timeout is > short_time gevent.sleep(short_time) MyTaskSet.state = "third" # should only run when run time + stop_timeout is > short_time * 2 class MyTestUser(User): tasks = [MyTaskSet] environment = create_environment([MyTestUser], mocked_options()) runner = environment.create_local_runner() runner.start(1, 1) gevent.sleep(short_time / 2) runner.stop_users({MyTestUser.__name__: 1}) > self.assertEqual("first", MyTaskSet.state) E AssertionError: 'first' != 'second' E - first E + second locust/test/test_runners.py:3930: AssertionError ------------------------------ Captured log call ------------------------------- INFO locust.runners:runners.py:507 Ramping to 1 users at a rate of 1.00 per second INFO locust.runners:runners.py:545 All users spawned: {"MyTestUser": 1} (1 total users) INFO locust.runners:runners.py:159 Resetting stats ______________________ TestStopTimeout.test_stop_timeout _______________________ self = def test_stop_timeout(self): short_time = 0.05 class MyTaskSet(TaskSet): @task def my_task(self): MyTaskSet.state = "first" gevent.sleep(short_time) MyTaskSet.state = "second" # should only run when run time + stop_timeout is > short_time gevent.sleep(short_time) MyTaskSet.state = "third" # should only run when run time + stop_timeout is > short_time * 2 class MyTestUser(User): tasks = [MyTaskSet] environment = Environment(user_classes=[MyTestUser]) runner = environment.create_local_runner() runner.start(1, 1, wait=False) gevent.sleep(short_time / 2) runner.quit() > self.assertEqual("first", MyTaskSet.state) E AssertionError: 'first' != 'second' E - first E + second locust/test/test_runners.py:3770: AssertionError ------------------------------ Captured log call ------------------------------- INFO locust.runners:runners.py:507 Ramping to 1 users at a rate of 1.00 per second INFO locust.runners:runners.py:545 All users spawned: {"MyTestUser": 1} (1 total users) _______________ TestStopTimeout.test_stop_timeout_with_ramp_down _______________ self = def test_stop_timeout_with_ramp_down(self): class MyTaskSet(TaskSet): @task def my_task(self): gevent.sleep(1) class MyTestUser(User): tasks = [MyTaskSet] environment = Environment(user_classes=[MyTestUser], stop_timeout=2) runner = environment.create_local_runner() # Start load test, wait for users to start, then trigger ramp down ts = time.perf_counter() runner.start(10, 10, wait=False) runner.spawning_greenlet.join() delta = time.perf_counter() - ts self.assertTrue( 0 <= delta <= 0.05, f"Expected user count to increase to 10 instantaneously, instead it took {delta:f}" ) self.assertTrue( runner.user_count == 10, "User count has not decreased correctly to 2, it is : %i" % runner.user_count ) ts = time.perf_counter() runner.start(2, 4, wait=False) runner.spawning_greenlet.join() delta = time.perf_counter() - ts > self.assertTrue(2 <= delta <= 2.05, f"Expected user count to decrease to 2 in 2s, instead it took {delta:f}") E AssertionError: False is not true : Expected user count to decrease to 2 in 2s, instead it took 2.082472 locust/test/test_runners.py:4033: AssertionError ------------------------------ Captured log call ------------------------------- INFO locust.runners:runners.py:507 Ramping to 10 users at a rate of 10.00 per second INFO locust.runners:runners.py:545 All users spawned: {"MyTestUser": 10} (10 total users) INFO locust.runners:runners.py:507 Ramping to 2 users at a rate of 4.00 per second INFO locust.runners:runners.py:545 All users spawned: {"MyTestUser": 2} (2 total users) _______________ TestCsvStats.test_csv_stats_writer_full_history ________________ self = @mock.patch("locust.stats.CSV_STATS_INTERVAL_SEC", new=_TEST_CSV_STATS_INTERVAL_SEC) def test_csv_stats_writer_full_history(self): stats_writer = StatsCSVFileWriter( self.environment, PERCENTILES_TO_REPORT, self.STATS_BASE_NAME, full_history=True ) for i in range(10): self.runner.stats.log_request("GET", "/", 100, content_length=666) greenlet = gevent.spawn(stats_writer) gevent.sleep(10) for i in range(10): self.runner.stats.log_request("GET", "/", 10, content_length=666) gevent.sleep(5) gevent.sleep(_TEST_CSV_STATS_INTERVAL_WAIT_SEC) gevent.kill(greenlet) stats_writer.close_files() self.assertTrue(os.path.exists(self.STATS_FILENAME)) self.assertTrue(os.path.exists(self.STATS_HISTORY_FILENAME)) self.assertTrue(os.path.exists(self.STATS_FAILURES_FILENAME)) self.assertTrue(os.path.exists(self.STATS_EXCEPTIONS_FILENAME)) with open(self.STATS_HISTORY_FILENAME) as f: reader = csv.DictReader(f) rows = [r for r in reader] > self.assertGreaterEqual(len(rows), 130) E AssertionError: 126 not greater than or equal to 130 locust/test/test_stats.py:461: AssertionError _______________________ TestCsvStats.test_stats_history ________________________ self = def test_stats_history(self): env1 = Environment(events=locust.events, catch_exceptions=False) runner1 = env1.create_master_runner("127.0.0.1", 5558) env2 = Environment(events=locust.events, catch_exceptions=False) > runner2 = env2.create_worker_runner("127.0.0.1", 5558) locust/test/test_stats.py:591: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ locust/env.py:148: in create_worker_runner return self._create_runner( locust/env.py:110: in _create_runner self.runner = runner_class(self, *args, **kwargs) locust/runners.py:1183: in __init__ self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() locust/runners.py:1397: in connect_to_master self.connect_to_master() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def connect_to_master(self): self.retry += 1 self.client.send(Message("client_ready", __version__, self.client_id)) success = self.connection_event.wait(timeout=CONNECT_TIMEOUT) if not success: if self.retry < 3: logger.debug( f"Failed to connect to master {self.master_host}:{self.master_port}, retry {self.retry}/{CONNECT_RETRY_COUNT}." ) else: logger.warning( f"Failed to connect to master {self.master_host}:{self.master_port}, retry {self.retry}/{CONNECT_RETRY_COUNT}." ) if self.retry > CONNECT_RETRY_COUNT: > raise ConnectionError() E ConnectionError locust/runners.py:1396: ConnectionError ------------------------------ Captured log call ------------------------------- ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 3/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 4/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 5/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 6/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 7/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 8/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 9/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 10/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 11/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 12/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 13/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 14/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 15/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 16/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 17/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 18/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 19/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 20/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 21/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 22/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 23/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 24/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 25/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING root:runners.py:324 CPU usage above 90%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 26/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 27/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 28/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 29/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 30/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 31/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 32/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 33/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 34/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 35/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 36/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 37/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 38/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 39/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 40/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 41/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 42/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 43/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 44/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 45/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 46/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 47/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 48/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 49/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 50/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 51/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 52/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 53/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 54/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 55/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 56/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 57/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 58/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 59/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 60/60. ERROR locust.runners:runners.py:1022 An old (pre 2.0) worker tried to connect (ionos15-amd64_1f072316f927448e954329c59323de95). That's not going to work. WARNING locust.runners:runners.py:1392 Failed to connect to master 127.0.0.1:5558, retry 61/60. ______________ TestCsvStats.test_user_count_in_csv_history_stats _______________ self = @mock.patch("locust.stats.CSV_STATS_INTERVAL_SEC", new=_TEST_CSV_STATS_INTERVAL_SEC) def test_user_count_in_csv_history_stats(self): start_time = int(time.time()) class TestUser(User): wait_time = constant(10) @task def t(self): self.environment.runner.stats.log_request("GET", "/", 10, 10) environment = Environment(user_classes=[TestUser]) stats_writer = StatsCSVFileWriter(environment, PERCENTILES_TO_REPORT, self.STATS_BASE_NAME, full_history=True) runner = environment.create_local_runner() # spawn a user every _TEST_CSV_STATS_INTERVAL_SEC second user_count = 15 spawn_rate = 5 assert 1 / 5 == _TEST_CSV_STATS_INTERVAL_SEC runner_greenlet = gevent.spawn(runner.start, user_count, spawn_rate) gevent.sleep(0.1) greenlet = gevent.spawn(stats_writer) gevent.sleep(user_count / spawn_rate) gevent.kill(greenlet) stats_writer.close_files() runner.stop() gevent.kill(runner_greenlet) with open(self.STATS_HISTORY_FILENAME) as f: reader = csv.DictReader(f) rows = [r for r in reader] > self.assertEqual(2 * user_count, len(rows)) E AssertionError: 30 != 26 locust/test/test_stats.py:547: AssertionError ------------------------------ Captured log call ------------------------------- INFO locust.runners:runners.py:507 Ramping to 15 users at a rate of 5.00 per second INFO locust.runners:runners.py:545 All users spawned: {"TestUser": 15} (15 total users) =============================== warnings summary =============================== locust/test/test_fasthttp.py::TestFastHttpSsl::test_ssl_request_insecure locust/test/test_web.py::TestWebUIWithTLS::test_index_with_https /usr/lib/python3/dist-packages/gevent/_ssl3.py:231: DeprecationWarning: ssl.PROTOCOL_TLS is deprecated self._context = SSLContext(ssl_version) locust/test/test_load_locustfile.py::TestLoadLocustfile::test_load_locust_file_from_absolute_path locust/test/test_load_locustfile.py::TestLoadLocustfile::test_load_locust_file_from_relative_path locust/test/test_load_locustfile.py::TestLoadLocustfile::test_load_locust_file_with_a_dot_in_filename locust/test/test_load_locustfile.py::TestLoadLocustfile::test_return_docstring_and_user_classes locust/test/test_load_locustfile.py::TestLoadLocustfile::test_with_shape_class :283: DeprecationWarning: the load_module() method is deprecated and slated for removal in Python 3.12; use exec_module() instead -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED locust/test/test_dispatch.py::TestLargeScale::test_distribute_users - ... FAILED locust/test/test_dispatch.py::TestLargeScale::test_ramp_up_from_0_to_100_000_users_with_50_user_classes_and_1000_workers_and_5000_spawn_rate FAILED locust/test/test_fasthttp.py::TestFastHttpUserClass::test_client_pool_concurrency FAILED locust/test/test_log.py::TestLoggingOptions::test_log_to_file - OSErro... FAILED locust/test/test_log.py::TestLoggingOptions::test_logging_output - OSE... FAILED locust/test/test_log.py::TestLoggingOptions::test_skip_logging - OSErr... FAILED locust/test/test_main.py::ProcessIntegrationTest::test_help_arg - OSEr... FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_autostart_mutliple_locustfiles_with_shape FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_autostart_w_load_shape FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_autostart_w_run_time FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_autostart_wo_run_time FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_command_line_user_selection FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_custom_arguments FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_custom_arguments_in_file FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_custom_exit_code FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_default_headless_spawn_options FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_default_headless_spawn_options_with_shape FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_error_when_duplicate_shape_class_names FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_error_when_duplicate_userclass_names FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_error_when_locustfiles_directory_is_empty FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_error_when_no_tasks_match_tags FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_headless_spawn_options_wo_run_time FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_help_arg - ... FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_html_report_option FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_input - Ass... FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_no_error_when_same_userclass_in_two_files FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_run_autostart_with_multiple_locustfiles FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_run_headless_with_multiple_locustfiles FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_run_headless_with_multiple_locustfiles_with_shape FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_run_with_userclass_picker FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_spawing_with_fixed_multiple_locustfiles FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_spawning_with_fixed FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_web_options FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_webserver FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_webserver_multiple_locustfiles FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_webserver_multiple_locustfiles_in_directory FAILED locust/test/test_main.py::StandaloneIntegrationTests::test_webserver_multiple_locustfiles_with_shape FAILED locust/test/test_main.py::DistributedIntegrationTests::test_distributed FAILED locust/test/test_main.py::DistributedIntegrationTests::test_distributed_events FAILED locust/test/test_main.py::DistributedIntegrationTests::test_distributed_report_timeout_expired FAILED locust/test/test_main.py::DistributedIntegrationTests::test_distributed_tags FAILED locust/test/test_main.py::DistributedIntegrationTests::test_expect_workers FAILED locust/test/test_main.py::DistributedIntegrationTests::test_help_arg FAILED locust/test/test_main.py::DistributedIntegrationTests::test_worker_indexes FAILED locust/test/test_runners.py::TestLocustRunner::test_cpu_warning - Asse... FAILED locust/test/test_runners.py::TestLocustRunner::test_stop_users_with_spawn_rate FAILED locust/test/test_runners.py::TestMasterRunner::test_attributes_populated_when_calling_start FAILED locust/test/test_runners.py::TestMasterRunner::test_custom_shape_scale_down FAILED locust/test/test_runners.py::TestMasterRunner::test_custom_shape_scale_up FAILED locust/test/test_runners.py::TestMasterRunner::test_last_worker_missing_stops_test FAILED locust/test/test_runners.py::TestMasterRunner::test_last_worker_quitting_stops_test FAILED locust/test/test_runners.py::TestMasterRunner::test_master_discard_first_client_ready FAILED locust/test/test_runners.py::TestMasterRunner::test_master_marks_downed_workers_as_missing FAILED locust/test/test_runners.py::TestMasterRunner::test_master_reset_connection FAILED locust/test/test_runners.py::TestMasterRunner::test_rebalance_locust_users_on_worker_connect FAILED locust/test/test_runners.py::TestMasterRunner::test_reset_connection_after_RPCError FAILED locust/test/test_runners.py::TestMasterRunner::test_spawn_correct_worker_indexes FAILED locust/test/test_runners.py::TestMasterRunner::test_spawn_fewer_locusts_than_workers FAILED locust/test/test_runners.py::TestMasterRunner::test_spawn_uneven_locusts FAILED locust/test/test_runners.py::TestMasterRunner::test_start_event - Asse... FAILED locust/test/test_runners.py::TestMasterRunner::test_stop_event - Asser... FAILED locust/test/test_runners.py::TestMasterRunner::test_stop_event_quit - ... FAILED locust/test/test_runners.py::TestMasterRunner::test_worker_connect - A... FAILED locust/test/test_runners.py::TestMasterRunner::test_worker_connect_with_special_versions FAILED locust/test/test_runners.py::TestMasterRunner::test_worker_missing_after_heartbeat_dead_interval FAILED locust/test/test_runners.py::TestMasterRunner::test_worker_sends_bad_message_to_master FAILED locust/test/test_runners.py::TestStopTimeout::test_kill_locusts_with_stop_timeout FAILED locust/test/test_runners.py::TestStopTimeout::test_stop_timeout - Asse... FAILED locust/test/test_runners.py::TestStopTimeout::test_stop_timeout_with_ramp_down FAILED locust/test/test_stats.py::TestCsvStats::test_csv_stats_writer_full_history FAILED locust/test/test_stats.py::TestCsvStats::test_stats_history - Connecti... FAILED locust/test/test_stats.py::TestCsvStats::test_user_count_in_csv_history_stats ==== 72 failed, 430 passed, 15 deselected, 7 warnings in 710.42s (0:11:50) ===== E: pybuild pybuild:388: test: plugin custom failed with: exit code=1: PYTHONPATH=/build/locust-2.12.1/.pybuild/cpython3_3.11_locust/build python3.11 -m pytest -v --ignore=examples/test_data_management.py -k 'not TestMasterWorkerRunners' dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p 3.11 returned exit code 13 make[1]: [debian/rules:15: override_dh_auto_test] Error 25 (ignored) make[1]: Leaving directory '/build/locust-2.12.1' create-stamp debian/debhelper-build-stamp fakeroot debian/rules binary dh binary --with python3 --buildsystem=pybuild dh_testroot -O--buildsystem=pybuild dh_prep -O--buildsystem=pybuild dh_auto_install --destdir=debian/python3-locust/ -O--buildsystem=pybuild I: pybuild plugin_pyproject:161: Copying package built for python3.11 to destdir dh_installdocs -O--buildsystem=pybuild dh_installchangelogs -O--buildsystem=pybuild debian/rules override_dh_installexamples make[1]: Entering directory '/build/locust-2.12.1' dh_installexamples -X.pyc make[1]: Leaving directory '/build/locust-2.12.1' dh_python3 -O--buildsystem=pybuild dh_installsystemduser -O--buildsystem=pybuild dh_perl -O--buildsystem=pybuild dh_link -O--buildsystem=pybuild dh_strip_nondeterminism -O--buildsystem=pybuild dh_compress -O--buildsystem=pybuild dh_fixperms -O--buildsystem=pybuild dh_missing -O--buildsystem=pybuild dh_installdeb -O--buildsystem=pybuild dh_gencontrol -O--buildsystem=pybuild dpkg-gencontrol: warning: Recommends field of package python3-locust: substitution variable ${python3:Recommends} used, but is not defined dpkg-gencontrol: warning: Suggests field of package python3-locust: substitution variable ${python3:Suggests} used, but is not defined dh_md5sums -O--buildsystem=pybuild dh_builddeb -O--buildsystem=pybuild dpkg-deb: building package 'python3-locust' in '../python3-locust_2.12.1-1_all.deb'. dpkg-genbuildinfo --build=binary -O../locust_2.12.1-1_amd64.buildinfo dpkg-genchanges --build=binary -O../locust_2.12.1-1_amd64.changes dpkg-genchanges: info: binary-only upload (no source code included) dpkg-source --after-build . dpkg-source: info: using options from locust-2.12.1/debian/source/options: --extend-diff-ignore=^[^/]+.egg-info/ dpkg-buildpackage: info: binary-only upload (no source included) dpkg-genchanges: info: including full source code in upload I: copying local configuration 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/178780 and its subdirectories I: Current time: Fri May 24 00:03:52 -12 2024 I: pbuilder-time-stamp: 1716552232