summaryrefslogtreecommitdiffstats
path: root/tests/auto/testserver.pri
blob: 7dd32db0af166ae805602d45449b15809f85e0d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Integrating docker-based test servers into Qt Test framework
#
# This file adds support for docker-based test servers built by testcase
# projects that need them. To enable this feature, any automated test can
# include testserver.pri in its project file. This instructs qmake to insert
# additional targets into the generated Makefile. The 'check' target then brings
# up test servers before running the testcase, and shuts them down afterwards.
#
# TESTSERVER_COMPOSE_FILE
# - Contains the path of docker-compose file
# This configuration file defines the services used for autotests. It tells the
# docker engine how to build up the docker images and containers. In qtbase, a
# shared docker-compose file is located in the tests folder.
# Example: TESTSERVER_COMPOSE_FILE = \
#              $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml
#
# The user must run the provisioning scripts in advance before attempting to
# build the test servers. The docker_testserver.sh script is used to build up
# the docker images into the docker-cache. It handles the immutable parts of the
# server installation that rarely need adjustment, such as downloading packages.
# Example: qt5/coin/provisioning/.../testserver/docker_testserver.sh
#
# QT_TEST_SERVER_LIST
# - A list of test servers to bring up for this testcase
# These test servers should be defined in $$TESTSERVER_COMPOSE_FILE. Each
# testcase can define the test servers it depends on.
# Example: QT_TEST_SERVER_LIST = apache2 squid vsftpd ftp-proxy danted
#
# Pre-processor defines needed for the application:
# QT_TEST_SERVER
# - A preprocessor macro used for testcase to change testing parameters at
#   compile time
# This macro is predefined for docker-based test servers and is passed as a
# compiler option (-DQT_TEST_SERVER). The testcase can then check whether
# docker-based servers are in use and change the testing parameters, such as
# host name or port number, at compile time. An example can be found in
# network-settings.h.
#
# Example:
# #if defined(QT_TEST_SERVER)
#     Change the testing parameters at compile time
# #endif
#
# QT_TEST_SERVER_DOMAIN
# - A preprocessor macro that holds the server domain name
# Provided for the helper functions in network-settings.h. Use function
# serverDomainName() in your application instead.
#
# Additional make targets:
# 1. check_network - A renamed target from the check target of testcase feature.
# 2. testserver_clean - Clean up server containers/images and tidy away related
#    files.

TESTSERVER_VERSION = $$system(docker-compose --version)

equals(QMAKE_HOST.os, Windows)|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
    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;
        # but it causes a port conflict if the user is running a service that
        # binds the same port on the host. An alternative solution is to deploy
        # the docker environment into VirtualBox using docker-machine.
        TESTSERVER_COMPOSE_FILE = \
            $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose-for-macOS.yml

        # The connection configuration for the target machine
        MACHINE_CONFIG = $(shell docker-machine config qt-test-server)

        # The environment variables passed to the docker-compose file
        TEST_ENV = 'MACHINE_IP=$(shell docker-machine ip qt-test-server)'
    } else {
        TESTSERVER_COMPOSE_FILE = $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml
        DEFINES += QT_TEST_SERVER_NAME
    }

    # 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))

    # 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_MSG = "Docker machine qt-test-server not found"
        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$"
        MACHINE_START_CMD = docker-machine start qt-test-server
        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}\")

    # Rename the check target of testcase feature
    check.target = check_network
    testserver_test.target = check

    # Pretesting test servers environment
    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
    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) check_network;

    # Stop and remove test servers after testing.
    testserver_test.commands += docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE down \
                                --timeout 1

    # Destroy test servers and tidy away related files.
    testserver_clean.commands = docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE down \
                                --rmi all

    QMAKE_EXTRA_TARGETS += testserver_pretest testserver_test testserver_clean
}