Commit ace98fca authored by ale's avatar ale
Browse files

Merge branch 'tests' into 'master'

Add CI testing of changes

See merge request !123
parents fca6c8a3 0d16949b
Pipeline #15318 passed with stages
in 11 minutes and 18 seconds
image: registry.git.autistici.org/ai3/docker/float-runner:master
# Stage the tests sequentially to avoid overloading the test VM server.
stages:
- docker_build
- test_mail
- test_noblogs
- test_web
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
BUILD_DIR: "$CI_PROJECT_DIR/build-$CI_JOB_ID"
docker_build_and_release_tests:
stage: docker_build
......@@ -16,6 +21,53 @@ docker_build_and_release_tests:
- cd test && docker build --build-arg ci_token=$CI_JOB_TOKEN --pull -t $IMAGE_TAG .
- docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:integration-test
- docker push $CI_REGISTRY_IMAGE:integration-test
only:
changes:
- test/**/*
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
changes:
- test/**/*
.base_test_template: &base_test
image: registry.git.autistici.org/ai3/docker/float-runner:bullseye
before_script:
- mkdir -p $BUILD_DIR
script:
- ./test/mkenv ./test/env/$TEST_NAME $BUILD_DIR
- with-ssh-key $BUILD_DIR/float/scripts/floatup.py ${LIBVIRT:+--ssh $LIBVIRT} --inventory $BUILD_DIR/hosts.yml --ram 3072 --image ${VM_IMAGE:-buster} up
- with-ssh-key env TESTDATA_DIR=$BUILD_DIR/testdata $BUILD_DIR/float/test-driver init --no-vagrant $BUILD_DIR
- sleep 30
- with-ssh-key $BUILD_DIR/float/test-driver run $BUILD_DIR $PWD/playbooks/ai3-test-docker.yml
after_script:
- with-ssh-key $BUILD_DIR/float/test-driver cleanup --no-vagrant $BUILD_DIR
- with-ssh-key $BUILD_DIR/float/scripts/floatup.py ${LIBVIRT:+--ssh ${LIBVIRT}} down
tags: [ai3]
artifacts:
when: on_failure
expire_in: 1 week
name: "${CI_JOB_NAME}_${CI_COMMIT_REF_SLUG}_${CI_COMMIT_SHORT_SHA}"
paths:
- "${BUILD_DIR}/ansible.log"
- "${BUILD_DIR}/logs"
test_mail:
<<: *base_test
stage: test_mail
variables:
TEST_NAME: "mail"
test_noblogs:
<<: *base_test
stage: test_noblogs
variables:
TEST_NAME: "noblogs"
rules:
- changes:
- roles/noblogs/**/*
test_web:
<<: *base_test
stage: test_web
variables:
TEST_NAME: "web"
rules:
- changes:
- roles/web-users/**/*
......@@ -10,14 +10,9 @@
content: "{{ vars|to_nice_yaml }}"
- name: Setup test Docker image
docker_image:
name: registry.git.autistici.org/ai3/config:integration-test
force: true
when: "float_debian_dist == 'stretch'"
- name: Setup test Docker image
command: "podman pull registry.git.autistici.org/ai3/config:integration-test"
when: "float_debian_dist != 'stretch'"
command: "float-pull-image registry.git.autistici.org/ai3/config:integration-test"
register: test_container_image
failed_when: "test_container_image.rc not in [0, 42]"
- name: Run tests
command: docker run --net host --mount type=bind,source=/tmp/test-config.yml,destination=/test-config.yml registry.git.autistici.org/ai3/config:integration-test
command: "docker run --rm --net host --mount type=bind,source=/tmp/test-config.yml,destination=/test-config.yml registry.git.autistici.org/ai3/config:integration-test"
......@@ -5,24 +5,48 @@
roles:
- testdata-ldap
vars:
testdata_dir: "{{ playbook_dir }}/../../testdata"
testdata_dir: "{{ lookup('env', 'TESTDATA_DIR') | default(playbook_dir + '/../../testdata', True) }}"
- hosts: web-users
gather_facts: no
roles:
- testdata-web-users
vars:
testdata_dir: "{{ playbook_dir }}/../../testdata"
testdata_dir: "{{ lookup('env', 'TESTDATA_DIR') | default(playbook_dir + '/../../testdata', True) }}"
- hosts: noblogs
gather_facts: no
roles:
- testdata-noblogs
vars:
testdata_dir: "{{ playbook_dir }}/../../testdata"
testdata_dir: "{{ lookup('env', 'TESTDATA_DIR') | default(playbook_dir + '/../../testdata', True) }}"
# Run the automation scripts that generate configurations.
- hosts: frontend
gather_facts: no
tasks:
- name: Configure account-automation frontend
command: /opt/ai/scripts/config-nginx
command: "/opt/ai/scripts/{{ item }}"
loop:
- config-nginx
- config-dns
- hosts: mail-frontend
gather_facts: no
tasks:
- name: Configure account-automation mail frontend
command: "/opt/ai/scripts/{{ item }}"
loop:
- config-mail-domains
- config-mailman
- config-opendkim
- hosts: backend
gather_facts: no
tasks:
- name: Configure account-automation backend
command: "/opt/ai/scripts/{{ item }}"
loop:
- create-websites
- config-apache-instances
- config-homedir-map
......@@ -128,7 +128,9 @@
loop: "{{ sieve_filters | zip(dovecot_sieve_scripts.results) | list }}"
rescue:
- name: Reload Dovecot
command: "systemctl reload dovecot"
systemd:
name: dovecot.service
state: restarted
- name: Compile the default sieve filters
shell: "env HOME=/tmp sievec /var/lib/dovecot/sieve/{{ item.0 }}"
when: "item.1.changed"
......
Test suite per ai3
==================
ai3 Test Suite
===
# Setup iniziale
We need to be able to test arbitrary combinations of float / the ai3
configuration / individual service releases, so we've created a simple
framework to programmatically generate test environments.
Furthermore, since the ai3 configuration is very large, and we're
generally concerned about minimizing the time it takes to set up a
test environment, we have created a number of "base" test
configurations which only include specific subsets of the ai3
services.
To reduce the parameter space, the inventory always consists of 3
hosts, one in the *frontend* group, two in *backend*.
This test framework combines:
- a specific float version
- test data
as an alternative to using git submodules, which are cumbersome to
manage programatically. Instead, repositories are cloned every time
(though specific branches might be requested via the FLOAT_BRANCH and
TESTDATA_BRANCH environment variables).
A consequence of this setup is that the *float* repository path will
change on every invocation, as repositories are cloned to a temporary
directory, so we have to edit the test skeleton YAML files to point at
the float location. These YAML files contain the special variables
`$FLOAT_DIR` and `$CONFIG_DIR` which are replaced by the *mkenv*
script before invoking "float create-env". The consequence is that the
environment configurations in the *env* directory can't be used
directly with "float create-env".
## Setup iniziale
Per testare l'ambiente locale di test di ai3 (Vagrant), bisogna prima
installare alcuni prerequisiti. Anzitutto serve *virtualenv*, per
......@@ -21,7 +55,7 @@ temporaneo:
$ ./venv/bin/python3 setup.py develop
# Test
## Test
Per lanciare i test, bisogna passare il file di configurazione ai3 di
Ansible (quello cioè passato come inventory) attraverso la variabile
......
---
dkim_selector: stigmate
jabber_domains: "{{ domain_public | list }}"
available_domains:
email: "{{ domain_public | list }}"
web: "{{ domain_public | list }}"
list: "{{ domain_public | list }}"
# Ensure we can always reach the external hosts holding our build artifacts.
static_host_entries:
- host: registry.git.autistici.org
addr: 88.99.75.198
- host: deb.autistici.org
addr: 88.99.75.197
# SSO configuration, mirroring prod.
enable_keystore: true
sso_server_url: "https://accounts.{{ domain_public[0] }}/sso/"
sso_server_url_path_prefix: "/sso/"
sso_server_account_recovery_url: "/account/recovery"
sso_extra_allowed_services:
- "[^.]+\\.webmail\\.({{ domain_public | map('regex_escape') | join('|') }})$"
- "^services\\.({{ domain_public | map('regex_escape') | join('|') }})/admin/$"
- "^(imap|accountserver|mailman)\\.{{ domain | regex_escape }}/$"
sso_allowed_exchanges:
- src_regexp: "^[^.]+\\.webmail\\.({{ domain_public | map('regex_escape') | join('|') }})/$"
dst_regexp: "^imap\\.{{ domain | regex_escape }}/$"
- src_regexp: "^accounts\\.({{ domain_public | map('regex_escape') | join('|') }})/$"
dst_regexp: "^(accountserver|mailman)\\.{{ domain | regex_escape }}/$"
- src_regexp: "^accountadmin\\.({{ domain_public | map('regex_escape') | join('|') }})/$"
dst_regexp: "^(accountserver|mailman)\\.{{ domain | regex_escape }}/$"
- src_regexp: "^services\\.({{ domain_public | map('regex_escape') | join('|') }})/admin/$"
dst_regexp: "^accountserver\\.{{ domain | regex_escape }}/$"
# Run the service-prober on the testdata accounts.
service_prober_credentials:
- username: "due@investici.org"
password: "password"
---
- include: "$FLOAT_DIR/passwords.yml.default"
- include: "$CONFIG_DIR/passwords.common.yml"
- include: "$CONFIG_DIR/passwords.mail.yml"
---
include:
- "$FLOAT_DIR/services.yml.no-elasticsearch"
- "$CONFIG_DIR/services.common.yml"
- "$CONFIG_DIR/services.mail.yml"
- "$CONFIG_DIR/test/services.override.yml"
---
- import_playbook: "$FLOAT_DIR/playbooks/all.yml"
- import_playbook: "$CONFIG_DIR/playbooks/common.yml"
- import_playbook: "$CONFIG_DIR/playbooks/mail.yml"
- import_playbook: "$CONFIG_DIR/playbooks/testdata.yml"
---
- include: "$FLOAT_DIR/passwords.yml.default"
- include: "$CONFIG_DIR/passwords.common.yml"
- include: "$CONFIG_DIR/passwords.noblogs.yml"
---
include:
- "$FLOAT_DIR/services.yml.no-elasticsearch"
- "$CONFIG_DIR/services.common.yml"
- "$CONFIG_DIR/services.noblogs.yml"
- "$CONFIG_DIR/test/services.override.yml"
---
- import_playbook: "$FLOAT_DIR/playbooks/all.yml"
- import_playbook: "$CONFIG_DIR/playbooks/common.yml"
- import_playbook: "$CONFIG_DIR/playbooks/noblogs.yml"
- import_playbook: "$CONFIG_DIR/playbooks/testdata.yml"
---
- include: "$FLOAT_DIR/passwords.yml.default"
- include: "$CONFIG_DIR/passwords.common.yml"
- include: "$CONFIG_DIR/passwords.web.yml"
---
include:
- "$FLOAT_DIR/services.yml.no-elasticsearch"
- "$CONFIG_DIR/services.common.yml"
- "$CONFIG_DIR/services.web.yml"
- "$CONFIG_DIR/test/services.override.yml"
---
- import_playbook: "$FLOAT_DIR/playbooks/all.yml"
- import_playbook: "$CONFIG_DIR/playbooks/common.yml"
- import_playbook: "$CONFIG_DIR/playbooks/web.yml"
- import_playbook: "$CONFIG_DIR/playbooks/testdata.yml"
#!/bin/sh
test_dir="$(dirname "$(realpath "$0")")"
config_dir="$(realpath "${test_dir}/..")"
# Configuration, can be overridden from the environment.
FLOAT_REPO="${FLOAT_REPO:-https://git.autistici.org/ai3/float.git}"
FLOAT_BRANCH="${FLOAT_BRANCH:-master}"
# Default to a different testdata URL (which is a private repository)
# depending on whether we're running under the CI or not.
if [ -n "${CI_JOB_TOKEN}" ]; then
TESTDATA_REPO="${TESTDATA_REPO:-https://gitlab-ci-token:${CI_JOB_TOKEN}@git.autistici.org/ai3/testdata.git}"
else
TESTDATA_REPO="${TESTDATA_REPO:-git@git.autistici.org:ai3/testdata.git}"
fi
TESTDATA_BRANCH="${TESTDATA_BRANCH:-master}"
usage() {
cat >&2 <<EOF
Usage: $0 [<options>]
EOF
exit 2
}
die() {
echo "ERROR: $*" >&2
exit 1
}
git_clone() {
local repo="$1"
local branch="$2"
local local_dir="$3"
if [ -e "${local_dir}" ]; then
(cd "${local_dir}" && git pull && git checkout "${branch}")
else
case "${branch}" in
HEAD|master)
git clone --depth 1 "${repo}" "${local_dir}" ;;
*)
git clone --single-branch --branch "${branch}" "${repo}" "${local_dir}" ;;
esac
fi
[ $? -gt 0 ] && die "failed to clone repository ${repo}"
local rev=$(cd "${local_dir}" && git rev-parse HEAD | cut -c1-8)
echo "checked out $(basename "${local_dir}") at revision ${rev}" >&2
}
patsubst() {
local src="$1"
local sedargs=""
shift
while [ $# -gt 0 ]; do
local var_name="$1"
local var_value="$2"
shift 2
sedargs="${sedargs} -e s,\\\$${var_name},${var_value},g"
done
sed ${sedargs} "${src}"
}
skel_dir="$1"
dest_dir="$2"
mkdir -p "${dest_dir}"
git_clone "${FLOAT_REPO}" "${FLOAT_BRANCH}" "${dest_dir}/float"
git_clone "${TESTDATA_REPO}" "${TESTDATA_BRANCH}" "${dest_dir}/testdata"
# Replace variables in the skeleton YAML files to get the path of our
# local float instance.
for f in services.yml passwords.yml site.yml ; do
patsubst "${skel_dir}/${f}" \
FLOAT_DIR "${dest_dir}/float" \
CONFIG_DIR "${config_dir}" \
> "${dest_dir}/test-${f}"
done
"${dest_dir}/float/float" create-env \
--domain="${DOMAIN:-autistici.org}" \
--infra-domain="${INFRA_DOMAIN:-investici.org}" \
--services="${dest_dir}/test-services.yml" \
--passwords="${dest_dir}/test-passwords.yml" \
--playbook="${dest_dir}/test-site.yml" \
--additional-config="${test_dir}/config.override.yml" \
--roles-path="${config_dir}/roles" \
--num-hosts=3 \
-e config.docker_registry_url=${REGISTRY_URL:-https://registry.git.autistici.org} \
-e config.docker_registry_username=${REGISTRY_USERNAME:-docker-registry-client} \
-e config.docker_registry_password=${REGISTRY_PASSWORD:-} \
${LIBVIRT:+-e libvirt.remote_host=${LIBVIRT#*@} -e libvirt.remote_user=${LIBVIRT%@*}} \
-e ansible_cfg.defaults.strategy=mitogen_linear ${MITOGEN:+-e ansible_cfg.defaults.strategy_plugins=${MITOGEN}/ansible_mitogen/plugins/strategy} \
${APT_PROXY:+-e config.apt_proxy=${APT_PROXY}} \
"${dest_dir}" \
|| die "'float create-env' failed"
(cd "${dest_dir}" && ./float/float run init-credentials) \
|| die "'float run init-credentials' failed"
exit 0
---
# This file exists to override things that are temporarily
# broken in the test environment.
saml-server:
enabled: false
tor-director:
num_instances: 1
aux-db:
scheduling_group: backend
ai3-prober:
num_instances: 1
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment