Commit bb357596 authored by Emeric Verschuur's avatar Emeric Verschuur

[tests] Add the test suite (tests/run-testsuite.sh)

parent 7be6902f
Pipeline #29038367 passed with stages
in 8 minutes and 47 seconds
image: ubuntu:16.04
variables:
GLOBAL_TEST_VAR: "scope: global"
after_script:
- echo "job ${CI_JOB_NAME} end"
job-minimal:
stage: build
tags:
- docker
script:
- echo "Hello world"
job-with-before-after-script:
stage: build
tags:
- docker
before_script:
- echo "executed before"
script:
- echo "script"
"on several"
- echo "lines"
- cat <<< $(echo 'hi!')
after_script:
- echo "executed after"
job-advanced:
image: ubuntu:16.04
stage: build
tags:
- docker
variables:
JOB_TEST_VAR: "${CI_JOB_NAME} - ${GLOBAL_TEST_VAR}"
script:
- ci-scripts/run-job-script.sh
job-test-services-mysql:
stage: build
variables:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: password
image: mysql
services:
- mysql
tags:
- docker
script:
- printf "Waiting for mysql";
TIME_SEC_MAX=60;
while ! mysql -h mysql -u root -ppassword test -e '' > /dev/null 2>&1 ;
do printf "."; ((TIME_SEC_MAX--)) || (printf " timeout!\n"; exit 1); sleep 1; done;
printf " done!\n"
- mysql -h mysql -u root -ppassword test -e 'SHOW VARIABLES LIKE "%version%";'
job-test-services-postgres:
stage: build
image: postgres:9.4
services:
- name: postgres:9.4
alias: db-postgres
entrypoint: ["docker-entrypoint.sh"]
command: ["postgres"]
tags:
- docker
script:
- printf "Waiting for postgres";
TIME_SEC_MAX=60;
while ! psql -h db-postgres -U postgres -c '' > /dev/null 2>&1 ;
do printf "."; ((TIME_SEC_MAX--)) || (printf " timeout!\n"; exit 1); sleep 1; done;
printf " done!\n"
- psql -h db-postgres -U postgres -c 'select version();'
job-test-deps:
stage: test
tags:
- docker
script:
- echo "Simple job to test dependencies"
dependencies:
- job-with-before-after-script
- job-advanced
##################################################
# ### PACKAGE BUILD ### #
##################################################
......@@ -142,7 +57,7 @@ build-package-rel-rpm: *build-package-rel
script: ["ci-scripts/run-job-script.sh"]
test-package-deb-dev-ubuntu-18.04:
image: ubuntu:16.04
image: ubuntu:18.04
dependencies: ["build-package-dev-deb"]
<<: *test-package-template
<<: *package-channel-dev
......@@ -158,11 +73,11 @@ test-package-rpm-dev-fedora-27:
<<: *package-channel-dev
test-package-deb-rel-ubuntu-18.04:
image: ubuntu:16.04
image: ubuntu:18.04
dependencies: ["build-package-rel-deb"]
<<: *test-package-template
<<: *package-channel-rel
test-package-deb-rel-ubuntu-14.04:
test-package-deb-rel-ubuntu-16.04:
image: ubuntu:16.04
dependencies: ["build-package-rel-deb"]
<<: *test-package-template
......
......@@ -160,6 +160,8 @@ Chaque tâche peut être représentée par :
* Une chaine de caractère contenant le nom de la tâche
* Un objet contenant un camp `name` et `arguments` ave la liste des arguments
Un exemple de fichier `.ci-pipelines.yml` est disponible [ici](tests/.ci-pipelines.yml)
## Écrire une tâche ou un module en utilisant le composant run-job-script.sh
En plus de pouvoir lancer une tâche du pipeline, (comme la tâche [job-minimal](#job-minimal)), vous pouvez utiliser le composant `run-job-script.sh` pour écrire les scripts de celle-ci avec une structure modulaire comme c'est le cas pour la tâche d'exemple [job-advanced](#job-advanced)
......
......@@ -160,6 +160,8 @@ Each jobs can be represented by:
* A string containing the job name
* An object containing a `name` and `arguments` with the custom argument list
An example of `.ci-pipelines.yml` can be found [here](tests/.ci-pipelines.yml)
## Write a job or a module script using the run-job-script.sh component
In addition, to run a classical job (like [job-minimal](#job-minimal)), you can use the `run-job-script.sh` component to write a job into a modular format (Job parts, modules, ...) like the [job-advanced](#job-advanced) job example.
......
......@@ -67,11 +67,16 @@ job_main() {
echo -n "Waiting for docker daemon"
until [ -e /var/run/docker.sock ]; do sleep 1; echo -n "."; done
print_info "### STEP3 ### job-* exec"
for j in $(ci-toolbox | grep '^ job-'); do
print_info "### JOB ### Running job $j..."
sudo -u test-user env HOME="$TEST_USER_HOME" ci-toolbox $j
done
print_info "### STEP4 ### run pipeline"
sudo -u test-user env \
CITBX_SEARCH_PATH=ci-toolbox/ \
CI_CONFIG_PATH="tests/.gitlab-ci.yml" \
CITBX_PIPELINES_CONFIG_PATH="tests/.ci-pipelines.yml" \
CITBX_SCRIPTS_DIR=tests/ci-scripts \
ci-toolbox pipeline
print_info "### STEP5 ### run testsuite"
sudo -u test-user env HOME="$TEST_USER_HOME" ./tests/run-testsuite.sh
}
job_after() {
......
......@@ -330,7 +330,13 @@ citbx_run_job() {
fi
# Add variable to the environment list
CITBX_ENV_EXPORT_LIST+=(CI_JOB_NAME CI_REGISTRY CI_PROJECT_DIR CI_SERVER_TLS_CA_FILE)
citbx_export CI_JOB_NAME \
CI_REGISTRY \
CI_PROJECT_DIR \
CI_SERVER_TLS_CA_FILE \
CITBX_SCRIPTS_DIR \
CITBX_MODULES_DIR \
CITBX_JOBS_DIR
if [ "$CITBX_DEBUG_SCRIPT_ENABLED" == "true" ]; then
citbx_before_script="set -x"
......
custom-pipeline:
- minimal-job-global-image
- name: job-advanced
arguments:
job-opt-export: "custom pipeline value"
- job-test-deps
image: ubuntu:16.04
variables:
GLOBAL_TEST_VAR: "scope: global"
before_script:
- echo "TEST_JOB=${CI_JOB_NAME}"
minimal-job-global-image:
stage: build
tags:
- docker
script:
- . /etc/os-release
- echo "Using default image $PRETTY_NAME"
job-with-before-after-script:
stage: build
tags:
- docker
before_script:
- echo "executed before"
script:
- echo "script"
"on several"
- echo "lines"
- cat <<< $(echo 'hi!')
after_script:
- echo "executed after"
job-advanced:
image: ubuntu:16.04
stage: build
tags:
- docker
variables:
JOB_TEST_VAR: "${CI_JOB_NAME} - ${GLOBAL_TEST_VAR}"
script:
- ci-scripts/run-job-script.sh
job-test-services-mysql:
stage: build
variables:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: password
image: mysql
services:
- mysql
tags:
- docker
script:
- printf "Waiting for mysql";
TIME_SEC_MAX=60;
while ! mysql -h mysql -u root -ppassword test -e '' > /dev/null 2>&1 ;
do printf "."; ((TIME_SEC_MAX--)) || (printf " timeout!\n"; exit 1); sleep 1; done;
printf " done!\n"
- mysql -h mysql -u root -ppassword test -e 'SHOW VARIABLES LIKE "%version%";'
job-test-services-postgres:
stage: build
image: postgres:9.4
services:
- name: postgres:9.4
alias: db-postgres
entrypoint: ["docker-entrypoint.sh"]
command: ["postgres"]
tags:
- docker
script:
- printf "Waiting for postgres";
TIME_SEC_MAX=60;
while ! psql -h db-postgres -U postgres -c '' > /dev/null 2>&1 ;
do printf "."; ((TIME_SEC_MAX--)) || (printf " timeout!\n"; exit 1); sleep 1; done;
printf " done!\n"
- psql -h db-postgres -U postgres -c 'select version();'
job-test-deps:
stage: test
tags:
- docker
script:
- echo "Simple job to test dependencies"
dependencies:
- job-with-before-after-script
- job-advanced
......@@ -20,27 +20,17 @@ job_setup() {
" * on the host (outside the docker container)" \
" * before start the suitable docker container"
print_note "Outside the docker:" \
"* JOB_OPTION_LOCAL=\"$JOB_OPTION_LOCAL\"" \
"* JOB_OPTION_EXPORT=\"$JOB_OPTION_EXPORT\""
"* JOB_OPTION_LOCAL=$JOB_OPTION_LOCAL" \
"* JOB_OPTION_EXPORT=$JOB_OPTION_EXPORT"
# Test variable scope
test "$JOB_TEST_VAR" == "job-advanced - scope: global"
}
job_main() {
print_info "This part is executed into the suitable docker container"
if [[ ! -v JOB_OPTION_LOCAL ]]; then
print_info " [ OK ] JOB_OPTION_LOCAL=\"$JOB_OPTION_LOCAL\" (is not defined as expected)"
else
print_critical " [ KO ] JOB_OPTION_LOCAL=\"$JOB_OPTION_LOCAL\" (is defined)"
fi
if [[ -v JOB_OPTION_EXPORT ]]; then
print_info " [ OK ] JOB_OPTION_EXPORT=\"$JOB_OPTION_EXPORT\" (is defined as expected)"
else
print_critical " [ KO ] JOB_OPTION_EXPORT=\"$JOB_OPTION_EXPORT\" (is not defined)"
fi
print_note "Inside the docker:" \
"* JOB_OPTION_LOCAL=$JOB_OPTION_LOCAL" \
"* JOB_OPTION_EXPORT=$JOB_OPTION_EXPORT"
exit $JOB_OPTION_EXIT_CODE
}
......
......@@ -5,11 +5,11 @@ citbx_module_example_define() {
}
citbx_module_example_setup() {
print_note "HOOK example: Job setup (EXAMPLE_VALUE='$EXAMPLE_VALUE')"
print_note "HOOK example: Job setup (EXAMPLE_VALUE=$EXAMPLE_VALUE)"
}
citbx_module_example_before() {
print_note "HOOK example: Before the job (EXAMPLE_VALUE='$EXAMPLE_VALUE')"
print_note "HOOK example: Before the job (EXAMPLE_VALUE=$EXAMPLE_VALUE)"
}
citbx_module_example_after() {
......
#!/usr/bin/env bash
# citbx4gitlab: CI toolbox for Gitlab
# Copyright (C) 2017-2018 ERCOM - Emeric Verschuur <emeric@mbedsys.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set -e
TEST_OK_NB=0
TEST_KO_NB=0
CI_PROJECT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || true)"
# Print an error message and exit with error status 1
print_critical() {
>&2 printf "\033[91m[CRIT] %s\033[0m\n" "$@"
exit 1
}
# Print an error message
print_error() {
>&2 printf "\033[91m[ERRO] %s\033[0m\n" "$@"
}
# Print a warning message
print_warning() {
>&2 printf "\033[93m[WARN] %s\033[0m\n" "$@"
}
# Print a note message
print_note() {
printf "[NOTE] %s\n" "$@"
}
# Pring an info message
print_info() {
printf "\033[92m[INFO] %s\033[0m\n" "$@"
}
# Pring an info message
test_msg_ok() {
printf "\033[92m[<OK>] %s\033[0m\n" "$@"
((++TEST_OK_NB))
}
# Print an error message
test_msg_ko() {
>&2 printf "\033[91m[<!!>] %s\033[0m\n" "$@"
((++TEST_KO_NB))
}
test_finish() {
local retcode=$?
rm -f output.log
if [ $retcode -ne 0 ]; then
print_critical "Exit on fatal error"
fi
print_note "* Test number : $((TEST_OK_NB + TEST_KO_NB))" \
"* Successes : $TEST_OK_NB" \
"* Failures : $TEST_KO_NB"
if [ $TEST_KO_NB -eq 0 ]; then
print_info "Test suite execution succeeded"
else
print_critical "Test suite execution failed"
fi
}
trap test_finish EXIT SIGHUP SIGINT SIGQUIT SIGABRT SIGKILL SIGALRM SIGTERM
export CITBX_SEARCH_PATH=ci-toolbox/
export CI_CONFIG_PATH="tests/.gitlab-ci.yml"
export CITBX_PIPELINES_CONFIG_PATH="tests/.ci-pipelines.yml"
export CITBX_SCRIPTS_DIR=tests/ci-scripts
run_test_case() {
local arglist arg command \
match_list not_match_list \
exitcode_c=0 exitcode_m=0 line
if ! arglist=$(getopt -o "c:m:M:e:" -n "$0 " -- "$@"); then
print_critical "Usage run_test_case:" \
" -j <val> Job name"
fi
eval set -- "$arglist";
# Store the global bashopts properties
while true; do
arg=$1
shift
case "$arg" in
-c) command=$1; shift;;
-m) match_list+=("$1"); shift;;
-e) exitcode_m=$1; shift;;
-M) not_match_list+=("$1"); shift;;
--) break;;
*) print_critical "Fatal error";;
esac
done
# Run job
if [ -z "$command" ]; then
print_critical "run_test_case: No command specified"
fi
$CI_PROJECT_DIR/ci-toolbox/ci-toolbox.sh $command "$@" | tee /tmp/output.log \
&& exitcode_c=${PIPESTATUS[0]} || exitcode_c=${PIPESTATUS[0]}
# Check exit code
if [ $exitcode_c -eq $exitcode_m ]; then
test_msg_ok "Current exit code ($exitcode_c) match with expected one"
else
test_msg_ko "Current exit code ($exitcode_c) don't match with expected one ($exitcode_m)"
fi
# Read output
while read -r line; do
output_lines+=("$line")
done <<< "$(sed -E 's/\r//g' /tmp/output.log)"
# Check matches
if [ ${#match_list[@]} -gt 0 ]; then
set -- "${match_list[@]}";
for line in "${output_lines[@]}"; do
if [ $# -eq 0 ]; then
break
elif [[ "$line" =~ $1 ]]; then
test_msg_ok "'$1' match as expected - line: $line"
shift
fi
done
if [ $# -ne 0 ]; then
test_msg_ko "'$1' don't match as expected or not in the right order"
shift
while [ $# -ne 0 ]; do
test_msg_ko "'$1' match not tested due to previous error"
shift
done
fi
fi
for m in "${not_match_list[@]}"; do
if grep -E "$m" output.log; then
test_msg_ko "'$m' match and shouldn't"
else
test_msg_ok "'$m' don't match as expected"
fi
done
}
run_test_case -c job-advanced \
-m 'HOOK example: Job setup.*EXAMPLE_VALUE=EX 1' \
-m 'Outside the docker' \
-m 'JOB_OPTION_LOCAL=JOB!OPT LOCAL$' \
-m 'JOB_OPTION_EXPORT=JOB!OPT EXPORT$' \
-m 'HOOK example: Before the job.*EXAMPLE_VALUE=EX 1' \
-m 'Inside the docker' \
-m 'JOB_OPTION_LOCAL=$' \
-m 'JOB_OPTION_EXPORT=JOB!OPT EXPORT$' \
-m 'HOOK example: After the job.*exit with code: 0' \
-- \
--example 'EX 1' \
--job-opt-local 'JOB!OPT LOCAL' \
--job-opt-export 'JOB!OPT EXPORT'
run_test_case -c job-advanced \
-e 133 \
-m 'HOOK example: After the job.*exit with code: 133' \
-- \
--job-exit-code 133
run_test_case -c minimal-job-global-image \
-m '^TEST_JOB=minimal-job-global-image$' \
-m '^Using default image Ubuntu 16.04(.[0-9]+)? LTS$'
run_test_case -c job-with-before-after-script \
-m '^executed before$' \
-m '^script on several$' -m '^lines$' -m '^hi!$' \
-m '^executed after$'
run_test_case -c job-test-services-mysql \
-m '^Waiting for mysql(\.)* done!' \
-m 'version\W+[0-9\.]+'
run_test_case -c job-test-services-postgres \
-m '^Waiting for postgres(\.)* done!' \
-m 'PostgreSQL 9\.4\.[0-9]+ on '
run_test_case -c pipeline \
-m 'Running the job \"(minimal-job-global-image|job-advanced|job-with-before-after-script|job-test-services-mysql|job-test-services-postgres)\"' \
-m 'Running the job \"(minimal-job-global-image|job-advanced|job-with-before-after-script|job-test-services-mysql|job-test-services-postgres)\"' \
-m 'Running the job \"(minimal-job-global-image|job-advanced|job-with-before-after-script|job-test-services-mysql|job-test-services-postgres)\"' \
-m 'Running the job \"(minimal-job-global-image|job-advanced|job-with-before-after-script|job-test-services-mysql|job-test-services-postgres)\"' \
-m 'Running the job \"(minimal-job-global-image|job-advanced|job-with-before-after-script|job-test-services-mysql|job-test-services-postgres)\"' \
-m 'Running the job \"job-test-deps\"'
run_test_case -c job-test-deps \
-m 'Running the job \"(job-with-before-after-script|job-advanced)\"' \
-m 'Running the job \"(job-with-before-after-script|job-advanced)\"' \
-m 'Running the job \"job-test-deps\"' \
-- \
--with-dependencies
run_test_case -c job-test-deps \
-m 'JOB_OPTION_EXPORT=dispatched value to subjobs' \
-m 'Running the job \"job-test-deps\"' \
-- \
--with-dependencies
run_test_case -c pipeline \
-m 'Running the job \"minimal-job-global-image\"' \
-m 'Running the job \"job-advanced\"' \
-m 'JOB_OPTION_EXPORT=custom pipeline value' \
-m 'Running the job \"job-test-deps\"' \
-- \
--pipeline-name custom-pipeline
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