Hello community, here is the log from the commit of package python-testinfra for openSUSE:Factory checked in at 2020-03-11 18:54:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-testinfra (Old) and /work/SRC/openSUSE:Factory/.python-testinfra.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-testinfra" Wed Mar 11 18:54:34 2020 rev:13 rq:783800 version:5.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-testinfra/python-testinfra.changes 2020-02-07 15:54:19.979508200 +0100 +++ /work/SRC/openSUSE:Factory/.python-testinfra.new.3160/python-testinfra.changes 2020-03-11 18:56:14.679698981 +0100 @@ -1,0 +2,12 @@ +Wed Mar 11 11:31:39 UTC 2020 - pgaj...@suse.com + +- version update to 5.0.0 + 5.0.0 + ===== + * Breaking change: host.file().listdir() is now a method + 4.1.0 + ===== + * Pass extra arguments to ansible CLI via host.ansible() + * New method host.file.listdir() to list items in a directory. + +------------------------------------------------------------------- Old: ---- testinfra-4.0.0.tar.gz New: ---- testinfra-5.0.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-testinfra.spec ++++++ --- /var/tmp/diff_new_pack.FYy1t5/_old 2020-03-11 18:56:15.483699340 +0100 +++ /var/tmp/diff_new_pack.FYy1t5/_new 2020-03-11 18:56:15.487699342 +0100 @@ -19,7 +19,7 @@ %define skip_python2 1 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-testinfra -Version: 4.0.0 +Version: 5.0.0 Release: 0 Summary: Python module to test infrastructures License: Apache-2.0 ++++++ testinfra-4.0.0.tar.gz -> testinfra-5.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/CHANGELOG.rst new/testinfra-5.0.0/CHANGELOG.rst --- old/testinfra-4.0.0/CHANGELOG.rst 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/CHANGELOG.rst 2020-03-05 19:42:34.000000000 +0100 @@ -2,6 +2,17 @@ Changelog ========= +5.0.0 +===== + +* Breaking change: host.file().listdir() is now a method + +4.1.0 +===== + +* Pass extra arguments to ansible CLI via host.ansible() +* New method host.file.listdir() to list items in a directory. + 4.0.0 ===== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/PKG-INFO new/testinfra-5.0.0/PKG-INFO --- old/testinfra-4.0.0/PKG-INFO 2020-01-05 16:29:48.000000000 +0100 +++ new/testinfra-5.0.0/PKG-INFO 2020-03-05 19:42:51.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: testinfra -Version: 4.0.0 +Version: 5.0.0 Summary: Test infrastructures Home-page: https://github.com/philpep/testinfra Author: Philippe Pepiot diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/images/alpine/Dockerfile new/testinfra-5.0.0/images/alpine/Dockerfile --- old/testinfra-4.0.0/images/alpine/Dockerfile 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/images/alpine/Dockerfile 2020-03-05 19:42:34.000000000 +0100 @@ -1,4 +1,4 @@ -FROM alpine:3.9 +FROM alpine:3.11 RUN apk add --update --no-cache python openrc openssh && \ sed -i "s/^#PermitRootLogin prohibit-password/PermitRootLogin without-password/g" /etc/ssh/sshd_config && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/images/debian_buster/Dockerfile new/testinfra-5.0.0/images/debian_buster/Dockerfile --- old/testinfra-4.0.0/images/debian_buster/Dockerfile 1970-01-01 01:00:00.000000000 +0100 +++ new/testinfra-5.0.0/images/debian_buster/Dockerfile 2020-03-05 19:42:34.000000000 +0100 @@ -0,0 +1,75 @@ +FROM debian:buster + +ENV container docker + +# ntpd is linked to /bin/false, so the service is not running but is enabled +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ + lsb-release \ + python \ + openssh-server \ + puppet \ + salt-minion \ + locales \ + ntp \ + sudo \ + supervisor \ + systemd-sysv \ + python-pip \ + python-virtualenv \ + iptables \ + iptables-persistent && \ + rm -rf /var/lib/apt/lists/* +RUN mkdir -p /var/run/sshd && \ + (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do if ! test $i = systemd-tmpfiles-setup.service; then rm -f $i; fi; done) && \ + rm -f /lib/systemd/system/multi-user.target.wants/* && \ + rm -f /etc/systemd/system/*.wants/* && \ + rm -f /lib/systemd/system/local-fs.target.wants/* && \ + rm -f /lib/systemd/system/sockets.target.wants/*udev* && \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl* && \ + systemctl enable ssh.service && \ + systemctl disable salt-minion.service && \ + systemctl enable ntp.service && \ + systemctl enable supervisor.service && \ + systemctl enable netfilter-persistent.service && \ + ln -fsn /bin/false /usr/sbin/ntpd && \ + echo "python hold" | dpkg --set-selections && \ + echo "LANG=fr_FR.ISO-8859-15" > /etc/default/locale && \ + echo "LANGUAGE=fr_FR" >> /etc/default/locale && \ + echo "fr_FR.ISO-8859-15 ISO-8859-15" >> /etc/locale.gen && \ + locale-gen && \ + update-locale && \ + useradd -m user -c "gecos.comment" && \ + adduser user sudo && \ + echo "user ALL=NOPASSWD: ALL" > /etc/sudoers.d/user && \ + useradd -m unprivileged && \ + mkdir -p /root/.ssh && \ + echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCgDryK4AjJeifuc2N54St13KMNlnGLAtibQSMmvSyrhH7XJ1atnBo1HrJhGZNNBVKM67+zYNc9J3fg3qI1g63vSQAA+nXMsDYwu4BPwupakpwJELcGZJxsUGzjGVotVpqPIX5nW8NBGvkVuObI4UELOleq5mQMTGerJO64KkSVi20FDwPJn3q8GG2zk3pESiDA5ShEyFhYC8vOLfSSYD0LYmShAVGCLEgiNb+OXQL6ZRvzqfFEzL0QvaI/l3mb6b0VFPAO4QWOL0xj3cWzOZXOqht3V85CZvSk8ISdNgwCjXLZsPeaYL/toHNvBF30VMrDZ7w4SDU0ZZLEsc/ezxjb" > /root/.ssh/authorized_keys && \ + mkdir -p /home/user/.ssh && \ + cp /root/.ssh/authorized_keys /home/user/.ssh/authorized_keys && \ + chown -R user:user /home/user/.ssh && \ + echo "[program:tail]\ncommand=tail -f /dev/null\nuser=user\ngroup=user\n" > /etc/supervisor/conf.d/tail.conf + +RUN echo "root:foo" | chpasswd + +# Enable ssh login for user and fix side effect on environment variables... +RUN sed -ri 's/^UsePAM yes$/UsePAM no/' /etc/ssh/sshd_config +RUN sed -ri 's/AcceptEnv LANG LC_*/#AcceptEnv LANG LC_*/' /etc/ssh/sshd_config +RUN echo "PermitUserEnvironment yes" >> /etc/ssh/sshd_config +RUN echo "LANG=fr_FR.ISO-8859-15" >> /root/.ssh/environment +RUN echo "user:foo" | chpasswd + +# Iptables rules +RUN echo "*nat\n:PREROUTING ACCEPT [0:0]\n:INPUT ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n:POSTROUTING ACCEPT [0:0]\n-A PREROUTING -d 192.168.0.1/32 -j REDIRECT\nCOMMIT\n*filter\n:INPUT ACCEPT [0:0]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT\nCOMMIT" > /etc/iptables/rules.v4 + +# Expiration date for user "user" +RUN chage -E 20000 user + +# Some python virtualenv +RUN python -m virtualenv /v && /v/bin/pip install 'pytest>2,<3' + +ENV LANG fr_FR.ISO-8859-15 +ENV LANGUAGE fr_FR + +EXPOSE 22 +CMD ["/sbin/init"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/images/debian_stretch/Dockerfile new/testinfra-5.0.0/images/debian_stretch/Dockerfile --- old/testinfra-4.0.0/images/debian_stretch/Dockerfile 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/images/debian_stretch/Dockerfile 1970-01-01 01:00:00.000000000 +0100 @@ -1,74 +0,0 @@ -FROM debian:stretch - -ENV container docker - -# ntpd is linked to /bin/false, so the service is not running but is enabled -RUN apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ - lsb-release \ - python \ - openssh-server \ - puppet \ - salt-minion \ - locales \ - ntp \ - sudo \ - supervisor \ - systemd-sysv \ - python-pip \ - python-virtualenv \ - iptables \ - iptables-persistent && \ - rm -rf /var/lib/apt/lists/* -RUN mkdir -p /var/run/sshd && \ - (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do if ! test $i = systemd-tmpfiles-setup.service; then rm -f $i; fi; done) && \ - rm -f /lib/systemd/system/multi-user.target.wants/* && \ - rm -f /etc/systemd/system/*.wants/* && \ - rm -f /lib/systemd/system/local-fs.target.wants/* && \ - rm -f /lib/systemd/system/sockets.target.wants/*udev* && \ - rm -f /lib/systemd/system/sockets.target.wants/*initctl* && \ - systemctl enable ssh.service && \ - systemctl disable salt-minion.service && \ - systemctl enable ntp.service && \ - systemctl enable supervisor.service && \ - systemctl enable netfilter-persistent.service && \ - ln -fsn /bin/false /usr/sbin/ntpd && \ - echo "python hold" | dpkg --set-selections && \ - echo "LANG=fr_FR.ISO-8859-15" > /etc/default/locale && \ - echo "LANGUAGE=fr_FR" >> /etc/default/locale && \ - echo "fr_FR.ISO-8859-15 ISO-8859-15" >> /etc/locale.gen && \ - locale-gen && \ - update-locale && \ - useradd -m user -c "gecos.comment" && \ - adduser user sudo && \ - echo "user ALL=NOPASSWD: ALL" > /etc/sudoers.d/user && \ - useradd -m unprivileged && \ - mkdir -p /root/.ssh && \ - echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCgDryK4AjJeifuc2N54St13KMNlnGLAtibQSMmvSyrhH7XJ1atnBo1HrJhGZNNBVKM67+zYNc9J3fg3qI1g63vSQAA+nXMsDYwu4BPwupakpwJELcGZJxsUGzjGVotVpqPIX5nW8NBGvkVuObI4UELOleq5mQMTGerJO64KkSVi20FDwPJn3q8GG2zk3pESiDA5ShEyFhYC8vOLfSSYD0LYmShAVGCLEgiNb+OXQL6ZRvzqfFEzL0QvaI/l3mb6b0VFPAO4QWOL0xj3cWzOZXOqht3V85CZvSk8ISdNgwCjXLZsPeaYL/toHNvBF30VMrDZ7w4SDU0ZZLEsc/ezxjb" > /root/.ssh/authorized_keys && \ - mkdir -p /home/user/.ssh && \ - cp /root/.ssh/authorized_keys /home/user/.ssh/authorized_keys && \ - chown -R user:user /home/user/.ssh && \ - echo "[program:tail]\ncommand=tail -f /dev/null\nuser=user\ngroup=user\n" > /etc/supervisor/conf.d/tail.conf - -RUN echo "root:foo" | chpasswd - -# Enable ssh login for user and fix side effect on environment variables... -RUN sed -ri 's/^UsePAM yes$/UsePAM no/' /etc/ssh/sshd_config -RUN echo "PermitUserEnvironment yes" >> /etc/ssh/sshd_config -RUN echo "LANG=fr_FR.ISO-8859-15" >> /root/.ssh/environment -RUN echo "user:foo" | chpasswd - -# Iptables rules -RUN echo "*nat\n:PREROUTING ACCEPT [0:0]\n:INPUT ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n:POSTROUTING ACCEPT [0:0]\n-A PREROUTING -d 192.168.0.1/32 -j REDIRECT\nCOMMIT\n*filter\n:INPUT ACCEPT [0:0]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT\nCOMMIT" > /etc/iptables/rules.v4 - -# Expiration date for user "user" -RUN chage -E 20000 user - -# Some python virtualenv -RUN python -m virtualenv /v && /v/bin/pip install 'pytest>2,<3' - -ENV LANG fr_FR.ISO-8859-15 -ENV LANGUAGE fr_FR - -EXPOSE 22 -CMD ["/sbin/init"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/pylintrc new/testinfra-5.0.0/pylintrc --- old/testinfra-4.0.0/pylintrc 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/pylintrc 2020-03-05 19:42:34.000000000 +0100 @@ -16,6 +16,7 @@ max-branches=20 max-bool-expr=6 max-args=8 +max-public-methods=30 # we have flake8 for that max-line-length=1000 generated-members=check_output,run_test,run_expect,run,find_command diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/setup.cfg new/testinfra-5.0.0/setup.cfg --- old/testinfra-4.0.0/setup.cfg 2020-01-05 16:29:48.000000000 +0100 +++ new/testinfra-5.0.0/setup.cfg 2020-03-05 19:42:51.000000000 +0100 @@ -1,6 +1,3 @@ -[bdist_wheel] -universal = 1 - [tool:pytest] norecursedirs = .tox .git .local *.egg build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/test/conftest.py new/testinfra-5.0.0/test/conftest.py --- old/testinfra-4.0.0/test/conftest.py 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/test/conftest.py 2020-03-05 19:42:34.000000000 +0100 @@ -60,7 +60,7 @@ "archlinux", "centos_6", "centos_7", - "debian_stretch", + "debian_buster", "ubuntu_xenial", ] @@ -223,7 +223,7 @@ break else: # Default - hosts = ["docker://debian_stretch"] + hosts = ["docker://debian_buster"] metafunc.parametrize("host", hosts, indirect=True, scope="function") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/test/test_backends.py new/testinfra-5.0.0/test/test_backends.py --- old/testinfra-4.0.0/test/test_backends.py 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/test/test_backends.py 2020-03-05 19:42:34.000000000 +0100 @@ -23,36 +23,36 @@ from testinfra.backend.winrm import _quote from testinfra.utils.ansible_runner import AnsibleRunner HOSTS = [ - "ssh://debian_stretch", - "safe-ssh://debian_stretch", - "docker://debian_stretch", - "paramiko://debian_stretch", - "ansible://debian_stretch", - "ansible://debian_stretch?force_ansible=True", + "ssh://debian_buster", + "safe-ssh://debian_buster", + "docker://debian_buster", + "paramiko://debian_buster", + "ansible://debian_buster", + "ansible://debian_buster?force_ansible=True", ] USER_HOSTS = [ - "ssh://user@debian_stretch", - "safe-ssh://user@debian_stretch", - "docker://user@debian_stretch", - "paramiko://user@debian_stretch", - "ansible://user@debian_stretch", - "ansible://user@debian_stretch?force_ansible=True", + "ssh://user@debian_buster", + "safe-ssh://user@debian_buster", + "docker://user@debian_buster", + "paramiko://user@debian_buster", + "ansible://user@debian_buster", + "ansible://user@debian_buster?force_ansible=True", ] SUDO_HOSTS = [ - "ssh://user@debian_stretch?sudo=True", - "safe-ssh://user@debian_stretch?sudo=True", - "docker://user@debian_stretch?sudo=True", - "paramiko://user@debian_stretch?sudo=True", - "ansible://user@debian_stretch?sudo=True", - "ansible://user@debian_stretch?force_ansible=True&sudo=True", + "ssh://user@debian_buster?sudo=True", + "safe-ssh://user@debian_buster?sudo=True", + "docker://user@debian_buster?sudo=True", + "paramiko://user@debian_buster?sudo=True", + "ansible://user@debian_buster?sudo=True", + "ansible://user@debian_buster?force_ansible=True&sudo=True", ] SUDO_USER_HOSTS = [ - "ssh://debian_stretch?sudo=True&sudo_user=user", - "safe-ssh://debian_stretch?sudo=True&sudo_user=user", - "docker://debian_stretch?sudo=True&sudo_user=user", - "paramiko://debian_stretch?sudo=True&sudo_user=user", - "ansible://debian_stretch?sudo=True&sudo_user=user", - "ansible://debian_stretch?force_ansible=True&sudo=True&sudo_user=user", + "ssh://debian_buster?sudo=True&sudo_user=user", + "safe-ssh://debian_buster?sudo=True&sudo_user=user", + "docker://debian_buster?sudo=True&sudo_user=user", + "paramiko://debian_buster?sudo=True&sudo_user=user", + "ansible://debian_buster?sudo=True&sudo_user=user", + "ansible://debian_buster?force_ansible=True&sudo=True&sudo_user=user", ] @@ -79,7 +79,7 @@ @pytest.mark.testinfra_hosts(*HOSTS) def test_encoding(host): - # stretch image is fr_FR@ISO-8859-15 + # buster image is fr_FR@ISO-8859-15 cmd = host.run("ls -l %s", "/é") if host.backend.get_connection_type() == "docker": # docker bug ? @@ -108,7 +108,7 @@ @pytest.mark.testinfra_hosts( - "ansible://debian_stretch?force_ansible=True") + "ansible://debian_buster?force_ansible=True") def test_ansible_any_error_fatal(host): os.environ['ANSIBLE_ANY_ERRORS_FATAL'] = 'True' try: @@ -355,6 +355,53 @@ del os.environ['ANSIBLE_CONFIG'] +@pytest.mark.parametrize( + 'options,expected_cli,expected_args', + [ + ({}, "--check", []), + ({"become": True}, "--become --check", []), + ({"check": False}, "", []), + ({"diff": True, "check": False}, "--diff", []), + ({"one_line": True, "check": False}, "--one-line", []), + ( + {"become_method": "sudo", "check": False}, + "--become-method %s", + ["sudo"], + ), + ( + {"become_user": "root", "check": False}, + "--become-user %s", + ["root"], + ), + ({"user": "root", "check": False}, "--user %s", ["root"]), + ( + { + "extra_vars": {"target": "production", "foo": 42}, + "check": False + }, + "--extra-vars %s", + ['{"target": "production", "foo": 42}'], + ), + ({"verbose": 0, "check": False}, "", []), + ({"verbose": 1, "check": False}, "-v", []), + ({"verbose": 2, "check": False}, "-vv", []), + ({"verbose": 3, "check": False}, "-vvv", []), + ({"verbose": 4, "check": False}, "-vvvv", []), + ], +) +def test_ansible_options(options, expected_cli, expected_args): + runner = AnsibleRunner() + cli, args = runner.options_to_cli(options) + assert cli == expected_cli + assert args == expected_args + + +def test_ansible_unknown_option(): + runner = AnsibleRunner() + with pytest.raises(KeyError, match="^'unknown'$"): + runner.options_to_cli({"unknown": True}) + + def test_backend_importables(): # just check that all declared backend are importable and NAME is set # correctly diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/test/test_modules.py new/testinfra-5.0.0/test/test_modules.py --- old/testinfra-4.0.0/test/test_modules.py 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/test/test_modules.py 2020-03-05 19:42:34.000000000 +0100 @@ -28,7 +28,7 @@ "docker://{}".format(image) for image in ( "alpine", "archlinux", "centos_6", "centos_7", - "debian_stretch", "ubuntu_xenial" + "debian_buster", "ubuntu_xenial" ) ]) @@ -43,21 +43,21 @@ ssh = host.package(name) version = { - "alpine": "7.", + "alpine": "8.", "archlinux": "8.", "centos_6": "5.", "centos_7": "7.", - "debian_stretch": "1:7.4", + "debian_buster": "1:7.9", "ubuntu_xenial": "1:7.2" }[docker_image] assert ssh.is_installed assert ssh.version.startswith(version) release = { - "alpine": "r6", + "alpine": "r0", "archlinux": None, "centos_6": ".el6", "centos_7": ".el7", - "debian_stretch": None, + "debian_buster": None, "ubuntu_xenial": None }[docker_image] if release is None: @@ -92,11 +92,11 @@ assert host.system_info.type == "linux" release, distribution, codename = { - "alpine": (r"^3\.9\.", "alpine", None), + "alpine": (r"^3\.11\.", "alpine", None), "archlinux": ("rolling", "arch", None), "centos_6": (r"^6", "CentOS", None), "centos_7": (r"^7$", "centos", None), - "debian_stretch": (r"^9\.", "debian", "stretch"), + "debian_buster": (r"^10", "debian", "buster"), "ubuntu_xenial": (r"^16\.04$", "ubuntu", "xenial") }[docker_image] @@ -145,19 +145,17 @@ def test_salt(host): ssh_version = host.salt("pkg.version", "openssh-server", local=True) - assert ssh_version.startswith("1:7.4") + assert ssh_version.startswith("1:7.9") def test_puppet_resource(host): resource = host.puppet_resource("package", "openssh-server") - assert resource["openssh-server"]["ensure"].startswith("1:7.4") + assert resource["openssh-server"]["ensure"].startswith("1:7.9") def test_facter(host): - assert host.facter()["lsbdistcodename"] == "stretch" - assert host.facter("lsbdistcodename") == { - "lsbdistcodename": "stretch", - } + assert host.facter()["os"]["distro"]["codename"] == "buster" + assert host.facter("virtual") == {"virtual": "docker"} def test_sysctl(host): @@ -217,7 +215,7 @@ "archlinux": ("/usr/sbin/init", "systemd"), "centos_6": ("/usr/sbin/sshd -D", "sshd"), "centos_7": ("/usr/sbin/init", "systemd"), - "debian_stretch": ("/sbin/init", "systemd"), + "debian_buster": ("/sbin/init", "systemd"), "ubuntu_xenial": ("/sbin/init", "systemd") }[docker_image] assert init.args == args @@ -228,7 +226,7 @@ user = host.user("sshd") assert user.exists assert user.name == "sshd" - assert user.uid == 106 + assert user.uid == 105 assert user.gid == 65534 assert user.group == "nogroup" assert user.gids == [65534] @@ -275,9 +273,12 @@ def test_file(host): host.check_output("mkdir -p /d && printf foo > /d/f && chmod 600 /d/f") + host.check_output('touch "/d/f\nl"') + host.check_output('touch "/d/f s"') d = host.file("/d") assert d.is_directory assert not d.is_file + assert d.listdir() == ["f", "f?l", "f s"] f = host.file("/d/f") assert f.exists assert f.is_file @@ -322,10 +323,10 @@ assert expected in str(excinfo.value) -@pytest.mark.testinfra_hosts("ansible://debian_stretch") +@pytest.mark.testinfra_hosts("ansible://debian_buster") def test_ansible_module(host): setup = host.ansible("setup")["ansible_facts"] - assert setup["ansible_lsb"]["codename"] == "stretch" + assert setup["ansible_lsb"]["codename"] == "buster" passwd = host.ansible("file", "path=/etc/passwd state=file") assert passwd["changed"] is False assert passwd["gid"] == 0 @@ -342,11 +343,11 @@ assert variables["myvar"] == "foo" assert variables["myhostvar"] == "bar" assert variables["mygroupvar"] == "qux" - assert variables["inventory_hostname"] == "debian_stretch" + assert variables["inventory_hostname"] == "debian_buster" assert variables["group_names"] == ["testgroup"] assert variables["groups"] == { - "all": ["debian_stretch"], - "testgroup": ["debian_stretch"], + "all": ["debian_buster"], + "testgroup": ["debian_buster"], } with pytest.raises(host.ansible.AnsibleException) as excinfo: @@ -358,7 +359,7 @@ host.ansible("command", "zzz", check=False) except host.ansible.AnsibleException as exc: assert exc.result['rc'] == 2 - # notez que the debian stretch container is set to LANG=fr_FR + # notez que the debian buster container is set to LANG=fr_FR assert exc.result['msg'] == ('[Errno 2] Aucun fichier ou dossier ' 'de ce type') @@ -366,8 +367,8 @@ assert result['stdout'] == 'foo' -@pytest.mark.testinfra_hosts("ansible://debian_stretch", - "ansible://user@debian_stretch") +@pytest.mark.testinfra_hosts("ansible://debian_buster", + "ansible://user@debian_buster") def test_ansible_module_become(host): user_name = host.user().name assert host.ansible('shell', 'echo $USER', @@ -383,6 +384,17 @@ check=False, become=True)['stdout'] == 'root' +@pytest.mark.testinfra_hosts("ansible://debian_buster") +def test_ansible_module_options(host): + assert host.ansible( + 'command', + 'id --user --name', + check=False, + become=True, + become_user='nobody', + )['stdout'] == 'nobody' + + @pytest.mark.destructive def test_supervisor(host): # Wait supervisord is running @@ -460,7 +472,7 @@ assert host.user().name == "root" -@pytest.mark.testinfra_hosts("docker://user@debian_stretch") +@pytest.mark.testinfra_hosts("docker://user@debian_buster") def test_sudo_to_root(host): assert host.user().name == "user" with host.sudo(): @@ -477,7 +489,7 @@ def test_pip_package(host): - assert host.pip_package.get_packages()['pip']['version'] == '9.0.1' + assert host.pip_package.get_packages()['pip']['version'] == '18.1' pytest = host.pip_package.get_packages(pip_path='/v/bin/pip')['pytest'] assert pytest['version'].startswith('2.') outdated = host.pip_package.get_outdated_packages( @@ -491,6 +503,8 @@ def test_iptables(host): + cmd = host.run("systemctl start netfilter-persistent") + assert cmd.exit_status == 0, f"{cmd.stdout}\n{cmd.stderr}" ssh_rule_str = \ '-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT' vip_redirect_rule_str = \ @@ -503,14 +517,26 @@ assert ssh_rule_str in input_rules assert vip_redirect_rule_str in nat_rules assert vip_redirect_rule_str in nat_prerouting_rules + + +def test_ip6tables(host): # test ip6tables call works; ipv6 setup is a whole huge thing, but # ensure we at least see the headings - v6_rules = host.iptables.rules(version=6) - assert '-P INPUT ACCEPT' in v6_rules - assert '-P FORWARD ACCEPT' in v6_rules - assert '-P OUTPUT ACCEPT' in v6_rules - v6_filter_rules = host.iptables.rules('filter', 'INPUT', version=6) - assert '-P INPUT ACCEPT' in v6_filter_rules + try: + v6_rules = host.iptables.rules(version=6) + except AssertionError as exc_info: + if "Perhaps ip6tables or your kernel needs to " \ + "be upgraded" in exc_info.args[0]: + pytest.skip(f"IPV6 does not seem to be enabled on the docker host" + f"\n{exc_info}") + else: + raise + else: + assert '-P INPUT ACCEPT' in v6_rules + assert '-P FORWARD ACCEPT' in v6_rules + assert '-P OUTPUT ACCEPT' in v6_rules + v6_filter_rules = host.iptables.rules('filter', 'INPUT', version=6) + assert '-P INPUT ACCEPT' in v6_filter_rules @all_images diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/testinfra/modules/ansible.py new/testinfra-5.0.0/testinfra/modules/ansible.py --- old/testinfra-4.0.0/testinfra/modules/ansible.py 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/testinfra/modules/ansible.py 2020-03-05 19:42:34.000000000 +0100 @@ -61,6 +61,20 @@ <https://docs.ansible.com/ansible/user_guide/become.html#id1>`_ is `False` by default. You can enable it with `become=True`. + Ansible arguments that are not related to the Ansible inventory or + connection (both managed by testinfra) are also accepted through keyword + arguments: + + - ``become_method`` *str* sudo, su, doas, etc. + - ``become_user`` *str* become this user. + - ``diff`` *bool*: when changing (small) files and templates, show the + differences in those files. + - ``extra_vars`` *dict* serialized to a JSON string, passed to + Ansible. + - ``one_line`` *bool*: condense output. + - ``user`` *str* connect as this user. + - ``verbose`` *int* level of verbosity + >>> host.ansible("apt", "name=nginx state=present")["changed"] False >>> host.ansible("apt", "name=nginx state=present", become=True)["changed"] @@ -71,6 +85,21 @@ 'jessie' >>> host.ansible("file", "path=/etc/passwd")["mode"] '0640' + >>> host.ansible( + ... "command", + ... "id --user --name", + ... check=False, + ... become=True, + ... become_user="http", + ... )["stdout"] + 'http' + >>> host.ansible( + ... "apt", + ... "name={{ packages }}", + ... check=False, + ... extra_vars={"packages": ["neovim", "vim"]}, + ... ) + # Installs neovim and vim. """ # pylint: disable=self-assigning-variable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/testinfra/modules/file.py new/testinfra-5.0.0/testinfra/modules/file.py --- old/testinfra-4.0.0/testinfra/modules/file.py 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/testinfra/modules/file.py 2020-03-05 19:42:34.000000000 +0100 @@ -166,6 +166,17 @@ """Return size of file in bytes""" raise NotImplementedError + def listdir(self): + """Return list of items under the directory + + >>> host.file("/tmp").listdir() + ['foo_file', 'bar_dir'] + """ + out = self.run_test("ls -1 -q -- %s", self.path) + if out.rc != 0: + raise RuntimeError("Unexpected output %s" % (out,)) + return out.stdout.splitlines() + def __repr__(self): return "<file %s>" % (self.path,) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/testinfra/modules/systeminfo.py new/testinfra-5.0.0/testinfra/modules/systeminfo.py --- old/testinfra-4.0.0/testinfra/modules/systeminfo.py 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/testinfra/modules/systeminfo.py 2020-03-05 19:42:34.000000000 +0100 @@ -154,7 +154,7 @@ """Distribution release number >>> host.system_info.release - '7.8' + '10.2' """ return self.sysinfo["release"] @@ -163,6 +163,6 @@ """Release code name >>> host.system_info.codename - 'wheezy' + 'buster' """ return self.sysinfo["codename"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/testinfra/utils/ansible_runner.py new/testinfra-5.0.0/testinfra/utils/ansible_runner.py --- old/testinfra-4.0.0/testinfra/utils/ansible_runner.py 2020-01-05 16:29:32.000000000 +0100 +++ new/testinfra-5.0.0/testinfra/utils/ansible_runner.py 2020-03-05 19:42:34.000000000 +0100 @@ -135,6 +135,43 @@ class AnsibleRunner(object): _runners = {} + _known_options = { + # Boolean arguments. + "become": { + "cli": "--become", + "type": "boolean", + }, + "check": { + "cli": "--check", + "type": "boolean", + }, + "diff": { + "cli": "--diff", + "type": "boolean", + }, + "one_line": { + "cli": "--one-line", + "type": "boolean", + }, + # String arguments. + "become_method": { + "cli": "--become-method", + "type": "string", + }, + "become_user": { + "cli": "--become-user", + "type": "string", + }, + "user": { + "cli": "--user", + "type": "string", + }, + # Arguments serialized as JSON. + "extra_vars": { + "cli": "--extra-vars", + "type": "json", + }, + } def __init__(self, inventory_file=None): self.inventory_file = inventory_file @@ -197,8 +234,35 @@ self.ansible_config, self.inventory, host, **kwargs) return self._host_cache[host] - def run_module(self, host, module_name, module_args, become=False, - check=True, **kwargs): + def options_to_cli(self, options): + verbose = options.pop("verbose", 0) + + args = {"become": False, "check": True} + args.update(options) + + cli = [] + cli_args = [] + if verbose: + cli.append('-' + "v" * verbose) + for arg_name, value in args.items(): + option = self._known_options[arg_name] + opt_cli = option["cli"] + opt_type = option["type"] + if opt_type == "boolean": + if value: + cli.append(opt_cli) + elif opt_type == "string": + cli.append(opt_cli + " %s") + cli_args.append(value) + elif opt_type == "json": + cli.append(opt_cli + " %s") + value_json = json.dumps(value) + cli_args.append(value_json) + else: + raise TypeError("Unsupported argument type '%s'." % opt_type) + return " ".join(cli), cli_args + + def run_module(self, host, module_name, module_args, **options): cmd, args = 'ansible --tree %s', [None] if self.inventory_file: cmd += ' -i %s' @@ -208,10 +272,10 @@ if module_args: cmd += ' --args %s' args += [module_args] - if become: - cmd += ' --become' - if check: - cmd += ' --check' + options_cli, options_args = self.options_to_cli(options) + if options_cli: + cmd += ' ' + options_cli + args.extend(options_args) cmd += ' %s' args += [host] with tempfile.TemporaryDirectory() as d: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/testinfra.egg-info/PKG-INFO new/testinfra-5.0.0/testinfra.egg-info/PKG-INFO --- old/testinfra-4.0.0/testinfra.egg-info/PKG-INFO 2020-01-05 16:29:47.000000000 +0100 +++ new/testinfra-5.0.0/testinfra.egg-info/PKG-INFO 2020-03-05 19:42:51.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: testinfra -Version: 4.0.0 +Version: 5.0.0 Summary: Test infrastructures Home-page: https://github.com/philpep/testinfra Author: Philippe Pepiot diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testinfra-4.0.0/testinfra.egg-info/SOURCES.txt new/testinfra-5.0.0/testinfra.egg-info/SOURCES.txt --- old/testinfra-4.0.0/testinfra.egg-info/SOURCES.txt 2020-01-05 16:29:48.000000000 +0100 +++ new/testinfra-5.0.0/testinfra.egg-info/SOURCES.txt 2020-03-05 19:42:51.000000000 +0100 @@ -31,7 +31,7 @@ images/archlinux/Dockerfile images/centos_6/Dockerfile images/centos_7/Dockerfile -images/debian_stretch/Dockerfile +images/debian_buster/Dockerfile images/ubuntu_xenial/Dockerfile test/conftest.py test/ssh_key