From 41d3b981d8858f5a32da2df557fa19561c4f7521 Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Thu, 25 Feb 2016 15:25:37 +0100 Subject: [PATCH] Tests with docker-compose Closes #67 --- .gitignore | 2 +- .travis.yml | 19 +++-- CONTRIBUTING.rst | 14 ++-- Vagrantfile | 25 ------- docker-compose.yml | 24 +++++++ images/{fedora_21 => fedora}/Dockerfile | 4 +- insecure_private_key | 27 +++++++ testinfra/test/integration/test_centos_7.py | 8 ++- .../{test_fedora_21.py => test_fedora.py} | 14 ++-- testinfra/test/integration/test_jessie.py | 6 +- testinfra/test/integration/test_trusty.py | 8 ++- testinfra/test/integration/test_wheezy.py | 6 +- .../utils/docker_compose_to_ssh_config.py | 70 +++++++++++++++++++ tox.ini | 6 +- 14 files changed, 178 insertions(+), 55 deletions(-) delete mode 100644 Vagrantfile create mode 100644 docker-compose.yml rename images/{fedora_21 => fedora}/Dockerfile (91%) create mode 100644 insecure_private_key rename testinfra/test/integration/{test_fedora_21.py => test_fedora.py} (79%) create mode 100644 testinfra/utils/docker_compose_to_ssh_config.py diff --git a/.gitignore b/.gitignore index 29aef166..cdfa6ebf 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,4 @@ coverage.xml flake8.report junit*.xml doc/build -.vagrant +.cache diff --git a/.travis.yml b/.travis.yml index a44d4bce..3a43649f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,25 @@ sudo: required services: - docker +env: + global: + - DOCKER_VERSION=1.10.2-0~trusty + - DOCKER_COMPOSE_VERSION=1.6.2 language: python python: 2.7 before_install: - - wget https://releases.hashicorp.com/vagrant/1.8.1/vagrant_1.8.1_x86_64.deb - - sudo dpkg -i vagrant_1.8.1_x86_64.deb - - for image in debian_wheezy debian_jessie ubuntu_trusty centos_7 fedora_21; do docker pull philpep/testinfra:$image; done - - vagrant up --provider=docker + - apt-cache madison docker-engine + - sudo apt-get -o Dpkg::Options::="--force-confnew" install -y docker-engine=${DOCKER_VERSION} + - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose + - chmod +x docker-compose + - sudo mv docker-compose /usr/local/bin + - docker version + - docker-compose version + - for image in debian_wheezy debian_jessie ubuntu_trusty centos_7; do docker pull philpep/testinfra:$image; done + - docker-compose up -d install: - pip install tox script: - tox +after_script: + - docker-compose kill diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index eb3b8685..4b54264e 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -14,13 +14,13 @@ You're encouraged to setup a full test environment, to add tests and check if all the tests pass *before* submitting your pull request. To run the complete test suite you must install: -- `Vagrant `_ version 1.7 or greater -- `Docker `_ version 1.7 or greater +- `Docker `_ version 1.10 or greater +- `Docker compose `_ version 1.6 or greater - `tox `_ To run all tests run:: - vagrant up --provider=docker + docker-compose up -d tox To run only some selected tests:: @@ -32,11 +32,11 @@ To run only some selected tests:: tox -e py27 -- -v --pdb testinfra/test/integration/test_jessie.py -To speedup the docker images generation during `vagrant up` you can download -them before running the tests (docker will detect they are the same and use the -cache):: +To speedup the docker images generation during `docker-compose up` you can +download them before running the tests (docker will detect they are the same +and use the cache):: - for tag in debian_jessie debian_wheezy centos_7 fedora_21 ubuntu_trusty; do + for tag in debian_jessie debian_wheezy centos_7 fedora ubuntu_trusty; do docker pull philpep/testinfra:$tag done diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 3ce9866a..00000000 --- a/Vagrantfile +++ /dev/null @@ -1,25 +0,0 @@ -# vim: ts=2 sw=2 et ft=ruby - -Vagrant.configure("2") do |config| - config.vm.synced_folder ".", "/vagrant", disabled: true - config.ssh.username = "root" - [ - "debian_wheezy", "debian_jessie", "ubuntu_trusty", - "centos_7", "fedora_21", - ].each do |vmname| - config.vm.define vmname do |vm| - vm.vm.provider "docker" do |docker| - docker.build_dir = "images/#{vmname}" - docker.has_ssh = true - docker.name = vmname - if ENV['TRAVIS'] or ['debian_jessie', 'centos_7', 'fedora_21'].include? vmname - # Travis require privileged to run exec on containers... - # Systemd require privileged - docker.create_args = ["-h", vmname, "--privileged"] - else - docker.create_args = ["-h", vmname] - end - end - end - end -end diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..d8b3a3dc --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,24 @@ +version: '2' +services: + debian_wheezy: + build: images/debian_wheezy + hostname: debian_wheezy + + debian_jessie: + build: images/debian_jessie + privileged: true + hostname: debian_jessie + + centos_7: + build: images/centos_7 + privileged: true + hostname: centos_7 + + fedora: + build: images/fedora + privileged: true + hostname: fedora + + ubuntu_trusty: + build: images/ubuntu_trusty + hostname: ubuntu_trusty diff --git a/images/fedora_21/Dockerfile b/images/fedora/Dockerfile similarity index 91% rename from images/fedora_21/Dockerfile rename to images/fedora/Dockerfile index 7ff81ae5..b3a2a525 100644 --- a/images/fedora_21/Dockerfile +++ b/images/fedora/Dockerfile @@ -1,6 +1,6 @@ -FROM fedora:21 +FROM fedora:23 -RUN yum -y install systemd openssh-server && yum clean all &&\ +RUN dnf -y install which procps python systemd openssh-server && dnf clean all &&\ (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done) && \ rm -f /lib/systemd/system/multi-user.target.wants/* && \ rm -f /etc/systemd/system/*.wants/* && \ diff --git a/insecure_private_key b/insecure_private_key new file mode 100644 index 00000000..7d6a0839 --- /dev/null +++ b/insecure_private_key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI +w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP +kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2 +hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO +Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW +yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd +ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1 +Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf +TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK +iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A +sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf +4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP +cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk +EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN +CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX +3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG +YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj +3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+ +dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz +6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC +P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF +llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ +kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH ++vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ +NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s= +-----END RSA PRIVATE KEY----- diff --git a/testinfra/test/integration/test_centos_7.py b/testinfra/test/integration/test_centos_7.py index a24a09a6..b180f648 100644 --- a/testinfra/test/integration/test_centos_7.py +++ b/testinfra/test/integration/test_centos_7.py @@ -19,11 +19,15 @@ import pytest + +from testinfra.utils.docker_compose_to_ssh_config import DockerComposeService + + pytestmark = pytest.mark.integration testinfra_hosts = [ "%s://centos_7" % (b_type,) - for b_type in ("ssh", "paramiko", "safe-ssh", "docker") -] + for b_type in ("ssh", "paramiko", "safe-ssh") +] + ["docker://" + DockerComposeService.get("centos_7")["name"]] if sys.version_info == 2: testinfra_hosts.append("ansible://centos_7") diff --git a/testinfra/test/integration/test_fedora_21.py b/testinfra/test/integration/test_fedora.py similarity index 79% rename from testinfra/test/integration/test_fedora_21.py rename to testinfra/test/integration/test_fedora.py index 35f179b8..d4b7f9dc 100644 --- a/testinfra/test/integration/test_fedora_21.py +++ b/testinfra/test/integration/test_fedora.py @@ -19,20 +19,22 @@ import pytest +from testinfra.utils.docker_compose_to_ssh_config import DockerComposeService + pytestmark = pytest.mark.integration testinfra_hosts = [ - "%s://fedora_21" % (b_type,) - for b_type in ("ssh", "paramiko", "safe-ssh", "docker") -] + "%s://fedora" % (b_type,) + for b_type in ("ssh", "paramiko", "safe-ssh") +] + ["docker://" + DockerComposeService.get("fedora")["name"]] if sys.version_info[0] == 2: - testinfra_hosts.append("ansible://fedora_21") + testinfra_hosts.append("ansible://fedora") def test_ssh_package(Package): ssh = Package("openssh-server") assert ssh.is_installed - assert ssh.version.startswith("6.6") + assert ssh.version.startswith("7.1") def test_ssh_service(Service): @@ -43,7 +45,7 @@ def test_ssh_service(Service): def test_systeminfo(SystemInfo): assert SystemInfo.type == "linux" - assert SystemInfo.release == "21" + assert SystemInfo.release == "23" assert SystemInfo.distribution == "fedora" assert SystemInfo.codename is None diff --git a/testinfra/test/integration/test_jessie.py b/testinfra/test/integration/test_jessie.py index 72c7f3d9..8fc94752 100644 --- a/testinfra/test/integration/test_jessie.py +++ b/testinfra/test/integration/test_jessie.py @@ -19,11 +19,13 @@ import pytest +from testinfra.utils.docker_compose_to_ssh_config import DockerComposeService + pytestmark = pytest.mark.integration testinfra_hosts = [ "%s://debian_jessie" % (b_type,) - for b_type in ("ssh", "paramiko", "safe-ssh", "docker") -] + for b_type in ("ssh", "paramiko", "safe-ssh") +] + ["docker://" + DockerComposeService.get("debian_jessie")["name"]] if sys.version_info[0] == 2: testinfra_hosts.append("ansible://debian_jessie") diff --git a/testinfra/test/integration/test_trusty.py b/testinfra/test/integration/test_trusty.py index b4c0a586..80eac2d1 100644 --- a/testinfra/test/integration/test_trusty.py +++ b/testinfra/test/integration/test_trusty.py @@ -20,13 +20,19 @@ import pytest +from testinfra.utils.docker_compose_to_ssh_config import DockerComposeService + +_docker_name = DockerComposeService.get("ubuntu_trusty")["name"] pytestmark = pytest.mark.integration testinfra_hosts = [ "%s://ubuntu_trusty?sudo=%s" % (b_type, sudo) for b_type, sudo in itertools.product( - ["ssh", "paramiko", "safe-ssh", "docker"], + ["ssh", "paramiko", "safe-ssh"], ["true", "false"], ) +] + [ + "docker://%s?sudo=%s" % (_docker_name, sudo,) + for sudo in ["true", "false"] ] if sys.version_info == 2: diff --git a/testinfra/test/integration/test_wheezy.py b/testinfra/test/integration/test_wheezy.py index 1fc8263b..dadc2001 100644 --- a/testinfra/test/integration/test_wheezy.py +++ b/testinfra/test/integration/test_wheezy.py @@ -19,11 +19,13 @@ import pytest +from testinfra.utils.docker_compose_to_ssh_config import DockerComposeService + pytestmark = pytest.mark.integration testinfra_hosts = [ "%s://debian_wheezy" % (b_type,) - for b_type in ("ssh", "paramiko", "safe-ssh", "docker") -] + for b_type in ("ssh", "paramiko", "safe-ssh") +] + ["docker://" + DockerComposeService.get("debian_wheezy")["name"]] if sys.version_info[0] == 2: testinfra_hosts.append("ansible://debian_wheezy") diff --git a/testinfra/utils/docker_compose_to_ssh_config.py b/testinfra/utils/docker_compose_to_ssh_config.py new file mode 100644 index 00000000..f028ff9f --- /dev/null +++ b/testinfra/utils/docker_compose_to_ssh_config.py @@ -0,0 +1,70 @@ +# -*- coding: utf8 -*- +# Copyright © 2016 Philippe Pepiot +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import testinfra + +template = """ +Host %s + HostName %s + User root + Port 22 + UserKnownHostsFile /dev/null + StrictHostKeyChecking no + PasswordAuthentication no + IdentityFile .cache/insecure_private_key + IdentitiesOnly yes + LogLevel FATAL +""" + + +class DockerComposeService(object): + _services = None + + @classmethod + def get_services(cls): + if cls._services is not None: + return cls._services + + cls._services = {} + Command = testinfra.get_backend("local://").get_module("Command") + + for line in Command.check_output(( + "docker-compose ps -q | xargs docker inspect --format " + """'{{ index .Config.Labels "com.docker.compose.service" }} """ + """{{ .Name }} """ + """{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'""" + )).splitlines(): + service, name, ip = line.split() + cls._services[service] = { + "name": name[1:] if name[0] == "/" else name, + "ip": ip, + } + + return cls._services + + @classmethod + def get(cls, service): + return cls.get_services()[service] + + +def docker_compose_to_ssh_config(): + for service, values in DockerComposeService.get_services().items(): + print(template % (service, values["ip"])) + + +if __name__ == "__main__": + docker_compose_to_ssh_config() diff --git a/tox.ini b/tox.ini index d7c366f1..19cd81e3 100644 --- a/tox.ini +++ b/tox.ini @@ -6,9 +6,9 @@ deps= -rtest-requirements.txt py27: ansible>=2 commands= - /bin/sh -c 'test -f .vagrant/ssh-config || vagrant ssh-config > .vagrant/ssh-config' - py27: /bin/sh -c 'python -m testinfra.utils.ssh_config_to_ansible_inventory .vagrant/ssh-config > .vagrant/ansible-inventory' - testinfra --integration --ansible-inventory=.vagrant/ansible-inventory --ssh-config=.vagrant/ssh-config {posargs:-v -n 5 --cov testinfra --cov-report xml --cov-report term testinfra} + /bin/sh -c 'mkdir -p .cache && install -m 600 insecure_private_key .cache/ && python -m testinfra.utils.docker_compose_to_ssh_config > .cache/ssh-config' + py27: /bin/sh -c 'python -m testinfra.utils.ssh_config_to_ansible_inventory .cache/ssh-config > .cache/ansible-inventory' + testinfra --integration --ansible-inventory=.cache/ansible-inventory --ssh-config=.cache/ssh-config {posargs:-v -n 5 --cov testinfra --cov-report xml --cov-report term testinfra} usedevelop=True passenv=HOME TRAVIS