Skip to content

Commit

Permalink
smaller improvements to dcgoss (goss-org#478)
Browse files Browse the repository at this point in the history
* Debugging improvements:
add option to enable debug output of dcgoss
* do not delete tmp dir when running in debug

Runtime improvements:
raise default timeout
also stop container started with docker-compose run
move goss sleep to the beginning of the test run
do not delete container after run, rather stop it
print logs on error
print total runtime of test at the end
implement goss_file option from goss-org#454
always copy goss.yaml as well
only copy goss_file when it exists
do not run edit mode, when goss_file is set
better handling for goss_file
delete testing object after run
use install instead of cp
* this allows to specify permissions of the resulting file. otherwise it may not be writeable in the target

Improve documentation:
* document debug option
* add example compose file
* consistently use the db container as the example
* add example for goss files path

* fix readme
clean todos

Signed-off-by: Felix Bartels <[email protected]>
  • Loading branch information
fbartels authored and BenjaminHerbert committed May 28, 2020
1 parent a5df5c5 commit 6cda956
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 14 deletions.
30 changes: 29 additions & 1 deletion extras/dcgoss/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,20 @@ Edit will launch a docker container, install goss, and drop the user into an int

**Example:**

`dcgoss db`
`dcgoss edit db`

### Environment vars and defaults
The following environment variables can be set to change the behavior of dcgoss.

##### DEBUG
Enables debug output of `dcgoss`. (Default: empty)

When running in debug mode, the tmp dir with the container output will not be cleaned up.

**Example:**

`DEBUG=true dcgoss edit db`

##### GOSS_PATH
Location of the goss binary to use. (Default: `$(which goss)`)

Expand All @@ -53,6 +62,17 @@ Time to sleep after running container (and optionally `goss_wait.yaml`) and befo
##### GOSS_FILES_PATH
Location of the goss yaml files. (Default: `.`)

**Example:**

`GOSS_FILES_PATH=db dcgoss edit db`

##### GOSS_FILE
Allows to specify a differing name for `goss.yaml`. Useful when the same image is started for different configurations.

**Example:**

`GOSS_FILE=goss_config1.yaml dcgoss run db`

##### GOSS_VARS
The name of the variables file relative to `GOSS_FILES_PATH` to copy into the
docker container and use for valiation (i.e. `dcgoss run`) and copy out of the
Expand All @@ -64,3 +84,11 @@ If unset (or empty), the `--vars` flag is omitted, which is the normal behavior.
##### GOSS_FILES_STRATEGY
Strategy used for copying goss files into the docker container. If set to `'mount'` a volume with goss files is mounted and log output is streamed into the container as `/goss/docker_output.log` file. Other strategy is `'cp'` which uses `'docker cp'` command to copy goss files into docker container. With the `'cp'` strategy you lose the ability to write tests or waits against the docker output. The `'cp'` strategy is required especially when docker daemon is not on the local machine.
(Default `'mount'`)

## Debugging test runs

When debugging test execution its beneficual to set both `DEBUG=true` and `GOSS_WAIT_OPTS=-r 60s -s 5s` (without the redirect to `/dev/null`).

**Example:**

`DEBUG=true GOSS_FILES_PATH=db GOSS_WAIT_OPTS="-r 60s -s 5s" dcgoss run db`
30 changes: 17 additions & 13 deletions extras/dcgoss/dcgoss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/bash

set -e
[ "$DEBUG" ] && set -x

USAGE="USAGE: $(basename "$0") [run|edit] <docker-compose-service>"
GOSS_FILES_PATH="${GOSS_FILES_PATH:-.}"
Expand All @@ -10,26 +11,28 @@ info() {
}
error() {
echo -e "ERROR: $*" >&2;
[[ -e "$service" ]] && docker logs "$service"
exit 1;
}

cleanup() {
set +e
{ kill "$log_pid" && wait "$log_pid"; } 2> /dev/null
rm -rf "$tmp_dir"
[ "$DEBUG" ] || rm -rf "$tmp_dir"
if [[ -n "$service" ]]; then
info "Deleting container"
docker-compose down -v > /dev/null
info "Stopping container"
echo "Deleting $(docker rm -f "$service")"
docker-compose stop > /dev/null
fi
}

run(){
# Copy in goss
cp "${GOSS_PATH}" "$tmp_dir/goss"
chmod 755 "$tmp_dir/goss"
[[ -e "${GOSS_FILES_PATH}/goss.yaml" ]] && cp "${GOSS_FILES_PATH}/goss.yaml" "$tmp_dir"
[[ -e "${GOSS_FILES_PATH}/goss_wait.yaml" ]] && cp "${GOSS_FILES_PATH}/goss_wait.yaml" "$tmp_dir"
[[ -n "${GOSS_VARS}" ]] && [[ -e "${GOSS_FILES_PATH}/${GOSS_VARS}" ]] && cp "${GOSS_FILES_PATH}/${GOSS_VARS}" "$tmp_dir"
[[ -e "${GOSS_FILES_PATH}/${GOSS_FILE:-goss.yaml}" ]] && install -m ugo+rw "${GOSS_FILES_PATH}/${GOSS_FILE:-goss.yaml}" "$tmp_dir"
[[ -e "${GOSS_FILES_PATH}/goss_wait.yaml" ]] && install -m ugo+rw "${GOSS_FILES_PATH}/goss_wait.yaml" "$tmp_dir"
[[ -n "${GOSS_VARS}" ]] && [[ -e "${GOSS_FILES_PATH}/${GOSS_VARS}" ]] && install -m ugo+rw "${GOSS_FILES_PATH}/${GOSS_VARS}" "$tmp_dir"

info "Starting docker container"
docker-compose run -d -T --name "$service" -v "$tmp_dir:/goss" "$service"
Expand All @@ -52,7 +55,7 @@ get_docker_file() {
tmp_dir=$(mktemp -d /tmp/tmp.XXXXXXXXXX)
chmod 777 "$tmp_dir"
# shellcheck disable=SC2154
trap 'ret=$?; cleanup; exit $ret' EXIT
trap 'ret=$?; cleanup; info "Test ran for a total of $SECONDS seconds"; exit $ret' EXIT
service="$2"

if [[ ! -f docker-compose.yaml && ! -f docker-compose.yml ]]; then
Expand All @@ -62,9 +65,9 @@ fi

state=$(docker inspect --format '{{.State.Status}}' "$service" 2> /dev/null || true)
if [[ "$state" == running ]]; then
docker rm -f "$service"
docker rm -f "$service" > /dev/null
elif [[ "$state" == exited ]]; then
docker rm "$service"
docker rm "$service" > /dev/null
fi

GOSS_PATH="${GOSS_PATH:-$(command -v goss 2> /dev/null || true)}"
Expand All @@ -76,6 +79,7 @@ GOSS_SLEEP="${GOSS_SLEEP:-0.2}"
case "$1" in
run)
run "$@"
[[ "$GOSS_SLEEP" ]] && { info "Sleeping for $GOSS_SLEEP"; sleep "$GOSS_SLEEP"; }
if [[ -e "${GOSS_FILES_PATH}/goss_wait.yaml" ]]; then
info "Found goss_wait.yaml, waiting for it to pass before running tests"
if [[ -z "${GOSS_VARS}" ]]; then
Expand All @@ -88,22 +92,22 @@ case "$1" in
fi
fi
fi
[[ "$GOSS_SLEEP" ]] && { info "Sleeping for $GOSS_SLEEP"; sleep "$GOSS_SLEEP"; }
info "Container health"
if ! docker top "$service"; then
docker logs "$service"
error "The container failed to start"
fi
info "Running Tests"
if [[ -z "${GOSS_VARS}" ]]; then
docker exec "$service" sh -c "/goss/goss -g /goss/goss.yaml render | /goss/goss -g - validate $GOSS_OPTS"
docker exec "$service" sh -c "/goss/goss -g /goss/${GOSS_FILE:-goss.yaml} render | /goss/goss -g - validate $GOSS_OPTS"
else
docker exec "$service" sh -c "/goss/goss -g /goss/goss.yaml --vars='/goss/${GOSS_VARS}' render | /goss/goss -g - validate $GOSS_OPTS"
docker exec "$service" sh -c "/goss/goss -g /goss/${GOSS_FILE:-goss.yaml} --vars='/goss/${GOSS_VARS}' render | /goss/goss -g - validate $GOSS_OPTS"
fi
;;
edit)
run "$@"
info "Run goss add/autoadd to add resources"
docker exec -it "$service" sh -c 'cd /goss; PATH="/goss:$PATH" exec sh'
[[ -n "${GOSS_FILE}" ]] && get_docker_file "/goss/${GOSS_FILE}"
get_docker_file "/goss/goss.yaml"
get_docker_file "/goss/goss_wait.yaml"
[[ -n "${GOSS_VARS}" ]] && get_docker_file "/goss/${GOSS_VARS}"
Expand Down
28 changes: 28 additions & 0 deletions extras/dcgoss/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: '3.3'

services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress

wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}

0 comments on commit 6cda956

Please sign in to comment.