From beab266977c858950bfaa5c2c0d624cb6730f1bc Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Tue, 27 Nov 2018 22:04:02 +0100 Subject: Docker-based test servers for network-related Qt autotests on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no docker bridge on Windows. Docker document recommends using port mapping to connect to a container. The problem is that it causes a port conflict if the user is running a service that binds the same port on the host. This change applies the same solution of macOS to deploy the docker environment into VirtualBox and use the host network option. Task-number: QTQAINFRA-2294 Change-Id: Iedcb8daa39373f02adb59f02eae2775f02870c54 Reviewed-by: Jędrzej Nowacki Reviewed-by: Edward Welbourne --- tests/auto/testserver.pri | 79 +++++++++++++++----- tests/testserver/apache2/.gitattributes | 2 + tests/testserver/common/.gitattributes | 2 + tests/testserver/common/startup.sh | 4 +- tests/testserver/danted/.gitattributes | 2 + tests/testserver/docker-compose-for-windows.yml | 99 +++++++++++++++++++++++++ tests/testserver/ftp-proxy/.gitattributes | 2 + tests/testserver/squid/.gitattributes | 2 + tests/testserver/vsftpd/.gitattributes | 2 + 9 files changed, 175 insertions(+), 19 deletions(-) create mode 100644 tests/testserver/apache2/.gitattributes create mode 100644 tests/testserver/common/.gitattributes create mode 100644 tests/testserver/danted/.gitattributes create mode 100644 tests/testserver/docker-compose-for-windows.yml create mode 100644 tests/testserver/ftp-proxy/.gitattributes create mode 100644 tests/testserver/squid/.gitattributes create mode 100644 tests/testserver/vsftpd/.gitattributes (limited to 'tests') diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index 1a8b5a8187..735b5d4d90 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -58,11 +58,12 @@ debug_and_release:!build_pass: return() TESTSERVER_VERSION = $$system(docker-compose --version) -equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { +isEmpty(TESTSERVER_VERSION) { # Make check with server "qt-test-server.qt-test-net" as a fallback - message("testserver: qt-test-server.qt-test-net") } else { - # Make check with test servers + # Make check with docker test servers + DNSDOMAIN = test-net.qt.local + equals(QMAKE_HOST.os, Darwin) { # There is no docker bridge on macOS. It is impossible to ping a container. # Docker docs recommends using port mapping to connect to a container; @@ -77,44 +78,85 @@ equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { # The environment variables passed to the docker-compose file TEST_ENV = 'MACHINE_IP=$(shell docker-machine ip qt-test-server)' + TEST_ENV += 'TEST_DOMAIN=$$DNSDOMAIN' + TEST_CMD = env + } else:equals(QMAKE_HOST.os, Windows) { + # There is no docker bridge on Windows. It is impossible to ping a container. + # Use docker-machine to deploy the docker environment into VirtualBox. + TESTSERVER_COMPOSE_FILE = \ + $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose-for-windows.yml + + # Bonjour only works within a single broadcast domain. + DNSDOMAIN = local + + # The connection configuration for the target machine + MACHINE_CONFIG = (docker-machine config qt-test-server) + + # The environment variables passed to the docker-compose file + TEST_ENV = '\$\$env:MACHINE_IP = docker-machine ip qt-test-server;' + TEST_ENV += '\$\$env:TEST_DOMAIN = $$shell_quote(\"$$DNSDOMAIN\");' + TEST_CMD = 'PowerShell -noprofile' + CONFIG += PowerShell } else { TESTSERVER_COMPOSE_FILE = $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml DEFINES += QT_TEST_SERVER_NAME } + # The domain name is relevant to https keycert (qnetworkreply/crts/qt-test-net-cacert.pem). + DEFINES += QT_TEST_SERVER QT_TEST_SERVER_DOMAIN=$$shell_quote(\"$${DNSDOMAIN}\") + # Ensure that the docker-compose file is provided. It is a configuration # file which is mandatory for all docker-compose commands. You can get more # detail from the description of TESTSERVER_COMPOSE_FILE above. There is # also an example showing how to configure it manually. FILE_PRETEST_MSG = "Project variable 'TESTSERVER_COMPOSE_FILE' is not set" - testserver_pretest.commands = $(info "testserver:" $$TESTSERVER_VERSION) - testserver_pretest.commands += $(if $$TESTSERVER_COMPOSE_FILE,,$(error $$FILE_PRETEST_MSG)) + PowerShell { + testserver_pretest.commands = echo $$TESTSERVER_VERSION && + testserver_pretest.commands += \ + $$TEST_CMD if ([String]::IsNullOrEmpty($$shell_quote(\"$$TESTSERVER_COMPOSE_FILE\"))) \ + {Write-Error $$shell_quote(\"$$FILE_PRETEST_MSG\")} && + } else { + testserver_pretest.commands = $(info "testserver:" $$TESTSERVER_VERSION) + testserver_pretest.commands += $(if $$TESTSERVER_COMPOSE_FILE,,$(error $$FILE_PRETEST_MSG)) + } # Make sure docker-machine is both created and running. The docker_machine # script is used to deploy the docker environment into VirtualBox. # Example: qt5/coin/provisioning/common/shared/testserver/docker_machine.sh !isEmpty(MACHINE_CONFIG) { - MACHINE_LIST_CMD = docker-machine ls -q --filter "Name=^qt-test-server$" + MACHINE_LIST_CMD = docker-machine ls -q --filter "Name=^qt-test-server\$\$" MACHINE_LIST_MSG = "Docker machine qt-test-server not found" - testserver_pretest.commands += \ - $(if $(shell $$MACHINE_LIST_CMD),,$(error $$MACHINE_LIST_MSG)) + PowerShell { + testserver_pretest.commands += $$TEST_CMD if (!($$MACHINE_LIST_CMD)) \ + {Write-Error $$shell_quote(\"$$MACHINE_LIST_MSG\")} && + } else { + testserver_pretest.commands += \ + $(if $(shell $$MACHINE_LIST_CMD),,$(error $$MACHINE_LIST_MSG)) + } MACHINE_STATE_CMD = \ - docker-machine ls -q --filter "State=Running" --filter "Name=^qt-test-server$" + docker-machine ls -q --filter "State=Running" --filter "Name=^qt-test-server\$\$" MACHINE_START_CMD = docker-machine start qt-test-server - testserver_pretest.commands += \ - $(if $(shell $$MACHINE_STATE_CMD),,$(shell $$MACHINE_START_CMD > /dev/null)) + PowerShell { + testserver_pretest.commands += \ + $$TEST_CMD if (!($$MACHINE_STATE_CMD)) {$$MACHINE_START_CMD} && + } else { + testserver_pretest.commands += \ + $(if $(shell $$MACHINE_STATE_CMD),,$(shell $$MACHINE_START_CMD > /dev/null)) + } } # Before starting the test servers, it requires the user to run the setup # script (coin/provisioning/.../testserver/docker_testserver.sh) in advance. IMAGE_PRETEST_CMD = docker $$MACHINE_CONFIG images -aq "qt-test-server-*" IMAGE_PRETEST_MSG = "Docker image qt-test-server-* not found" - testserver_pretest.commands += $(if $(shell $$IMAGE_PRETEST_CMD),,$(error $$IMAGE_PRETEST_MSG)) - - # The domain name is relevant to https keycert (qnetworkreply/crts/qt-test-net-cacert.pem). - DNSDOMAIN = test-net.qt.local - DEFINES += QT_TEST_SERVER QT_TEST_SERVER_DOMAIN=$$shell_quote(\"$${DNSDOMAIN}\") + PowerShell { + testserver_pretest.commands += $$TEST_CMD if (!($$IMAGE_PRETEST_CMD)) \ + {Write-Error $$shell_quote(\"$$IMAGE_PRETEST_MSG\")} + } else { + testserver_pretest.commands += \ + $(if $(shell $$IMAGE_PRETEST_CMD),,$(error $$IMAGE_PRETEST_MSG)) + } # Rename the check target of testcase feature check.target = check_network @@ -124,14 +166,15 @@ equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { testserver_test.depends = testserver_pretest # Bring up test servers and make sure the services are ready. - !isEmpty(TEST_ENV): testserver_test.commands = env $$TEST_ENV + !isEmpty(TEST_CMD): testserver_test.commands = $$TEST_CMD $$TEST_ENV testserver_test.commands += docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE up \ --detach --force-recreate --timeout 1 $${QT_TEST_SERVER_LIST} && # Check test cases with docker-based test servers. - testserver_test.commands += $(MAKE) -f $(MAKEFILE) check_network; + testserver_test.commands += $(MAKE) -f $(MAKEFILE) check_network && # Stop and remove test servers after testing. + !isEmpty(TEST_CMD): testserver_test.commands += $$TEST_CMD $$TEST_ENV testserver_test.commands += docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE down \ --timeout 1 diff --git a/tests/testserver/apache2/.gitattributes b/tests/testserver/apache2/.gitattributes new file mode 100644 index 0000000000..67af4c73e8 --- /dev/null +++ b/tests/testserver/apache2/.gitattributes @@ -0,0 +1,2 @@ +* text eol=lf +*.gif -text diff --git a/tests/testserver/common/.gitattributes b/tests/testserver/common/.gitattributes new file mode 100644 index 0000000000..21f6efbe14 --- /dev/null +++ b/tests/testserver/common/.gitattributes @@ -0,0 +1,2 @@ +*.sh text eol=lf +*.conf text eol=lf diff --git a/tests/testserver/common/startup.sh b/tests/testserver/common/startup.sh index 84d4003f86..74990a47f6 100755 --- a/tests/testserver/common/startup.sh +++ b/tests/testserver/common/startup.sh @@ -49,7 +49,9 @@ do $RUN_CMD done # start multicast DNS service discovery (mDNS) -sed -i "s,#domain-name=local,domain-name=test-net.qt.local," /etc/avahi/avahi-daemon.conf +sed -i -e "s,#domain-name=local,domain-name=${test_domain:-test-net.qt.local}," \ + -e "s,#publish-aaaa-on-ipv4=yes,publish-aaaa-on-ipv4=no," \ + /etc/avahi/avahi-daemon.conf service dbus restart service avahi-daemon restart diff --git a/tests/testserver/danted/.gitattributes b/tests/testserver/danted/.gitattributes new file mode 100644 index 0000000000..21f6efbe14 --- /dev/null +++ b/tests/testserver/danted/.gitattributes @@ -0,0 +1,2 @@ +*.sh text eol=lf +*.conf text eol=lf diff --git a/tests/testserver/docker-compose-for-windows.yml b/tests/testserver/docker-compose-for-windows.yml new file mode 100644 index 0000000000..07da5bcc70 --- /dev/null +++ b/tests/testserver/docker-compose-for-windows.yml @@ -0,0 +1,99 @@ +version: '3.4' + +# The tag of images is used by docker compose file to launch the corresponding +# docker containers. The value of tag comes from the provisioning script +# (coin/provisioning/.../testserver/docker_testserver.sh). The script gets SHA-1 +# of each server context as the tag of docker images. If one of the server +# contexts gets changes, please make sure to update this compose file as well. +# You can run command 'docker images' to list all the tags of test server images. +# For example: +# REPOSITORY TAG +# qt-test-server-apache2 537fe302f61851d1663f41495230d8e3554a4a13 + +services: + apache2: + image: qt-test-server-apache2:537fe302f61851d1663f41495230d8e3554a4a13 + container_name: qt-test-server-apache2 + domainname: ${TEST_DOMAIN} + volumes: + - ./common:/common:ro + - ./apache2:/service:ro + entrypoint: common/startup.sh + command: [common/ssl.sh, service/apache2.sh] + network_mode: "host" + extra_hosts: + - "qt-test-server.${TEST_DOMAIN}:${MACHINE_IP}" + environment: + - test_domain=${TEST_DOMAIN} + + squid: + image: qt-test-server-squid:9c32f41b19aca3d778733c4d8fb0ecc5955e893c + container_name: qt-test-server-squid + domainname: ${TEST_DOMAIN} + depends_on: + - apache2 + volumes: + - ./common:/common:ro + - ./squid:/service:ro + entrypoint: common/startup.sh + command: service/squid.sh + network_mode: "host" + extra_hosts: + - "qt-test-server.${TEST_DOMAIN}:${MACHINE_IP}" + environment: + - test_domain=${TEST_DOMAIN} + + vsftpd: + image: qt-test-server-vsftpd:f3a9c8d793a77cc007c0e4e481bec01f9e3eeb7e + container_name: qt-test-server-vsftpd + domainname: ${TEST_DOMAIN} + volumes: + - ./common:/common:ro + - ./vsftpd:/service:ro + entrypoint: common/startup.sh + command: service/vsftpd.sh + network_mode: "host" + extra_hosts: + - "qt-test-server.${TEST_DOMAIN}:${MACHINE_IP}" + environment: + - test_domain=${TEST_DOMAIN} + + ftp-proxy: + image: qt-test-server-ftp-proxy:d7de8b28392d173db512a558ccc84ead8bece2ae + container_name: qt-test-server-ftp-proxy + domainname: ${TEST_DOMAIN} + depends_on: + - vsftpd + volumes: + - ./common:/common:ro + - ./ftp-proxy:/service:ro + entrypoint: common/startup.sh + command: service/ftp-proxy.sh + network_mode: "host" + extra_hosts: + - "qt-test-server.${TEST_DOMAIN}:${MACHINE_IP}" + environment: + - test_domain=${TEST_DOMAIN} + + danted: + image: qt-test-server-danted:35607f9b790524cf9690c7d12a9a401696b7b6b5 + container_name: qt-test-server-danted + domainname: ${TEST_DOMAIN} + depends_on: + - apache2 + - vsftpd + - ftp-proxy + volumes: + - ./common:/common:ro + - ./danted:/service:ro + entrypoint: common/startup.sh + command: service/danted.sh + network_mode: "host" + extra_hosts: + - "qt-test-server.${TEST_DOMAIN}:${MACHINE_IP}" + environment: + - danted_internal=${MACHINE_IP:-eth0} + - danted_external=${MACHINE_IP:-eth0} + - danted_auth_internal=${MACHINE_IP:-eth0} + - danted_auth_external=${MACHINE_IP:-eth0} + - test_domain=${TEST_DOMAIN} diff --git a/tests/testserver/ftp-proxy/.gitattributes b/tests/testserver/ftp-proxy/.gitattributes new file mode 100644 index 0000000000..21f6efbe14 --- /dev/null +++ b/tests/testserver/ftp-proxy/.gitattributes @@ -0,0 +1,2 @@ +*.sh text eol=lf +*.conf text eol=lf diff --git a/tests/testserver/squid/.gitattributes b/tests/testserver/squid/.gitattributes new file mode 100644 index 0000000000..21f6efbe14 --- /dev/null +++ b/tests/testserver/squid/.gitattributes @@ -0,0 +1,2 @@ +*.sh text eol=lf +*.conf text eol=lf diff --git a/tests/testserver/vsftpd/.gitattributes b/tests/testserver/vsftpd/.gitattributes new file mode 100644 index 0000000000..67af4c73e8 --- /dev/null +++ b/tests/testserver/vsftpd/.gitattributes @@ -0,0 +1,2 @@ +* text eol=lf +*.gif -text -- cgit v1.2.3