-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
194 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
QGIS Docker images | ||
================== | ||
|
||
The QGIS project provides a few official docker images that can be | ||
used for testing purposes. | ||
|
||
These dockers are currently used to run continuous integration | ||
tests for the QGIS project itself and to run continuous integration | ||
tests for several third party Python plugins. | ||
|
||
The images are automatically built every day and pushed on docker hub | ||
to the QGIS account: https://hub.docker.com/r/qgis/ | ||
|
||
# Available images | ||
|
||
## Dependencies image | ||
|
||
`qgis/qgis3-build-deps` | ||
|
||
This is a simple base image that contains all the dependencies required to build | ||
QGIS, it is used by the other images. | ||
|
||
Multiple versions of this image may be available: the suffix in the image name indicates the Ubuntu version they are based on. | ||
|
||
## Main QGIS image | ||
|
||
`qgis/qgis` | ||
|
||
This is the main image containing a build of QGIS. | ||
|
||
|
||
### Features | ||
|
||
The docker file builds QGIS from the current directory | ||
sets up a testing environment and to run tests inside QGIS. | ||
|
||
You can use this docker to test QGIS or to run unit tests inside QGIS, | ||
`xvfb` (A fake X server) is available and running as a service inside the | ||
container to allow for fully automated headless testing in CI pipelines | ||
such as Travis or Circle-CI. | ||
|
||
### Building | ||
|
||
You can build the image from the main directory of the QGIS source tree with: | ||
|
||
``` | ||
$ docker build -t qgis/qgis:latest \ | ||
--build-arg DOCKER_TAG=latest \ | ||
-f .docker/qgis.dockerfile \ | ||
. | ||
``` | ||
|
||
The `DOCKER_TAG` argument, can be used to specify the tag of the dependencies image. | ||
|
||
|
||
### Running QGIS | ||
|
||
You can also use this image to run QGIS on your desktop. | ||
|
||
To run a QGIS container, assuming that you want to use your current | ||
display to use QGIS and the image is tagged `qgis/qgis:latest` you can use a script like the one here below: | ||
|
||
``` | ||
# Allow connections from any host | ||
$ xhost + | ||
$ docker run --rm -it --name qgis -v /tmp/.X11-unix:/tmp/.X11-unix \ | ||
-e DISPLAY=unix$DISPLAY qgis/qgis:latest qgis | ||
``` | ||
|
||
This code snippet will launch QGIS inside a container and display the | ||
application on your screen. | ||
|
||
### Running unit tests inside QGIS | ||
|
||
Suppose that you have local directory containing the tests you want to execute into QGIS: | ||
|
||
``` | ||
/my_tests/travis_tests/ | ||
├── __init__.py | ||
└── test_TravisTest.py | ||
``` | ||
|
||
To run the tests inside the container, you must mount the directory that | ||
contains the tests (e.g. your local directory `/my_tests`) into a volume | ||
that is accessible by the container, see `-v /my_tests/:/tests_directory` | ||
in the example below: | ||
|
||
``` | ||
$ docker run -d --name qgis -v /tmp/.X11-unix:/tmp/.X11-unix \ | ||
-v /my_tests/:/tests_directory \ | ||
-e DISPLAY=:99 \ | ||
qgis/qgis:latest | ||
``` | ||
|
||
|
||
When done, you can invoke the test runnner by specifying the test | ||
that you want to run, for instance: | ||
|
||
``` | ||
$ docker exec -it qgis sh -c "cd /tests_directory && qgis_testrunner.sh travis_tests.test_TravisTest.run_fail" | ||
``` | ||
|
||
The test can be specified by using a dotted notation, similar to Python | ||
import notation, by default the function named `run_all` will be executed | ||
but you can pass another function name as the last item in the dotted syntax: | ||
|
||
``` | ||
# Call the default function "run_all" inside test_TravisTest module | ||
qgis_testrunner.sh travis_tests.test_TravisTest | ||
# Call the function "run_fail" inside test_TravisTest module | ||
qgis_testrunner.sh travis_tests.test_TravisTest.run_fail | ||
``` | ||
|
||
Please note that in order to make the test script accessible to Python | ||
the calling command must ensure that the tests are in Python path. | ||
Common patterns are: | ||
- change directory to the one containing the tests (like in the examples above) | ||
- add to `PYTHONPATH` the directory contaning the tests | ||
|
||
#### Running tests for a Python plugin | ||
|
||
All the above considerations applies to this case too, however in order | ||
to simulate the installation of the plugin inside QGIS, you'll need to | ||
make an additional step: call `qgis_setup.sh <YourPluginName>` in the | ||
docker container before actually running the tests (see the paragraph | ||
about Running on Travis for a complete example). | ||
|
||
The `qgis_setup.sh` script prepares QGIS to run in headless mode and | ||
simulate the plugin installation process: | ||
|
||
- creates the QGIS profile folders | ||
- installs `startup.py` monkey patches to prevent blocking dialogs | ||
- enables the plugin | ||
|
||
#### Options for the test runner | ||
|
||
The env var `QGIS_EXTRA_OPTIONS` defaults to an empty string and can | ||
contains extra parameters that are passed to QGIS by the test runner. | ||
|
||
|
||
#### Running on Travis | ||
|
||
Here is a simple example for running unit tests of a small QGIS plugin (named *QuickWKT*), assuming that the tests are in `tests/test_Plugin.py` under | ||
the main directory of the QuickWKT plugin: | ||
|
||
``` | ||
services: | ||
- docker | ||
install: | ||
- docker run -d --name qgis-testing-environment -v ${TRAVIS_BUILD_DIR}:/tests_directory -e DISPLAY=:99 qgis/qgis:latest | ||
- sleep 10 # This is required to allow xvfb to start | ||
# Setup qgis and enables the plugin | ||
- docker exec -it qgis-testing-environment sh -c "qgis_setup.sh QuickWKT" | ||
# Additional steps (for example make or paver setup) here | ||
# Link the plugin to the tests_directory | ||
# (this mimicks the plugin download and installation process) | ||
- docker exec -it qgis-testing-environment sh -c "ln -s /tests_directory/ /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/QuickWKT" | ||
script: | ||
- docker exec -it qgis-testing-environment sh -c "cd /tests_directory &&qgis_testrunner.sh QuickWKT.tests.test_Plugin" | ||
``` | ||
|
||
Please note that `cd /tests_directory && ` before the call to `qgis_testrunner.sh` could be avoided here, because QGIS automatically | ||
adds the plugin main directory to Python path. | ||
|
||
|
||
#### Implementation notes | ||
|
||
The main goal of the test runner in this image is to execute unit tests | ||
inside a real instance of QGIS (not a mocked one). | ||
|
||
The QGIS tests should be runnable from a Travis/Circle-CI CI job. | ||
|
||
The implementation is: | ||
|
||
- run the docker, mounting as volumes the unit tests folder in `/tests_directory` | ||
(or the QGIS plugin folder if the unit tests belong to a plugin and the | ||
plugin is needed to run the tests) | ||
- execute `qgis_setup.sh MyPluginName` script in docker that sets up QGIS to | ||
avoid blocking modal dialogs and installs the plugin into QGIS if needed | ||
- create config and python plugin folders for QGIS | ||
- enable the plugin in the QGIS configuration file | ||
- install the `startup.py` script to disable python exception modal dialogs | ||
- execute the tests by running `qgis_testrunner.sh MyPluginName.tests.tests_MyTestModule.run_my_tests_function` | ||
- the output of the tests is captured by the `test_runner.sh` script and | ||
searched for `FAILED` (that is in the standard unit tests output) and other | ||
string that indicate a failure or success condition, if a failure condition | ||
is identified, the script exists with `1` otherwise it exits with `0`. | ||
|
||
`qgis_testrunner.sh` accepts a dotted notation path to the test module that | ||
can end with the function that has to be called inside the module to run the | ||
tests. The last part (`.run_my_tests_function`) can be omitted and defaults to | ||
`run_all`. |