1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. http://creativecommons.org/licenses/by/4.0
5 Preparing the Docker container
6 ------------------------------
8 Pull the Functest Docker image ('opnfv/functest') from the public dockerhub
9 registry under the OPNFV account: [dockerhub_], with the following docker
12 docker pull opnfv/functest:<TagIdentifier>
14 where <TagIdentifier> identifies a specifically tagged release of the Functest
15 docker container image in the public dockerhub registry. There are many
16 different tags created automatically by the CI mechanisms, but you must ensure
17 you pull an image with the **correct tag** to match the OPNFV software release
18 installed in your environment. All available tagged images can be seen from
19 location [FunctestDockerTags_]. For example, when running on the first official
20 release of the OPNFV Colorado system platform, tag "colorado.1.0" is needed.
21 Pulling other tags might cause some problems while running the tests. If you
22 need to specifically pull the latest Functest docker image, then omit the tag
26 docker pull opnfv/functest
28 After pulling the Docker image, check that the pulled image is available with
29 the following docker command::
31 [functester@jumphost ~]$ docker images
33 REPOSITORY TAG IMAGE ID CREATED SIZE
34 opnfv/functest latest 8cd6683c32ae 2 weeks ago 1.611 GB
35 opnfv/functest brahmaputra.3.0 94b78faa94f7 4 weeks ago 874.9 MB
36 hello-world latest 94df4f0ce8a4 7 weeks ago 967 B
38 (Docker images pulled without a tag specifier bear the implicitly
39 assigned label "latest", as seen above.)
41 The Functest docker container environment can -in principle- be also used with
42 non-OPNFV official installers (e.g. 'devstack), with the **disclaimer** that
43 support for such environments is outside of the scope of responsibility of the
46 The minimum command to create the Functest Docker container can be described as
49 docker run -it opnfv/functest:<TagIdentifier> /bin/bash
51 For OPNFV official installers, it is recommended (although no longer mandatory)
52 to provide two additional environment variables, in the 'docker run ...'
55 * **INSTALLER_TYPE** : possible values are **apex**, **compass**, **fuel** or
57 * **INSTALLER_IP** : IP of the installer node/VM.
59 Functest may need to know the IP of the installer to retrieve automatically the
60 credentials from the installer node/VM or even from the actual controllers.
62 Thus, the recommended minimum command to create the Functest Docker container
63 for OPNFV installer can be described (using installer 'fuel', and an invented
64 INSTALLER_IP of '10.20.0.2', for example), as follows::
67 -e "INSTALLER_IP=10.20.0.2" \
68 -e "INSTALLER_TYPE=fuel" \
69 opnfv/functest:<TagIdentifier> /bin/bash
71 Optionally, it is possible to assign precisely a container name through the
74 docker run --name "CONTAINER_NAME" -it \
75 -e "INSTALLER_IP=10.20.0.2" \
76 -e "INSTALLER_TYPE=fuel" \
77 opnfv/functest:<TagIdentifier> /bin/bash
79 It is also possible to to indicate the path of the OpenStack credentials using a
83 -e "INSTALLER_IP=10.20.0.2" \
84 -e "INSTALLER_TYPE=fuel" \
85 -v <path_to_your_local_creds_file>:/home/opnfv/functest/conf/openstack.creds \
86 opnfv/functest:<TagIdentifier> /bin/bash
88 NOTE: Make sure you have placed the needed credential file into the
89 Jumphost local path <path_to_your_local_cred_file>. For the
90 Apex Installer you will need to pre-copy the required OpenStack
91 credentials file from the Instack/Undercloud Virtual Machine.
92 See the section 'Apex Installer Tips' later in this document.
96 If you are using the Joid installer, you must use the method above
97 to provide the required OpenStack credentials. See the section
98 'Focus on the OpenStack credentials' later in this document.
101 The local openstack credential file will be mounted in the Docker container
102 under the path: '/home/opnfv/functest/conf/openstack.creds'
104 If the intention is to run Functest against any of the supported OPNFV
105 scenarios, it is recommended to include also the environment variable
106 **DEPLOY_SCENARIO**. The **DEPLOY_SCENARIO** environment variable is passed with the format::
108 -e "DEPLOY_SCENARIO=os-<controller>-<nfv_feature>-<ha_mode>"
111 os = OpenStack (No other VIM choices currently available)
112 controller is one of ( nosdn | odl_l2 | odl_l3 | onos | ocl )
113 nfv_feature is one or more of ( ovs | kvm | sfc | bgpvpn | nofeature )
114 If several features are pertinent then use the underscore
115 character '_' to separate each feature (e.g. ovs_kvm)
116 'nofeature' indicates no NFV feature is deployed
117 ha_mode is one of ( ha | noha )
122 -e "INSTALLER_IP=10.20.0.2" \
123 -e "INSTALLER_TYPE=fuel" \
124 -e "DEPLOY_SCENARIO=os-odl_l2-ovs_kvm-ha" \
125 opnfv/functest:<TagIdentifier> /bin/bash
127 **NOTE:** Not all possible combinations of "DEPLOY_SCENARIO" are supported.
128 The scenario name passed in to the Functest Docker container must match the
129 scenario used with the selected installer to create the actual OPNFV platform
132 Finally, three additional environment variables can also be passed in to the
133 Functest Docker Container, using the -e "<EnvironmentVariableName>=<Value>"
134 mechanism. The first two of these are only relevant to Jenkins CI invoked
135 testing and **should not be used** when performing manual test scenarios::
137 -e "NODE_NAME=<Test POD Name>" \
138 -e "BUILD_TAG=<Jenkins Build Tag>" \
139 -e "CI_DEBUG=<DebugTraceValue>"
142 <Test POD Name> = Symbolic name of the POD where the tests are run.
143 Visible in test results files, which are stored
144 to the database. This option is only used when
145 tests are activated under Jenkins CI control.
146 It indicates the POD/hardware where the test has
147 been run. If not specified, then the POD name is
148 defined as "Unknown" by default.
149 DO NOT USE THIS OPTION IN MANUAL TEST SCENARIOS.
151 <Jenkins Build tag> = Symbolic name of the Jenkins Build Job.
152 Visible in test results files, which are stored
153 to the database. This option is only set when
154 tests are activated under Jenkins CI control.
155 It enables the correlation of test results, which
156 are independently pushed to the results datbase
157 from different Jenkins jobs.
158 DO NOT USE THIS OPTION IN MANUAL TEST SCENARIOS.
160 <DebugTraceValue> = "true" or "false"
161 Default = "false", if not specified
162 If "true" is specified, then additional debug trace
163 text can be sent to the test results file / log files
164 and also to the standard console output.
168 Some specific tips are useful for the Apex Installer case. If not using Apex
169 Installer; ignore this section.
171 #. The "INSTALLER_IP" environment variable should be set equal to the IP
172 address of the so-called "Instack/undercloud Virtual Machine".
174 In the Jumphost, execute the following command and note the returned
177 sudo virsh domifaddr undercloud | grep -Eo "[0-9.]+{4}"
179 NOTE: In releases prior to Colorado, the name 'instack' was
180 used. From Colorado onward, the name 'undercloud' is used.
181 If in doubt, then execute -from the Jumphost- the command
182 "virsh list" to see which name is in use for the Installer
185 You can now enter the <Specific IP Address> as learned in the above step in the
186 -e option specification::
188 -e "INSTALLER_IP=<Specific IP Address>"
190 #. If you want to 'Bind mount' a local Openstack credentials file ("overcloudrc")
191 to the Docker container, then you may need to first pre-copy that file from the
192 'Instack/Undercloud VM' to the Jump host.
194 As before, in the Jumphost, execute the following command and note the
195 returned IP address::
197 sudo virsh domifaddr undercloud | grep -Eo "[0-9.]+{4}"
199 Using the <Specific IP Address> just learned above, execute the following
200 shell commands **in the Jumphost**, before issuing the 'docker run ...' command
203 scp stack@<Specific IP Address>:overcloudrc .
204 sed -i 's/export no_proxy/#export no_proxy/' overcloudrc
205 # The above 'sed' command is needed *only* in cases where
206 # the Jumphost is operating behind a http proxy.
207 # See the 'Proxy Support' section later on in this document
209 NOTE: There are two Openstack credential files present in the
210 Instack/Undercloud VM: 'overcloudrc' and 'stackrc'.
211 Don't mix these up! The file 'stackrc' is intended for use with
212 'Triple O Undercloud'; only. The SUT always requires OpenStack
213 Overcloud Credentials.
215 The file located at Jumphost path: '~/overcloudrc' is now 'Bind mounted'
216 to the Docker path '/home/opnfv/functest/conf/openstack.creds'
217 by specifying a **-v** option::
219 -v ~/overcloudrc:/home/opnfv/functest/conf/openstack.creds
221 in the argument list of the 'docker run ...' command invocation. In the
222 Apex installer case, the Openstack Credential file has the name
223 'overcloudrc' and is located in the home directory of the 'stack' user
224 ( '/home/stack/' or '~/'] ) in the 'Instack/Undercloud VM'.
226 #. In order that the docker container can access the Instack/Undercloud VM,
227 even with 'stack' user, the SSH keys of the Jumphost root user **must be**
228 'Bind mounted' to the docker container by the following **-v** option in
229 the 'docker run ...' command invocation::
231 -v /root/.ssh/id_rsa:/root/.ssh/id_rsa
233 #. Here is an example of the docker command invocation for an Apex installed
234 system, using latest Funtest docker container, for illustration purposes::
236 docker run -it --name "ApexFuncTstODL" \
237 -e "INSTALLER_IP=<Specific IP Address>" \
238 -e "INSTALLER_TYPE=apex" \
239 -e "DEPLOY_SCENARIO=os-odl_l2-nofeature-ha" \
240 -v /root/.ssh/id_rsa:/root/.ssh/id_rsa \
241 -v ~/overcloudrc:/home/opnfv/functest/conf/openstack.creds \
242 opnfv/functest /bin/bash
244 Functest docker container directory structure
245 ---------------------------------------------
246 Inside the Functest docker container, the following directory structure should
267 (The sub-directory 'ovno' holds SDN controller functional tests
268 for the OpenContrail SDN Controller, which should be available
269 for Colorado release)
271 Underneath the '/home/opnfv/' directory, the Functest docker container
272 includes two main directories:
274 * The **functest** directory stores configuration files (e.g. the OpenStack
275 creds are stored in path '/home/opnfv/functest/conf/openstack.creds'), the
276 **data** directory stores a 'cirros' test image used in some functional
277 tests and the **results** directory stores some temporary result log files
278 * The **repos** directory holds various repositories. The directory
279 '/home/opnfv/repos/functest' is used to prepare the needed Functest
280 environment and to run the tests. The other repository directories are
281 used for the installation of the needed tooling (e.g. rally) or for the
282 retrieval of feature projects scenarios (e.g. promise)
284 The structure under the **functest** repository can be described as follows::
292 | |-- config_functest.yaml
297 | |-- tier_builder.py
298 | `-- tier_handler.py
303 | |-- functest-complete.sh
308 | `--traffic-profile-guidelines.rst
311 | |-- config_install_env.sh
312 | `-- requirements.pip
330 |-- functest_logger.py
331 |-- functest_utils.py
332 |-- openstack_clean.py
333 |-- openstack_snapshot.py
334 `-- openstack_utils.py
336 (Note: All *.pyc files removed from above list for brevity...)
338 We may distinguish 7 different directories:
340 * **ci**: This directory contains test structure defintion files
341 (e.g <filename>.yaml) and bash shell/python scripts used to configure and
342 execute Functional tests. The test execution script can be executed under
343 the control of Jenkins CI jobs.
344 * **cli**: This directory holds the python based Functest CLI utility source
345 code, which is based on the Python 'click' framework.
346 * **commons**: This directory is dedicated for storage of traffic profile or
347 any other test inputs that could be reused by any test project.
348 * **docker**: This directory includes the needed files and tools to build the
349 Funtest Docker container image.
350 * **docs**: This directory includes documentation: Release Notes, User Guide,
351 Configuration Guide and Developer Guide. Test results are also located in
352 a sub--directory called 'results'.
353 * **testcases**: This directory includes the scripts required by Functest
354 internal test cases and other feature projects test cases.
355 * **utils**: this directory holds Python source code for some general purpose
356 helper utilities, which testers can also re-use in their own test code.
357 See for an example the Openstack helper utility: 'openstack_utils.py'.
359 After the *run* command, a new prompt appears which means that we are inside
360 the container and ready to move to the next step.
362 Useful Docker commands
363 ----------------------
364 When typing **exit** in the container prompt, this will cause exiting the
365 container and probably stopping it. When stopping a running Docker container
366 all the changes will be lost, there is a keyboard shortcut to quit the
367 container without stopping it: CTRL+P+Q. To reconnect to the running container
368 **DO NOT** use the *run* command again (since it will create a new container),
369 use the *exec* command instead::
371 docker ps <copy the container ID> docker exec -ti \
372 <CONTAINER_ID> /bin/bash
377 $(docker ps|grep functest|awk '{print $1}') /bin/bash
379 There are other useful Docker commands that might be needed to manage possible
380 issues with the containers.
382 List the running containers::
386 List all the containers including the stopped ones::
390 It is useful sometimes to remove a container if there are some problems::
392 docker rm <CONTAINER_ID>
394 Use the *-f* option if the container is still running, it will force to
397 docker -f rm <CONTAINER_ID>
399 The Docker image is called **opnfv/functest** and it is stored in the public
400 Docker registry under the OPNFV account: dockerhub_. The are many different
401 tags that have been created automatically by the CI mechanisms, but the one
402 that this document refers to is **brahmaputra.1.0**. Pulling other tags might
403 cause some problems while running the tests.
405 Check the Docker documentation dockerdocs_ for more information.
407 Preparing the Functest environment
408 ----------------------------------
409 Once the Functest docker container is up and running, the required Functest
410 environment needs to be prepared. A custom built **functest** CLI utility is
411 availabe to perform the needed environment preparation action. Once the
412 enviroment is prepared, the **functest** CLI utility can be used to run
413 different functional tests. The usage of the **functest** CLI utility to run
414 tests is described further in the Functest User Guide `OPNFV_FuncTestUserGuide`_
416 Prior to commencing the Functest environment preparation, we can check the
417 initial status of the environment. Issue the **functest env status** command at
421 Functest environment is not installed.
423 Note: When the Funtest environment is prepared, the command will
424 return the status: "Functest environment ready to run tests."
426 To prepare the Functest docker container for test case execution, issue the
427 **functest env prepare** command at the prompt::
431 This script will make sure that the requirements to run the tests are met and
432 will install the needed libraries and tools by all Functest test cases. It
433 should be run only once every time the Functest docker container is started
434 from scratch. If you try to run this command, on an already prepared
435 enviroment, you will be prompted whether you really want to continue or not::
438 It seems that the environment has been already prepared.
439 Do you want to do it again? [y|n]
441 (Type 'n' to abort the request, or 'y' to repeat the
442 environment preparation)
445 To list some basic information about an already prepared Functest docker
446 container environment, issue the **functest env show** at the prompt::
449 +======================================================+
450 | Functest Environment info |
451 +======================================================+
452 | INSTALLER: apex, 192.168.122.89 |
453 | SCENARIO: os-odl_l2-nofeature-ha |
455 | GIT BRANCH: master |
456 | GIT HASH: 5bf1647dec6860464eeb082b2875798f0759aa91 |
457 | DEBUG FLAG: false |
458 +------------------------------------------------------+
460 +------------------------------------------------------+
464 INSTALLER: Displays the INSTALLER_TYPE value
466 and the INSTALLER_IP value
467 - here = "192.168.122.89"
468 SCENARIO: Displays the DEPLOY_SCENARIO value
469 - here = "os-odl_l2-nofeature-ha"
470 POD: Displays the value pass in NODE_NAME
472 GIT BRANCH: Displays the git branch of the OPNFV Functest
473 project repository included in the Functest
476 (In first official colorado release
477 would be "colorado.1.0")
478 GIT HASH: Displays the git hash of the OPNFV Functest
479 project repository included in the Functest
481 - here = "5bf1647dec6860464eeb082b2875798f0759aa91"
482 DEBUG FLAG: Displays the CI_DEBUG value
485 NOTE: In Jenkins CI runs, an additional item "BUILD TAG"
486 would also be listed. The valaue is set by Jenkins CI.
488 Finally, the **functest** CLI has a basic 'help' system with so called
493 functest --help Usage: functest [OPTIONS] COMMAND [ARGS]...
496 --version Show the version and exit.
497 -h, --help Show this message and exit.
506 Usage: functest env [OPTIONS] COMMAND [ARGS]...
509 -h, --help Show this message and exit.
512 prepare Prepares the Functest environment.
513 show Shows information about the current...
514 status Checks if the Functest environment is ready...
516 Focus on the OpenStack credentials
517 ----------------------------------
518 The OpenStack credentials are needed to run the tests against the VIM.
519 There are 3 ways to provide them to Functest:
521 * using the -v option when running the Docker container
522 * create an empty file in '/home/opnfv/functest/conf/openstack.creds' and
523 paste the credentials into it. (Consult your installer guide to know from
524 where you can retrieve credential files, which are set-up in the Openstack
525 installation of the SUT)
526 * automatically retrieved using the following script::
528 $repos_dir/releng/utils/fetch_os_creds.sh \
529 -d /home/opnfv/functest/conf/openstack.creds \
533 (-d specifies the full destination path where to place the
534 copied Openstack credential file
535 -i specifies the INSTALLER_TYPE
536 -a specifies the INSTALLER_IP
537 If the installer is of type "fuel" and a Virtualized
538 deployment is used, then this should be indicated by
539 adding an option '-v'. The -v option takes no arguments.
540 It enables some needed special handling in the script.)
542 Note: If you omit the -d <full destination path> option in
543 the command invocation, then the script will create the
544 credential file with name 'opnfv-openrc.sh' in directory
545 '/home/opnfv'. In that case, you need to copy/edit the file
546 into the correct target path:
547 '/home/opnfv/functest/conf/openstack.creds'.
549 **Warning** If you are using the Joid installer, the 'fetch_os_cred-sh' shell
550 script **should not be used**. Use instead, the **-v** optin to Bind Mount a
551 suitably prepared local copy of the Openstack credentials for usage by the Functest
554 Once the credentials are there, they should be sourced **before** running the
557 source /home/opnfv/functest/conf/openstack.creds
559 or simply using the environment variable **creds**::
563 After this, try to run any OpenStack command to see if you get any output, for
568 This will return a list of the actual users in the OpenStack deployment. In any
569 other case, check that the credentials are sourced::
573 This command must show a set of environment variables starting with *OS_*, for
576 OS_REGION_NAME=RegionOne
577 OS_DEFAULT_DOMAIN=default
578 OS_PROJECT_NAME=admin
580 OS_AUTH_STRATEGY=keystone
581 OS_AUTH_URL=http://172.30.10.3:5000/v2.0
584 OS_ENDPOINT_TYPE=internalURL
587 If the OpenStack command still does not show anything or complains about
588 connectivity issues, it could be due to an incorrect url given to the
589 OS_AUTH_URL environment variable. Check the deployment settings.
593 If you need to connect to a server that is TLS-enabled (the auth URL begins
594 with ‘https’) and it uses a certificate from a private CA or a self-signed
595 certificate, then you will need to specify the path to an appropriate CA
596 certificate to use, to validate the server certificate with the environment
600 /etc/ssl/certs/ca.crt
602 However, this certificate does not exist in the container by default. It has
603 to be copied manually from the OpenStack deployment. This can be done in 2 ways:
605 #. Create manually that file and copy the contents from the OpenStack
607 #. (Recommended) Add the file using a Docker volume when starting the
610 -v <path_to_your_cert_file>:/etc/ssl/certs/ca.cert
612 You might need to export OS_CACERT environment variable inside the container::
614 export OS_CACERT=/etc/ssl/certs/ca.crt
616 Certificate verification can be turned off using OS_INSECURE=true. For example,
617 Fuel uses self-signed cacerts by default, so an pre step would be::
619 export OS_INSECURE=true
623 If your Jumphost node is operating behind a http proxy, then there are 2 places
624 where some special actions may be needed to make operations succeed:
626 #. Initial installation of docker engine First, try following the official
627 Docker documentation for Proxy_ settings. Some issues were experienced on
628 CentOS 7 based Jumphost. Some tips are documented in section:
629 `Docker Installation on CentOS 7 behind http proxy`_ below.
631 #. Execution of the Functest environment preparation inside the created
632 docker container Functest needs internet access to download some resources
633 for some test cases. For example to install the Rally environment. This might
634 not work properly if the Jumphost is running through a http Proxy.
636 If that is the case, make sure the resolv.conf and the needed http_proxy and
637 https_proxy environment variables, as well as the 'no_proxy' environment
638 variable are set correctly::
640 # Make double sure that the 'no_proxy=...' line in the
641 # 'openstack.creds' file is commented out first. Otherwise, the
642 # values set into the 'no_proxy' environment variable below will
643 # be ovewrwritten, each time the command
644 # 'source ~/functest/conf/openstack.creds' is issued.
646 sed -i 's/export no_proxy/#export no_proxy/' \
647 ~/functest/conf/openstack.creds
649 source ~/functest/conf/openstack.creds
651 # Next calculate some IP addresses for which http_proxy
652 # usage should be excluded:
654 publicURL_IP=$(echo $OS_AUTH_URL| \
655 grep -Eo "([0-9]+\.){3}[0-9]+")
657 adminURL_IP=$(openstack catalog show identity | \
658 grep adminURL | grep -Eo "([0-9]+\.){3}[0-9]+")
660 export http_proxy="<your http proxy settings>"
661 export https_proxy="<your httpsproxy settings>"
662 export no_proxy="127.0.0.1,localhost,$publicURL_IP,$adminURL_IP"
664 # Ensure that "git" uses the http_proxy
665 # This may be needed if your firewall forbids SSL based git fetch
666 git config --global http.sslVerify True
667 git config --global http.proxy <Your http proxy settings>
669 Validation check: Before running **'functest env prepare'** CLI command,
670 make sure you can reach http and https sites from inside the Functest docker
673 For example, try to use the **nc** command from inside the functest docker
677 Connection to google.com 80 port [tcp/http] succeeded!
680 Connection to google.com 443 port [tcp/https] succeeded!
682 Note: In a Jumphost node based on the CentOS 7, enviroment, it was observed that
683 the **nc** commands did not function as described in the section above. You can
684 however try using the **curl** command instead, if you encounter any issues
685 with the **nc** command::
687 curl http://www.google.com:80
689 <HTML><HEAD><meta http-equiv="content-type"
690 content="text/html;charset=utf-8">
691 <TITLE>302 Moved</TITLE>
699 curl https://www.google.com:443
701 <HTML><HEAD><meta http-equiv="content-type"
702 content="text/html;charset=utf-8">
703 <TITLE>302 Moved</TITLE>
711 (Even Google complained the URL used, it proves the http and https
712 protocols are working correctly through the http / https proxy.)
714 Docker Installation on CentOS 7 behind http proxy
715 -------------------------------------------------
716 There are good instructions in [`InstallDockerCentOS7`_] for the installation
717 of **docker** on CentOS 7. However, if your Jumphost is behind a http proxy,
718 then the following steps are needed **before** following the instructions in
719 the above reference::
721 1) # Make a directory '/etc/systemd/system/docker.service.d'
722 # if it does not exist
723 sudo mkdir /etc/systemd/system/docker.service.d
725 # Create a file called 'env.conf' in that directory with
726 # the following contents:
728 EnvironmentFile=-/etc/sysconfig/docker
730 2) # Set up a file called 'docker' in directory '/etc/sysconfig'
731 # with the following contents:
733 HTTP_PROXY="<Your http proxy settings>"
734 HTTPS_PROXY="<Your https proxy settings>"
735 http_proxy="${HTTP_PROXY}"
736 https_proxy="${HTTPS_PROXY}"
738 3) # Reload the daemon
739 systemctl daemon-reload
741 4) # Sanity check - check the following docker settings:
742 systemctl show docker | grep -i env
746 EnvironmentFile=/etc/sysconfig/docker (ignore_errors=yes)
747 DropInPaths=/etc/systemd/system/docker.service.d/env.conf
749 Now follow the instructions in [`InstallDockerCentOS7`_] to download and
750 install the **docker-engine**. The instructions conclude with a "test pull"
751 of a sample "Hello World" docker container. This should now work with the
752 above pre-requisite actions.
754 .. _dockerdocs: https://docs.docker.com/
755 .. _dockerhub: https://hub.docker.com/r/opnfv/functest/
756 .. _Proxy: https://docs.docker.com/engine/admin/systemd/#http-proxy
757 .. _FunctestDockerTags: https://hub.docker.com/r/opnfv/functest/tags/
758 .. _InstallDockerCentOS7: https://docs.docker.com/engine/installation/linux/centos/
759 .. _OPNFV_FuncTestUserGuide: http://artifacts.opnfv.org/functest/docs/userguide/index.html