From e94f8d8a1fd632b23b98978889a74fdca31dcb7f Mon Sep 17 00:00:00 2001 From: Ivan Mikushin Date: Tue, 1 Sep 2015 19:11:02 +0500 Subject: [PATCH 1/6] revive integration tests --- scripts/run | 2 +- tests/container/README.txt | 1 - .../rancheros/invmtest/test_sample.py | 6 ----- tests/container/requirements.txt | 3 --- tests/container/setup.py | 11 --------- tests/container/tox.ini | 12 ---------- tests/integration/rancherostest/conftest.py | 3 ++- .../rancherostest/test_00_system.py | 23 ++++++++++--------- tests/integration/rancherostest/util.py | 3 +++ tests/integration/requirements.txt | 19 +++++++-------- tests/integration/tox.ini | 8 +++---- 11 files changed, 32 insertions(+), 59 deletions(-) delete mode 100644 tests/container/README.txt delete mode 100644 tests/container/rancheros/invmtest/test_sample.py delete mode 100644 tests/container/requirements.txt delete mode 100644 tests/container/setup.py delete mode 100644 tests/container/tox.ini diff --git a/scripts/run b/scripts/run index 62387d4a..dfb58706 100755 --- a/scripts/run +++ b/scripts/run @@ -114,7 +114,7 @@ if [ "$UNAME" == "Darwin" ] && [ -x $(which xhyve) ]; then mkisofs -R -V config-2 -o "${CLOUD_CONFIG_ISO}" "$(pwd)/cloud-init" echo PWD=`pwd` - exec sudo xhyve -A -H -P -u \ + exec sudo -n xhyve -A -H -P -u \ -m 4G \ -s 0:0,hostbridge -s 31,lpc \ -l com1,stdio \ diff --git a/tests/container/README.txt b/tests/container/README.txt deleted file mode 100644 index 76616d3c..00000000 --- a/tests/container/README.txt +++ /dev/null @@ -1 +0,0 @@ -RancherOS In-VM Integration Tests diff --git a/tests/container/rancheros/invmtest/test_sample.py b/tests/container/rancheros/invmtest/test_sample.py deleted file mode 100644 index 1030a2e3..00000000 --- a/tests/container/rancheros/invmtest/test_sample.py +++ /dev/null @@ -1,6 +0,0 @@ -def func(x): - return x + 1 - - -def test_answer(): - assert func(3) == 4 diff --git a/tests/container/requirements.txt b/tests/container/requirements.txt deleted file mode 100644 index 8d2f15f3..00000000 --- a/tests/container/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -flake8==2.4.0 -pytest==2.7.0 -tox==1.9.2 diff --git a/tests/container/setup.py b/tests/container/setup.py deleted file mode 100644 index 2d44c6cc..00000000 --- a/tests/container/setup.py +++ /dev/null @@ -1,11 +0,0 @@ -from distutils.core import setup - -setup( - name='RancherOSInVMTests', - version='0.1', - packages=[ - 'rancheros.invmtest' - ], - license='ASL 2.0', - long_description=open('README.txt').read(), -) diff --git a/tests/container/tox.ini b/tests/container/tox.ini deleted file mode 100644 index 7052d0fb..00000000 --- a/tests/container/tox.ini +++ /dev/null @@ -1,12 +0,0 @@ -[tox] -envlist=flake8, py27 - -[testenv] -deps=-rrequirements.txt -changedir={toxinidir} -commands=py.test --durations=20 {posargs} - -[testenv:flake8] -deps=-rrequirements.txt -changedir={toxinidir} -commands=flake8 rancheros diff --git a/tests/integration/rancherostest/conftest.py b/tests/integration/rancherostest/conftest.py index 6f64c247..e81b2083 100644 --- a/tests/integration/rancherostest/conftest.py +++ b/tests/integration/rancherostest/conftest.py @@ -1,10 +1,11 @@ import os import pytest +import subprocess @pytest.fixture(scope="session", autouse=True) def chdir_to_project_root(): os.chdir('../..') - print('\nChdir to project root dir') + print('\nChdir to project root dir: ' + subprocess.check_output('pwd')) os.chmod('./tests/integration/assets/test.key', 0o600) print('Also, `chmod 600 tests/integration/assets/test.key` to make ssh happy') diff --git a/tests/integration/rancherostest/test_00_system.py b/tests/integration/rancherostest/test_00_system.py index 920d2bfe..32ab6dea 100644 --- a/tests/integration/rancherostest/test_00_system.py +++ b/tests/integration/rancherostest/test_00_system.py @@ -10,7 +10,7 @@ def qemu(request): def rancheros_version(): with open('./scripts/version') as f: - for ln in iter(f.readline, ''): + for ln in f: (k, _, v) = ln.partition('=') if k == 'VERSION' and v.strip() != '': return v.strip() @@ -19,13 +19,14 @@ def rancheros_version(): @pytest.mark.timeout(30) def test_system_boot(qemu): - with qemu.stdout as f: - for ln in iter(f.readline, ''): - ros_booted_substr = str.find(ln, 'RancherOS {v} started'.format(v=rancheros_version())) - print(str.strip(ln)) - if ros_booted_substr > -1: - assert True - return + version = rancheros_version() + print('parsed version: ' + version) + for ln in u.iter_lines(qemu.stdout): + ros_booted_substr = str.find(ln, 'RancherOS {v} started'.format(v=version)) + print(str.strip(ln)) + if ros_booted_substr > -1: + assert True + return assert False @@ -38,8 +39,8 @@ def test_run_system_container(qemu): './scripts/ssh sudo system-docker run --rm busybox /bin/true', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) - with ssh, ssh.stdout as f: - for ln in iter(f.readline, ''): - print(str.strip(ln)) + for ln in u.iter_lines(ssh.stdout): + print(str.strip(ln)) + ssh.wait() assert ssh.returncode == 0 diff --git a/tests/integration/rancherostest/util.py b/tests/integration/rancherostest/util.py index de6b4994..ec9e61a9 100644 --- a/tests/integration/rancherostest/util.py +++ b/tests/integration/rancherostest/util.py @@ -3,6 +3,9 @@ import subprocess import time +def iter_lines(s): + return iter(s.readline, '') + def run_qemu(request, run_args=[]): subprocess.check_call('rm -f ./state/empty-hd.img', shell=True) print('\nrm ./state/*') diff --git a/tests/integration/requirements.txt b/tests/integration/requirements.txt index 9f903942..1053a4a4 100644 --- a/tests/integration/requirements.txt +++ b/tests/integration/requirements.txt @@ -1,10 +1,11 @@ -PyYAML.Yandex==3.11.1 -flake8==2.4.0 -mccabe==0.3 -pep8==1.6.2 -py==1.4.27 +PyYAML==3.11 +flake8==2.4.1 +mccabe==0.3.1 +pep8==1.5.7 +pluggy==0.3.0 +py==1.4.30 pyflakes==0.8.1 -pytest==2.7.0 -pytest-timeout==0.4 -tox==1.9.2 -virtualenv==12.1.1 +pytest==2.7.2 +tox==2.1.1 +virtualenv==13.1.2 +wsgiref==0.1.2 diff --git a/tests/integration/tox.ini b/tests/integration/tox.ini index 20c60287..238c0f25 100644 --- a/tests/integration/tox.ini +++ b/tests/integration/tox.ini @@ -1,15 +1,15 @@ [tox] -envlist=flake8, py34 +envlist=flake8, py27 [testenv] deps=-rrequirements.txt -changedir={toxinidir} +changedir=rancherostest commands=py.test --durations=20 {posargs} [testenv:flake8] deps=-rrequirements.txt -changedir={toxinidir} -commands=flake8 rancherostest +changedir=rancherostest +commands=flake8 . [flake8] max-line-length = 120 From 74e589039bbe2e24c3efa546c43a9d1aa39c94fb Mon Sep 17 00:00:00 2001 From: Ivan Mikushin Date: Thu, 3 Sep 2015 19:06:09 +0500 Subject: [PATCH 2/6] make run and ssh scripts more robust Detect if KVM is available. Enable QEMU to run w/o KVM (in the cloud or on OS X). Use --xhyve flag to run with xhyve on OS X. --- scripts/run | 41 ++++++++++++++++++++++++----------------- scripts/ssh | 18 ++++++++++++++++-- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/scripts/run b/scripts/run index dfb58706..1cb3f10e 100755 --- a/scripts/run +++ b/scripts/run @@ -22,7 +22,7 @@ HD_GZ=${BASE}/assets/empty-hd.img.gz INITRD_TMP=${BUILD}/$(${sha1sum} ${INITRD} | awk '{print $1}') INITRD_CURRENT=${BUILD}/initrd-current INITRD_TEST=${BUILD}/initrd.test -USER_DATA=cloud-init/openstack/latest/user_data +USER_DATA=${BUILD}/cloud-config/openstack/latest/user_data # PREREQ: brew install coreutils path() { @@ -45,6 +45,11 @@ while [ "$#" -gt 0 ]; do exit 1 fi ;; + --xhyve) + if [ "$UNAME" == "Darwin" ] && [ -x $(which xhyve) ]; then + XHYVE=1 + fi + ;; *) break ;; @@ -77,14 +82,15 @@ ln -sf ${INITRD_TMP} ${INITRD_CURRENT} mkdir -p ${INITRD_TMP}/usr/{bin,share/ros} cp bin/rancheros ${INITRD_TMP}/usr/bin/ros cp -f os-config.yml ${INITRD_TMP}/usr/share/ros -cd ${INITRD_TMP} +pushd ${INITRD_TMP} find . | cpio -H newc -o > ${INITRD_TEST} +popd if [ ! -e ${HD} ]; then mkdir -p $(dirname ${HD}) - if [ "$UNAME" == "Darwin" ]; then qemu-img create -f raw -o size=10G ${HD} - elif [ "$UNAME" == "Linux" ]; then gzip -dc ${HD_GZ} > ${HD}; + if [ "$XHYVE" == "1" ]; then qemu-img create -f raw -o size=10G ${HD} + else qemu-img create -f qcow2 -o size=10G ${HD} fi fi @@ -103,15 +109,15 @@ else done fi -KERNEL_ARGS="rancher.password=rancher rancher.modules=[9p,9pnet_virtio] console=ttyS0 ${QEMU_APPEND}" +KERNEL_ARGS="quiet rancher.password=rancher console=ttyS0 ${QEMU_APPEND}" +KERNEL_ARGS="${KERNEL_ARGS} rancher.state.formatzero=true rancher.state.autoformat=[/dev/sda,/dev/vda]" -if [ "$UNAME" == "Darwin" ] && [ -x $(which xhyve) ]; then +CLOUD_CONFIG_ISO="${BUILD}/cloud-config.iso" +rm -rf ${CLOUD_CONFIG_ISO} - CLOUD_CONFIG_ISO="$(pwd)/cloud-config.iso" - rm -rf ${CLOUD_CONFIG_ISO} +mkisofs -R -V config-2 -o "${CLOUD_CONFIG_ISO}" "$BUILD/cloud-config" - # PREREQ: brew install cdrtools - mkisofs -R -V config-2 -o "${CLOUD_CONFIG_ISO}" "$(pwd)/cloud-init" +if [ "$XHYVE" == "1" ]; then echo PWD=`pwd` exec sudo -n xhyve -A -H -P -u \ @@ -122,9 +128,12 @@ if [ "$UNAME" == "Darwin" ] && [ -x $(which xhyve) ]; then -s 3,ahci-cd,${CLOUD_CONFIG_ISO} \ -s 4,virtio-blk,${HD} \ -U a01fb25c-3a19-4759-a47a-2e353e51807d \ - -f kexec,${KERNEL},${INITRD_TEST},"earlyprintk=serial elevator=noop rancher.state.formatzero=true rancher.state.autoformat=[/dev/sda,/dev/vda] ${KERNEL_ARGS}" + -f kexec,${KERNEL},${INITRD_TEST},"earlyprintk=serial elevator=noop ${KERNEL_ARGS}" -elif [ "$UNAME" == "Linux" ] && [ -x $(which qemu-system-x86_64) ]; then +elif [ -x $(which qemu-system-x86_64) ]; then + if [ -c /dev/kvm ] && [ -r /dev/kvm ] && [ -w /dev/kvm ]; then + KVM_ENABLE="-machine accel=kvm -cpu host" + fi exec qemu-system-x86_64 -serial stdio \ -kernel ${KERNEL} \ -initrd ${INITRD_TEST} \ @@ -132,14 +141,12 @@ elif [ "$UNAME" == "Linux" ] && [ -x $(which qemu-system-x86_64) ]; then -net nic,vlan=0,model=virtio \ -net user,vlan=0,hostfwd=tcp::2222-:22,hostname=rancher-dev \ -drive if=virtio,file=${HD} \ - -machine accel=kvm \ - -cpu host \ + ${KVM_ENABLE} \ -smp 4 \ - -fsdev local,id=conf,security_model=none,readonly,path=$(pwd)/cloud-init \ - -device virtio-9p-pci,fsdev=conf,mount_tag=config-2 \ + -cdrom ${CLOUD_CONFIG_ISO} \ -append "${KERNEL_ARGS}" \ - -serial mon:telnet:localhost:4444,server,nowait \ -nographic \ + -display none \ ${QEMU_ARGS} "${@}" else exit 42 diff --git a/scripts/ssh b/scripts/ssh index 30dc486c..6455ca72 100755 --- a/scripts/ssh +++ b/scripts/ssh @@ -7,10 +7,24 @@ chmod 0600 ./assets/rancher.key UNAME=$(uname) -if [ "$UNAME" == "Darwin" ]; then +while [ "$#" -gt 0 ]; do + case $1 in + --xhyve) + shift 1 + if [ "$UNAME" == "Darwin" ] && [ -x $(which xhyve) ]; then + XHYVE=1 + fi + ;; + *) + break + ;; + esac +done + +if [ "$XHYVE" == "1" ]; then HOST=192.168.64.2 # consult `/var/db/dhcpd_leases` or delete it exec ssh -F ./assets/scripts_ssh_config -i ./assets/rancher.key rancher@${HOST} "$@" -elif [ "$UNAME" == "Linux" ]; then +else exec ssh -p 2222 -F ./assets/scripts_ssh_config -i ./assets/rancher.key rancher@localhost "$@" fi From bde6b8bb7abf11a2d8943814928cf4674b423286 Mon Sep 17 00:00:00 2001 From: Ivan Mikushin Date: Thu, 3 Sep 2015 20:07:57 +0500 Subject: [PATCH 3/6] make tox happy --- tests/integration/rancherostest/util.py | 1 + tests/integration/tox.ini | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/integration/rancherostest/util.py b/tests/integration/rancherostest/util.py index ec9e61a9..f17f85ee 100644 --- a/tests/integration/rancherostest/util.py +++ b/tests/integration/rancherostest/util.py @@ -6,6 +6,7 @@ import time def iter_lines(s): return iter(s.readline, '') + def run_qemu(request, run_args=[]): subprocess.check_call('rm -f ./state/empty-hd.img', shell=True) print('\nrm ./state/*') diff --git a/tests/integration/tox.ini b/tests/integration/tox.ini index 238c0f25..2565d4f9 100644 --- a/tests/integration/tox.ini +++ b/tests/integration/tox.ini @@ -3,13 +3,11 @@ envlist=flake8, py27 [testenv] deps=-rrequirements.txt -changedir=rancherostest -commands=py.test --durations=20 {posargs} +commands=py.test --durations=20 rancherostest {posargs} [testenv:flake8] deps=-rrequirements.txt -changedir=rancherostest -commands=flake8 . +commands=flake8 rancherostest [flake8] max-line-length = 120 From 57444246ba428f840e0cd86237b1dbf366a85afb Mon Sep 17 00:00:00 2001 From: Ivan Mikushin Date: Fri, 4 Sep 2015 12:13:51 +0500 Subject: [PATCH 4/6] cleanup python tox setup --- .dockerignore | 2 ++ tests/integration/requirements.txt | 9 --------- tests/integration/tox.ini | 3 ++- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.dockerignore b/.dockerignore index fe5669be..b1d8c320 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,3 +10,5 @@ build dist assets Godeps/_workspace/pkg +tests/integration/.venv* +tests/integration/.tox diff --git a/tests/integration/requirements.txt b/tests/integration/requirements.txt index 1053a4a4..59cebadf 100644 --- a/tests/integration/requirements.txt +++ b/tests/integration/requirements.txt @@ -1,11 +1,2 @@ PyYAML==3.11 -flake8==2.4.1 -mccabe==0.3.1 -pep8==1.5.7 -pluggy==0.3.0 -py==1.4.30 -pyflakes==0.8.1 pytest==2.7.2 -tox==2.1.1 -virtualenv==13.1.2 -wsgiref==0.1.2 diff --git a/tests/integration/tox.ini b/tests/integration/tox.ini index 2565d4f9..ace164fb 100644 --- a/tests/integration/tox.ini +++ b/tests/integration/tox.ini @@ -1,12 +1,13 @@ [tox] envlist=flake8, py27 +skipsdist=True [testenv] deps=-rrequirements.txt commands=py.test --durations=20 rancherostest {posargs} [testenv:flake8] -deps=-rrequirements.txt +deps=flake8 commands=flake8 rancherostest [flake8] From 950158823c3ef68e25f9aff9015f0fe39e5de150 Mon Sep 17 00:00:00 2001 From: Ivan Mikushin Date: Fri, 4 Sep 2015 14:59:06 +0500 Subject: [PATCH 5/6] run integration tests as part of the build --- .dockerignore | 3 ++- .dockerignore.docker | 5 ++++- .gitignore | 2 ++ Dockerfile.build-base | 5 ++++- Makefile.docker | 4 +++- assets/empty-hd.img.gz | Bin 181960 -> 0 bytes scripts/ci | 2 +- scripts/docker-run.sh | 2 +- tests/integration/tox.ini | 2 +- 9 files changed, 18 insertions(+), 7 deletions(-) delete mode 100644 assets/empty-hd.img.gz diff --git a/.dockerignore b/.dockerignore index b1d8c320..4d50ab09 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,7 +8,8 @@ tmp state build dist -assets Godeps/_workspace/pkg tests/integration/.venv* tests/integration/.tox +*/*/*/*.pyc +*/*/*/__pycache__ diff --git a/.dockerignore.docker b/.dockerignore.docker index b36c0d26..0b3eb86d 100644 --- a/.dockerignore.docker +++ b/.dockerignore.docker @@ -7,5 +7,8 @@ gopath tmp state build -assets Godeps/_workspace/pkg +tests/integration/.venv* +tests/integration/.tox +*/*/*/*.pyc +*/*/*/__pycache__ diff --git a/.gitignore b/.gitignore index 342b3516..38ff8a7b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ /tests/integration/MANIFEST /tests/integration/.venv* /tests/integration/.tox +*.pyc +__pychache__ diff --git a/Dockerfile.build-base b/Dockerfile.build-base index 3355c155..50c7e335 100644 --- a/Dockerfile.build-base +++ b/Dockerfile.build-base @@ -2,7 +2,8 @@ FROM debian:jessie RUN apt-get update && \ apt-get -y dist-upgrade && \ apt-get -y install locales sudo vim less curl wget git rsync build-essential syslinux isolinux xorriso \ - libblkid-dev libmount-dev libselinux1-dev + libblkid-dev libmount-dev libselinux1-dev genisoimage qemu-kvm python-pip +RUN ln -s /usr/bin/genisoimage /usr/bin/mkisofs RUN locale-gen en_US.UTF-8 RUN curl -sSL https://get.docker.com/ | sh @@ -11,6 +12,8 @@ RUN curl -sSL https://get.docker.com/ | sh #ENV LC_ALL en_US.UTF-8 #ENV TERM linux +RUN pip install tox + ENV GOLANG_VERSION 1.4.2 RUN curl -sSL https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz | tar -v -C /usr/src -xz RUN cd /usr/src/go/src && ./make.bash --no-clean 2>&1 diff --git a/Makefile.docker b/Makefile.docker index 761afc39..b0ff821a 100644 --- a/Makefile.docker +++ b/Makefile.docker @@ -60,5 +60,7 @@ build-all: \ $(DIST)/artifacts/rancheros.iso \ $(DIST)/artifacts/iso-checksums.txt +integration-tests: + cd tests/integration && tox -.PHONY: build-all installer version bin/rancheros +.PHONY: build-all installer version bin/rancheros integration-tests diff --git a/assets/empty-hd.img.gz b/assets/empty-hd.img.gz deleted file mode 100644 index 7ccbceb16f102226b1bd9dbeb5ae890fce2da331..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181960 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 MyL#QAL92f8ztdqnj{pDw diff --git a/scripts/ci b/scripts/ci index fb50b2cb..0a2d2382 100755 --- a/scripts/ci +++ b/scripts/ci @@ -9,4 +9,4 @@ fi docker build -t ros-build-base -f Dockerfile.build-base . docker build -t ros-build -f Dockerfile.build . -./scripts/docker-run.sh make -f Makefile.docker build-all +./scripts/docker-run.sh make -f Makefile.docker build-all integration-tests diff --git a/scripts/docker-run.sh b/scripts/docker-run.sh index c3bf3b8d..5a4c56d3 100755 --- a/scripts/docker-run.sh +++ b/scripts/docker-run.sh @@ -10,4 +10,4 @@ if [ -n "$BIND_DIR" ]; then fi docker rm -fv ros-build >/dev/null 2>&1 || true -exec docker run -i -v /var/run/docker.sock:/var/run/docker.sock $DOCKER_ARGS --name=ros-build ros-build "$@" +exec docker run --privileged -i -v /var/run/docker.sock:/var/run/docker.sock $DOCKER_ARGS --name=ros-build ros-build "$@" diff --git a/tests/integration/tox.ini b/tests/integration/tox.ini index ace164fb..28f44931 100644 --- a/tests/integration/tox.ini +++ b/tests/integration/tox.ini @@ -4,7 +4,7 @@ skipsdist=True [testenv] deps=-rrequirements.txt -commands=py.test --durations=20 rancherostest {posargs} +commands=py.test -s --durations=20 rancherostest {posargs} [testenv:flake8] deps=flake8 From 9a75fc101c90209d67836e260664225d73b52faa Mon Sep 17 00:00:00 2001 From: Ivan Mikushin Date: Fri, 4 Sep 2015 19:48:46 +0500 Subject: [PATCH 6/6] detect /dev/kvm or optionally force --privileged using PRIVILEGED=1 in ./scripts/docker-run.sh --- scripts/docker-run.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/docker-run.sh b/scripts/docker-run.sh index 5a4c56d3..4993ab9b 100755 --- a/scripts/docker-run.sh +++ b/scripts/docker-run.sh @@ -8,6 +8,9 @@ if [ -n "$BIND_DIR" ]; then fi DOCKER_ARGS="-t -v $BIND_DIR:/go/src/github.com/rancherio/os" fi +if [ -c /dev/kvm ] || [ "${PRIVILEGED}" == "1" ]; then + DOCKER_ARGS="${DOCKER_ARGS} --privileged" +fi docker rm -fv ros-build >/dev/null 2>&1 || true -exec docker run --privileged -i -v /var/run/docker.sock:/var/run/docker.sock $DOCKER_ARGS --name=ros-build ros-build "$@" +exec docker run -i -v /var/run/docker.sock:/var/run/docker.sock $DOCKER_ARGS --name=ros-build ros-build "$@"