Here is our integration-tests.sh script:
#!/bin/sh
set -e
if [ "$1" = "build" ]; then
docker build -f ../docker/cir/Dockerfile -t registry.{url}/cir2 ..
docker build -f ../docker/db-restorer/Dockerfile -t registry.{url}/cir-db-restorer ../docker/db-restorer
docker build -f ../tests/scripts/Dockerfile -t registry.{url}/pester.tests ../tests/scripts
docker build -f ../tests/bruno/Dockerfile -t registry.{url}/cir-bruno-tests ../tests/bruno
fi
key=$(uuidgen)
echo ""
echo "Creating network..."
docker network create bridge-$key
echo ""
echo "Starting MSSQL server..."
mkdir -p /mnt/dock-temp/mssql-$key
chmod 777 /mnt/dock-temp/mssql-$key
mkdir -p /mnt/dock-temp/mssql-$key-backups
chmod 777 /mnt/dock-temp/mssql-$key-backups
docker run \
-d \
--name mssql-$key \
--hostname mssql \
--privileged \
--restart always \
--pull always \
--network bridge-$key \
-e "ACCEPT_EULA=Y" \
-e "MSSQL_SA_PASSWORD=$key" \
-e "MSSQL_COLLATION=utf8_general_ci" \
-v /mnt/dock-temp/mssql-$key:/var/opt/mssql \
-v /mnt/dock-temp/mssql-$key-backups:/var/backups \
registry.{url}/mssql
# sleep 30
echo ""
echo "Restoring DB backup from google drive..."
docker run \
--rm \
--network bridge-$key \
-v /mnt/dock-temp/mssql-$key-backups:/var/backups \
-e "DB_CIR_BACKUP={url}" \
-e "MSSQL_PASSWORD=$key" \
registry.{url}/cir-db-restorer
echo ""
echo "Starting CIR2..."
docker run \
-d \
--name cir2-$key \
--hostname cir2 \
--network bridge-$key \
--restart always \
-e "DATABASE__CONNECTIONSTRING=Server=mssql; Database=CIR; user id={user}; password=$key; Encrypt=False; App=CIR2" \
-e "ASPNETCORE_ENVIRONMENT=Development" \
registry.{url}/cir2
echo ""
echo "Running Integration Tests..."
docker run \
--rm \
--network bridge-$key \
-e "REQUEST_DELAY=0" \
-e "API_URI=http://cir2/api/v1" \
-e "DB_CON_STRING=Server=mssql; Database=CIR; user id={user}; password=$key; Encrypt=False; App=CIR_TESTS" \
registry.{url}/pester.tests
echo ""
echo "Running Bruno Tests..."
docker run \
--rm \
--network bridge-$key \
-e "API_URI=http://cir2/api/v1" \
registry.{url}/cir-bruno-tests
**<--- Here is where script break and exit --->**
echo ""
echo "Cleaning..."
docker stop cir2-$key 2>/dev/null || true
docker rm cir2-$key 2>/dev/null || true
docker stop mssql-$key 2>/dev/null || true
docker rm mssql-$key 2>/dev/null || true
sleep 5
rm -f -r /mnt/dock-temp/mssql-$key-backups
rm -f -r /mnt/dock-temp/mssql-$key
docker network rm bridge-$key
After Bruno tests are done script simply exit and stop and do not continue on line "Cleaning..."
And here is Dockerfile for Bruno tests
FROM alpine:latest
ENV API_URI ""
RUN apk add --no-cache \
nodejs npm
RUN npm install -g @usebruno/cli
COPY /BrunoTests/ /BrunoTests/
WORKDIR /BrunoTests
CMD ["bru", "run", "--env", "Env Cir", "--output", "result.json"]
So basically I would like that my script integration-tests.sh continue even after bruno tests are done and basically continue with commands after. If you need more information please let me know.
When you docker run
a container in the foreground (without the -d
option), the exit status of docker run
is the same as the exit status of the main container command. In your script, you set -e
, and so if any command exits with a non-zero status, the script will immediately exit. That matches the behavior you're seeing here.
More specifically, the command you're trying to run is a test runner. It's very reasonable for a test runner to exit with success (status 0) if all of the tests ran successfully, and failure (any other status) if there is a failure.
There are several common workarounds for this. In your script, you can ignore the failure
docker run ... \
"registry.{url}/cir-bruno-tests" \
|| true
In a comment, you suggest doing something similar in an entrypoint wrapper script, and in principle this would work too.
#!/bin/sh
# Run the main container command
"$@"
# But ignore its exit status and always return success
exit 0
However, also see BashFAQ/105, "Why doesn't set -e (or set -o errexit, or trap ERR) do what I expected?" set -e
has some subtleties that you may not expect. You may be better off specifically checking the error status of things that you expect to fail (docker network create; if [ "$@" != 0 ]; ...; fi
) which will help you clean up consistently.
I might suggest removing the set -e
, letting the test runners exit with failures, and specifically checking the other commands' success or failure state.
(It's also worth noting that the overall structure of this just creates Docker networks and runs containers with some dependencies, which is extremely similar to what Docker Compose does. Rewriting this script into a single Compose file might be more manageable, and Compose will handle the various failure cases for you.)