mirror of
https://github.com/saltstack-formulas/mysql-formula.git
synced 2025-04-17 10:10:30 +00:00
ci(podman): add state tests in simple container
This commit is contained in:
parent
5e2e2e3e72
commit
aea6ecf86e
9 changed files with 354 additions and 0 deletions
20
.github/workflows/test.yaml
vendored
Normal file
20
.github/workflows/test.yaml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
name: CI
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
img:
|
||||
- opensuse.leap
|
||||
- debian.11
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Test
|
||||
run: |
|
||||
cd t && \
|
||||
make test_container
|
||||
env:
|
||||
T_IMAGE: ${{ matrix.img }}
|
12
t/01-smoke-server.sh
Executable file
12
t/01-smoke-server.sh
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!lib/test-in-container-systemd.sh mariadb
|
||||
|
||||
set -ex
|
||||
|
||||
salt-call --local state.apply 'mysql'
|
||||
salt-call --local state.apply 'mysql.remove_test_database'
|
||||
|
||||
mysql -e 'select user(), current_user(), version()'
|
||||
|
||||
service mysql status
|
||||
|
||||
echo success
|
29
t/02-smoke-client.sh
Executable file
29
t/02-smoke-client.sh
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!lib/test-in-container-systemd.sh mariadb-client
|
||||
|
||||
set -ex
|
||||
|
||||
#########################
|
||||
# workaround for https://github.com/saltstack-formulas/mysql-formula/issues/267
|
||||
( grep -qi debian /etc/*release && mkdir -p /etc/mysql ) || \
|
||||
( grep -qi suse /etc/*release && mkdir -p /etc/my.cnf.d ) || \
|
||||
:
|
||||
#########################
|
||||
|
||||
salt-call --local state.apply 'mysql.client'
|
||||
|
||||
mariadb -V || mysql -V
|
||||
|
||||
# check mysqld service is not installed
|
||||
rc=0
|
||||
service mysql status || rc=$?
|
||||
test $rc -gt 0
|
||||
|
||||
rc=0
|
||||
service mysql status || rc=$?
|
||||
test $rc -gt 0
|
||||
|
||||
rc=0
|
||||
service mariadb status || rc=$?
|
||||
test $rc -gt 0
|
||||
|
||||
echo success
|
62
t/10-password.sh
Executable file
62
t/10-password.sh
Executable file
|
@ -0,0 +1,62 @@
|
|||
#!lib/test-in-container-systemd.sh mariadb
|
||||
|
||||
set -ex
|
||||
|
||||
# hack the pillar
|
||||
mkdir -p /srv/pillar
|
||||
echo "
|
||||
mysql:
|
||||
server:
|
||||
mysqld:
|
||||
max_allowed_packet: 1111040
|
||||
database:
|
||||
- testdb
|
||||
user:
|
||||
myuser1:
|
||||
password: 'mypass123'
|
||||
host: localhost
|
||||
databases:
|
||||
- database: testdb
|
||||
grants: ['all']
|
||||
" > /srv/pillar/testdata.sls
|
||||
|
||||
echo '
|
||||
{{ saltenv }}:
|
||||
"*":
|
||||
- testdata
|
||||
' >> /srv/pillar/top.sls
|
||||
|
||||
|
||||
salt-call --local pillar.get mysql:user:myuser1:password
|
||||
salt-call --local pillar.item mysql:user:myuser1:password | grep mypass123
|
||||
|
||||
pass=$(echo $(salt-call --local pillar.get mysql:user:myuser1:password) | tail -n 1 | grep -Eo '[^ ]+$')
|
||||
test "$pass" == mypass123
|
||||
|
||||
salt-call --local state.apply 'mysql'
|
||||
salt-call --local state.apply 'mysql.remove_test_database'
|
||||
|
||||
set -a
|
||||
shopt -s expand_aliases
|
||||
alias sql="mariadb -h 127.0.0.1 -umyuser1 -p$pass -e"
|
||||
(
|
||||
|
||||
sql 'select user(), current_user(), version()'
|
||||
|
||||
packet="$(sql 'show variables like "max_allowed_packet"' -Nb)"
|
||||
test 1111040 == ${packet//[!0-9]/}
|
||||
|
||||
echo test access denied to mysql database
|
||||
rc=0
|
||||
sql 'select user, host from mysql.user' || rc=$?
|
||||
test "$rc" -gt 0
|
||||
|
||||
echo test wrong password is denied
|
||||
rc=0
|
||||
sql 'select user(), current_user(), version()' -p"wrongpassword" || rc=$?
|
||||
test "$rc" -gt 0
|
||||
)
|
||||
|
||||
service mariadb status || service mysql status
|
||||
|
||||
echo success
|
8
t/Makefile
Normal file
8
t/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
test_container:
|
||||
( for f in *.sh; do ./$$f && continue; echo FAIL $$f; exit 1 ; done )
|
||||
|
||||
test_container_fast:
|
||||
( for f in *.sh; do T_CACHE_PACKAGES=1 ./$$f && continue; echo FAIL $$f; exit 1 ; done )
|
||||
|
77
t/README.md
Normal file
77
t/README.md
Normal file
|
@ -0,0 +1,77 @@
|
|||
Scripts to test SLS changes in podman containers
|
||||
-------------------
|
||||
|
||||
The goal is to cover following workflow:
|
||||
|
||||
* Change files related to an individual state.
|
||||
* Spawn a container with a local standalone salt node and apply the states.
|
||||
* Check basic bash commands to verify outcome.
|
||||
|
||||
The test is set of bash commands.
|
||||
The script relies on shebang to prepare an image and spawn a container with the sls files.
|
||||
It is also ready to test salt states using set of commands `salt-call --local`.
|
||||
|
||||
###### Example: Run test for mysql states:
|
||||
|
||||
```bash
|
||||
cd t
|
||||
./01-smoke-server.sh
|
||||
```
|
||||
|
||||
#### Challenge 1: By default, a container is destroyed when the test finishes.
|
||||
|
||||
This is to simplify re-run of tests and do not flood machine with leftover containers after tests.
|
||||
To make sure container stays around after faiure - set environment variable *T_PAUSE_ON_FAILURE* to 1
|
||||
|
||||
###### Example: Connect to the container after test failure
|
||||
|
||||
```bash
|
||||
> # terminal 1
|
||||
> echo fail >> 01-smoke-server.sh
|
||||
> T_PAUSE_ON_FAILURE=1 ./01-smoke-server.sh
|
||||
...
|
||||
bash: line 18: fail: command not found
|
||||
Test failed, press any key to finish
|
||||
```
|
||||
The terminal will wait for any input to finish the test and clean up the container.
|
||||
Now use another terminal window to check the running podman container and get into it for eventual troubleshooting:
|
||||
|
||||
```bash
|
||||
> # terminal 2
|
||||
> podman ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
2a37d23503fa localhost/mysql.formula.t38c8b1d778efa61c676f1aa99b2aded5.image:latest 4 minutes ago Up 4 minutes ago mysql.formula.t38c8b1d778efa61c676f1aa99b2aded5.01-smoke-server.sh
|
||||
> # use copy container id to start bash in it (hint: or bash completion should work for container name as well)
|
||||
> podman exec -it mysql.formuls.t38c8b1d778efa61c676f1aa99b2aded5.01-smoke-server.sh bash
|
||||
2a37d23503fa:/opt/project # ls
|
||||
bin encrypted_pillar_recipients ENCRYPTION.md FORMULAS.yaml gpgkeys pillar README.md salt t test
|
||||
2a37d23503fa:/opt/project # # now we are inside the container and can troubleshoot outcome of salt commands
|
||||
2a37d23503fa:/opt/project # rcmysql status
|
||||
* mariadb.service - MariaDB database server
|
||||
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled)
|
||||
Active: active (running) since Fri 2023-03-17 12:45:24 UTC; 10min ago
|
||||
```
|
||||
|
||||
#### Challenge 2: Vary OS in container.
|
||||
|
||||
Create new file Dockerfile.%osname% similar to existing Docker files in t/lib.
|
||||
Use environment variable T_IMAGE=%osname% to let scripts use corresponding Dockerfile.
|
||||
By default tests are run with t/Dockerfile.opensuse.leap
|
||||
|
||||
#### Challenge 3: Cache packages inside test image.
|
||||
|
||||
(Currently works only with default docker image, i.e. T_IMAGE is empty).
|
||||
Downloading and installing packages may be time consuming, so sometimes it may be advantageous to have an option to pre-install required packages inside image, in which the test will be run. (So the test will concentrate on verifying other aspects of salt states, without spending time on installing packages).
|
||||
At the same time the CI needs to verify salt states related to installation, so it must run the test without such caching.
|
||||
Such caching is implemented as optional parameters to shebang command in the test scripts. These parameters are ignored unless global variable *T_CACHE_PACKAGES* is set to 1.
|
||||
|
||||
```bash
|
||||
> # check parameter in shebang:
|
||||
> head -n 1 01-smoke-server.sh
|
||||
#!lib/test-in-container-systemd.sh mariadb
|
||||
> # run the test in a container with preinstalled mariadb package as specified above:
|
||||
> T_CACHE_PACKAGES=1 ./01-smoke-server.sh
|
||||
> # run the test in a container without preinstalled mariadb package (will take longer, but will verify package installation as part of test)
|
||||
> ./01-smoke-server.sh
|
||||
```
|
||||
|
19
t/lib/Dockerfile.debian.11
Normal file
19
t/lib/Dockerfile.debian.11
Normal file
|
@ -0,0 +1,19 @@
|
|||
FROM debian:11
|
||||
ENV container podman
|
||||
|
||||
ENV LANG en_US.UTF-8
|
||||
|
||||
# these are needed to run test
|
||||
RUN apt-get -y update && apt-get -y upgrade
|
||||
RUN apt-get -y install systemd salt-minion curl sudo
|
||||
|
||||
##DUMMY
|
||||
|
||||
RUN mkdir -p /srv/salt/ && \
|
||||
sed -i 's^\#*\s*file_client: .*$^file_client: local\nsystemd.scope: False\nenable_fqdns_grains: False^' /etc/salt/minion
|
||||
|
||||
ADD mysql /srv/salt/mysql
|
||||
|
||||
WORKDIR /opt/project
|
||||
|
||||
ENTRYPOINT ["/bin/systemd"]
|
21
t/lib/Dockerfile.opensuse.leap
Normal file
21
t/lib/Dockerfile.opensuse.leap
Normal file
|
@ -0,0 +1,21 @@
|
|||
FROM registry.opensuse.org/opensuse/leap
|
||||
ENV container podman
|
||||
|
||||
ENV LANG en_US.UTF-8
|
||||
|
||||
RUN test ! -f /var/log/zypper.log || mv /var/log/zypper.log /var/log/zypper.log.preinstalled
|
||||
|
||||
# these are needed to run test
|
||||
RUN zypper -vvvn install systemd salt-minion sudo
|
||||
|
||||
##DUMMY
|
||||
|
||||
RUN mkdir -p /srv/salt/ && \
|
||||
sed -i 's^\#*\s*file_client: .*$^file_client: local\nsystemd.scope: False\nenable_fqdns_grains: False^' /etc/salt/minion && \
|
||||
sed -i '/pam_systemd.so/d' /etc/pam.d/common-session-pc # delete pam_systemd , otherwise sudo will hang
|
||||
|
||||
ADD mysql /srv/salt/mysql
|
||||
|
||||
WORKDIR /opt/project
|
||||
|
||||
ENTRYPOINT ["/usr/lib/systemd/systemd"]
|
106
t/lib/test-in-container-systemd.sh
Executable file
106
t/lib/test-in-container-systemd.sh
Executable file
|
@ -0,0 +1,106 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (C) 2023 SUSE LLC
|
||||
#
|
||||
# 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 2 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/>.
|
||||
|
||||
last=${@:$#} # last parameter
|
||||
other=${*%${!#}} # all parameters except the last
|
||||
|
||||
testcase=$last
|
||||
|
||||
set -euo pipefail
|
||||
PODMAN=podman
|
||||
image=${T_IMAGE-opensuse.leap}
|
||||
(
|
||||
PODMAN_info="$($PODMAN info >/dev/null 2>&1)" || $PODMAN info
|
||||
[ -n "$testcase" ] || (echo No testcase provided; exit 1)
|
||||
[ -f "$testcase" ] || (echo Cannot find file "$testcase"; exit 1 )
|
||||
) >&2
|
||||
|
||||
thisdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
basename=$(basename "$testcase")
|
||||
basename=${basename,,}
|
||||
basename=${basename//:/_}
|
||||
|
||||
othermd5=
|
||||
test -z "$other" || othermd5=($(echo "$other" | md5sum -))
|
||||
|
||||
ident=mysql.formula.t$othermd5
|
||||
containername="$ident.${basename,,}"
|
||||
|
||||
# we use variable T_CACHE_PACKAGES to speedup testing and make sure that
|
||||
(
|
||||
if test -z "$other" || \
|
||||
test "${T_IMAGE-}" != "" || \
|
||||
test "${T_CACHE_PACKAGES:-}" != 1
|
||||
then
|
||||
cat $thisdir/Dockerfile.${image}
|
||||
else
|
||||
ar=""
|
||||
in="zypper -vvvn in "
|
||||
for pkg in $other vim; do
|
||||
if [[ $pkg == *:* ]]; then
|
||||
n=${pkg//*:}
|
||||
ar="$ar zypper -n ar http://download.opensuse.org/repositories/$pkg/\\\\\$releasever/ $n;"
|
||||
in="$in $n"
|
||||
else
|
||||
in="$in $pkg"
|
||||
fi
|
||||
done
|
||||
test -z "$ar" || ar="$ar zypper --gpg-auto-import-keys ref; "
|
||||
|
||||
sed "s,\#\#DUMMY,RUN $ar $in,g" $thisdir/Dockerfile.${T_IMAGE}
|
||||
fi
|
||||
|
||||
) | cat | $PODMAN build -t $ident.image -f - $thisdir/../..
|
||||
|
||||
map_port=""
|
||||
[ -z "${EXPOSE_PORT:-}" ] || map_port="-p $EXPOSE_PORT:80"
|
||||
$PODMAN run --privileged --rm $map_port --name "$containername" -d -v"$thisdir/../..":/opt/project --add-host localhost:127.0.0.1 -- $ident.image
|
||||
|
||||
in_cleanup=0
|
||||
|
||||
ret=111
|
||||
|
||||
function cleanup {
|
||||
[ "$in_cleanup" != 1 ] || return
|
||||
in_cleanup=1
|
||||
if [ "$ret" != 0 ] && [ -n "${T_PAUSE_ON_FAILURE-}" ]; then
|
||||
read -rsn1 -p"Test failed, press any key to finish";echo
|
||||
fi
|
||||
[ "$ret" == 0 ] || echo FAIL $basename
|
||||
$PODMAN stop -t 0 "$containername" >&/dev/null || :
|
||||
}
|
||||
|
||||
trap cleanup INT TERM EXIT
|
||||
counter=1
|
||||
|
||||
# wait container start
|
||||
until [ $counter -gt 10 ]; do
|
||||
sleep 0.5
|
||||
$PODMAN exec "$containername" pwd >& /dev/null && break
|
||||
((counter++))
|
||||
done
|
||||
|
||||
$PODMAN exec "$containername" pwd >& /dev/null || (echo Cannot start container; exit 1 ) >&2
|
||||
|
||||
echo "$*"
|
||||
# [ -z $initscript ] || echo "bash -xe /opt/project/t/$initscript" | $PODMAN exec -i "$containername" bash -x
|
||||
|
||||
set +e
|
||||
$PODMAN exec -e TESTCASE="$testcase" -i "$containername" bash -xe < "$testcase"
|
||||
ret=$?
|
||||
( exit $ret )
|
||||
|
Loading…
Add table
Reference in a new issue