Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automated testing #128

Merged
merged 2 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build Docker images
- name: Build/Test Docker images
uses: eskatos/gradle-command-action@v1
with:
arguments: build --info
arguments: build test -PisCI=true --info
4 changes: 2 additions & 2 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: Set TAG Environment Variable
run: |
echo "TAG=$GITHUB_SHA" >> $GITHUB_ENV
- name: Build and Push Docker images
- name: Build/Test/Push Docker images
uses: eskatos/gradle-command-action@v1
with:
arguments: push '-Pdocker.tags=${{ env.TAG }}' '-Pdocker.repository=${{ secrets.REPOSITORY }}' -Pdocker.driver=docker-container -Pdocker.cacheTo=true -Pdocker.platforms=linux/amd64,linux/arm64 --info
arguments: build test '-Pdocker.tags=${{ env.TAG }}' '-Pdocker.repository=${{ secrets.REPOSITORY }}' -Pdocker.push=true -Pdocker.driver=docker-container -Pdocker.cacheTo=true -Pdocker.platforms=linux/amd64,linux/arm64 -PisCI=true --info
5 changes: 2 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ jobs:
run: |
export TAG=$(echo "${GITHUB_REF}" | cut -d "/" -f3)
echo "TAG=$TAG" >> $GITHUB_ENV
- name: Push Docker images
- name: Build/Push/Test Docker images
uses: eskatos/gradle-command-action@v1
with:
arguments: push '-Pdocker.tags=${{ env.TAG }}' '-Pdocker.repository=${{ secrets.REPOSITORY }}' -Pdocker.driver=docker-container -Pdocker.cacheTo=true -Pdocker.platforms=linux/amd64,linux/arm64 --info
# @todo add tests.
arguments: build test '-Pdocker.tags=${{ env.TAG }}' '-Pdocker.repository=${{ secrets.REPOSITORY }}' -Pdocker.push=true -Pdocker.driver=docker-container -Pdocker.cacheTo=true -Pdocker.platforms=linux/amd64,linux/arm64 -PisCI=true --info
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
scratch
scratch.md
volumes
docker-compose.yml
/docker-compose.yml
4 changes: 4 additions & 0 deletions abuild/.dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
build.gradle.kts
Dockerfile
README.md
tests
tests/**/*
4 changes: 4 additions & 0 deletions activemq/.dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
build.gradle.kts
Dockerfile
README.md
tests
tests/**/*
8 changes: 4 additions & 4 deletions activemq/rootfs/etc/services.d/activemq/finish
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/execlineb -S1
# -*- mode: sh -*-
# vi: set ft=sh :
s6-svscanctl -t /var/run/s6/services
#!/usr/bin/env bash
set -e

source /usr/local/share/s6/finish
8 changes: 3 additions & 5 deletions activemq/rootfs/etc/services.d/activemq/run
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/execlineb -P
# -*- mode: sh -*-
# vi: set ft=sh :
s6-setuidgid activemq
/opt/activemq/bin/activemq console
#!/usr/bin/env bash
set -e
exec s6-setuidgid activemq /opt/activemq/bin/activemq console
4 changes: 4 additions & 0 deletions activemq/tests/ServiceStartsWithDefaults/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import tasks.tests.ServiceStartsWithDefaultsTest
tasks.register<ServiceStartsWithDefaultsTest>("test") {
waitForMessage.set("started | org.apache.activemq.broker.BrokerService")
}
4 changes: 4 additions & 0 deletions alpaca/.dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
build.gradle.kts
Dockerfile
README.md
tests
tests/**/*
4 changes: 4 additions & 0 deletions alpaca/tests/ServiceStartsWithDefaults/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import tasks.tests.ServiceStartsWithDefaultsTest
tasks.register<ServiceStartsWithDefaultsTest>("test") {
waitForMessage.set("INFO: Lock acquired")
}
4 changes: 4 additions & 0 deletions base/.dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
build.gradle.kts
Dockerfile
README.md
tests
tests/**/*
3 changes: 2 additions & 1 deletion base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ ARG TARGETARCH
COPY --from=download /usr/local/bin/*.sh /usr/local/bin

# Install s6
RUN --mount=type=cache,id=base-downloads,sharing=locked,target=/opt/downloads \
RUN --mount=type=cache,id=base-downloads,sharing=locked,from=download,target=/opt/downloads \
if [ "${TARGETARCH}" = "arm64" ]; then \
S6_FILE="s6-overlay-aarch64.tar.gz"; \
S6_SHA256="84f585a100b610124bb80e441ef2dc2d68ac2c345fd393d75a6293e0951ccfc5"; \
Expand Down Expand Up @@ -69,6 +69,7 @@ ENV \
S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \
S6_CMD_WAIT_FOR_SERVICE=1 \
S6_CMD_WAIT_FOR_SERVICES_MAXTIME=30000 \
S6_SERVICES_GRACETIME=30000 \
S6_LOGGING=0 \
TERM=xterm

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ set -e
# This is stage `00-container-environment-02` so child images can provide
# custom logic for setting the DB_DRIVER as stage `00-container-environment-01`.

# Allow DB_DRIVER to be overridden by FCREPO_DB_DRIVER, etc.
/usr/local/bin/confd-override-environment.sh --prefix DB

# Dervive DB_HOST/DB_PORT from the given driver if not specified.
DB_DRIVER=$(</var/run/s6/container_environment/DB_DRIVER)
case "${DB_DRIVER}" in
Expand All @@ -24,9 +27,6 @@ esac

# Use what has been provided by the user or default to the derived values.
cat << EOF | /usr/local/bin/confd-import-environment.sh
DB_HOST={{ getenv "DB_HOST" "${DB_HOST}" }}
DB_PORT={{ getenv "DB_PORT" "${DB_PORT}" }}
DB_HOST="{{ getenv "DB_HOST" "${DB_HOST}" }}"
DB_PORT="{{ getenv "DB_PORT" "${DB_PORT}" }}"
EOF

# Allow DB_NAME to be overridden by FCREPO_DB_NAME, etc.
/usr/local/bin/confd-override-environment.sh --prefix DB
2 changes: 1 addition & 1 deletion base/rootfs/etc/services.d/confd/finish
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ set -e

# Only shutdown the container if this service was enabled otherwise ignore.
if [[ "${CONFD_ENABLE_SERVICE}" == "true" ]]; then
s6-svscanctl -t /var/run/s6/services
source /usr/local/share/s6/finish
fi
2 changes: 1 addition & 1 deletion base/rootfs/etc/services.d/confd/run
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ set -e

# Only run the service if explicitly told to do so.
if [[ "${CONFD_ENABLE_SERVICE}" == "true" ]]; then
confd-render-templates.sh -- -interval ${CONFD_POLLING_INTERVAL}
exec confd-render-templates.sh -- -interval ${CONFD_POLLING_INTERVAL}
fi
2 changes: 1 addition & 1 deletion base/rootfs/usr/local/bin/confd-render-templates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,6 @@ function main {
;;
esac

confd ${args} "${OPTIONS[@]}"
exec confd ${args} "${OPTIONS[@]}"
}
main
42 changes: 42 additions & 0 deletions base/rootfs/usr/local/share/s6/finish
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
set -e

readonly SERVICE_DIR="$( cd "$( dirname "${BASH_SOURCE[1]}" )" &> /dev/null && pwd )"
readonly SERVICE=$(basename ${SERVICE_DIR})

# Handles exit codes / signals to ensure the container exits with the expected
# value. Meant to be sourced in /etc/service.d/*/finish scripts.
# See https://skarnet.org/software/s6/s6-supervise.html

# Process received a non-catchable signal (i.e. SIGINT). s6 sets the exit
# code to >= 256 and expects the user to inspect the signal value instead.
# Though it is possible for the service to recieve a signal directly and exit
# with a exit code that indicates it exited due to receiving a signal.
if test ${1} -gt 255; then
readonly EXIT_CODE=$(s6-expr 128 + ${2})
readonly SIGNAL=${2}
elif test ${1} -gt 128; then
readonly EXIT_CODE=${1}
readonly SIGNAL=$(s6-expr ${1} - 128)
else
readonly EXIT_CODE=${1}
fi

echo "[services.d] service ${SERVICE} finish: executing..." >&2

# Report the exit code / signal and exit.
if test -z "$SIGNAL"; then
echo ${EXIT_CODE} > /var/run/s6/env-stage3/S6_STAGE2_EXITED
echo "[services.d] service ${SERVICE} exiting with exit code: ${EXIT_CODE}" >&2
else
if test ${SIGNAL} -eq 15; then
# Process received a SIGTERM. Shutdown gracefully and do not set exit code.
echo "[services.d] service ${SERVICE} received SIGTERM exiting gracefully" >&2
else
echo ${EXIT_CODE} > /var/run/s6/env-stage3/S6_STAGE2_EXITED
echo "[services.d] service ${SERVICE} received signal: ${SIGNAL}, exiting with exit code: ${EXIT_CODE}" >&2
fi
fi

# Regardless take down all other services.
s6-svscanctl -t /var/run/s6/services 2>/dev/null
2 changes: 2 additions & 0 deletions base/tests/EnvironmentOverrideDatabase/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import tasks.tests.DockerComposeTest
tasks.register<DockerComposeTest>("test")
26 changes: 26 additions & 0 deletions base/tests/EnvironmentOverrideDatabase/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# file: docker-compose.yml
#
# Tests that the base values for database environment variables can be
# overridden by prefixing them.
#
# `base/rootfs/etc/cont-init.d/00-container-environment-00-init.sh`
version: "3.8"
services:
base:
# Allow downstream container to override `DB` environment variables.
environment:
TEST_DB_DRIVER: "postgresql"
TEST_DB_MYSQL_HOST: "DB_MYSQL_HOST override"
TEST_DB_MYSQL_PORT: "DB_MYSQL_PORT override"
TEST_DB_NAME: "DB_NAME override"
TEST_DB_PASSWORD: "DB_PASSWORD override"
TEST_DB_POSTGRESQL_HOST: "DB_POSTGRESQL_HOST override"
TEST_DB_POSTGRESQL_PORT: "DB_POSTGRESQL_PORT override"
TEST_DB_ROOT_PASSWORD: "DB_ROOT_PASSWORD override"
TEST_DB_ROOT_USER: "DB_ROOT_USER override"
TEST_DB_USER: "DB_USER override"
volumes:
- ./test.sh:/test.sh # Test to run.
command:
- /test.sh # Run test and exit.
image: ${BASE_IMAGE:-local/base:latest}
18 changes: 18 additions & 0 deletions base/tests/EnvironmentOverrideDatabase/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/with-contenv bash

source /usr/local/share/isle/utilities.sh

# Checks that all `DB` environment variables can be overriden.
expect "DB_DRIVER" "postgresql"
expect "DB_MYSQL_HOST" "DB_MYSQL_HOST override"
expect "DB_MYSQL_PORT" "DB_MYSQL_PORT override"
expect "DB_NAME" "DB_NAME override"
expect "DB_PASSWORD" "DB_PASSWORD override"
expect "DB_POSTGRESQL_HOST" "DB_POSTGRESQL_HOST override"
expect "DB_POSTGRESQL_PORT" "DB_POSTGRESQL_PORT override"
expect "DB_ROOT_PASSWORD" "DB_ROOT_PASSWORD override"
expect "DB_ROOT_USER" "DB_ROOT_USER override"
expect "DB_USER" "DB_USER override"

# All tests were successful
exit 0
22 changes: 22 additions & 0 deletions base/tests/EnvironmentPrecedence/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@file:Suppress("UnstableApiUsage")

import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
import java.io.ByteArrayOutputStream
import java.time.Duration.ofSeconds
import tasks.DockerCompose
import java.lang.RuntimeException

tasks.register<DockerCompose>("test") {
val arch = DefaultNativePlatform.getCurrentArchitecture()!!
timeout.convention(ofSeconds(30))
environment.put("ETCD_TAG", if (arch.isArm) "gcr.io/etcd-development/etcd:v3.4.15-arm64" else "gcr.io/etcd-development/etcd:v3.4.15")
doFirst {
setUp()
// Populate etcd before starting other containers.
up("-d", "etcd")
exec("-T", "etcd", "sh", "/populate-etcd.sh")
up( "--abort-on-container-exit") // Run test.sh as a CMD service and blocking until completion or failure.
tearDown()
checkExitCodes(0L)
}
}
1 change: 1 addition & 0 deletions base/tests/EnvironmentPrecedence/defaults/DB_NAME
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DB_NAME /etc/defaults value
1 change: 1 addition & 0 deletions base/tests/EnvironmentPrecedence/defaults/DB_PASSWORD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DB_PASSWORD /etc/defaults value
1 change: 1 addition & 0 deletions base/tests/EnvironmentPrecedence/defaults/DB_USER
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DB_USER /etc/defaults value
1 change: 1 addition & 0 deletions base/tests/EnvironmentPrecedence/defaults/JWT_ADMIN_TOKEN
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JWT_ADMIN_TOKEN /etc/defaults value
50 changes: 50 additions & 0 deletions base/tests/EnvironmentPrecedence/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# file: docker-compose.yml
#
# Used for testing environment precedence follows what is expected from:
#
# `base/rootfs/etc/cont-init.d/00-container-environment-00-init.sh`
version: "3.8"
secrets:
# Secrets are #2 on the precedence list.
DB_PASSWORD:
file: "./secrets/DB_PASSWORD"
JWT_ADMIN_TOKEN:
file: "./secrets/JWT_ADMIN_TOKEN"
JWT_PRIVATE_KEY:
file: "./secrets/JWT_PRIVATE_KEY"
services:
# Single node cluster.
etcd:
# etcd uses a different tag for arm64, default to x86_64 have gradle pass in the appropriate tag based on host.
image: ${ETCD_TAG:-gcr.io/etcd-development/etcd:v3.4.15}
environment:
ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2379"
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
volumes:
- ./populate-etcd.sh:/populate-etcd.sh
# etcd will be the confd backend and as such is #1 on the precedence list.
command: >
etcd --data-dir=/data
base:
# Environment variables defined here are #3 on on the precedence list.
# Environment variables specified in the Dockerfile for are #4 on the
# precedence list. Followed by files in /etc/defaults in the image,
# which are #5 on the precedence list
environment:
CONFD_BACKEND: "etcd"
DB_NAME: "DB_NAME passed in value" # Should take precedence.
DB_PASSWORD: "DB_PASSWORD passed in value" # Should be overridden by the secret.
JWT_ADMIN_TOKEN: "JWT_ADMIN_TOKEN passed in value" # Should be overridden by the confd backend.
secrets:
- DB_PASSWORD # Should take precedence.
- JWT_ADMIN_TOKEN # Should be overridden by confd backend.
- JWT_PRIVATE_KEY # Used to test template generation, should take precedence over /etc/defaults.
volumes:
- ./test.sh:/test.sh # Test to run.
- ./defaults/DB_NAME:/etc/defaults/DB_NAME # Should be overridden by the passed in environment variable.
- ./defaults/DB_PASSWORD:/etc/defaults/DB_PASSWORD # Should be overridden by the secret.
- ./defaults/DB_USER:/etc/defaults/DB_USER # Should be overridden by environment variable defined in Dockerfile.
- ./defaults/JWT_ADMIN_TOKEN:/etc/defaults/JWT_ADMIN_TOKEN # Should be overridden by confd backend.
command:
- /test.sh # Run test and exit.
image: ${BASE_IMAGE:-local/base:latest}
12 changes: 12 additions & 0 deletions base/tests/EnvironmentPrecedence/populate-etcd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh

# Wait for etcd to start
while true; do
etcdctl endpoint status >/dev/null 2>&1
if [ "$?" -eq "0" ]; then
break
fi
sleep 1
done

etcdctl put /jwt/admin/token "JWT_ADMIN_TOKEN confd value"
1 change: 1 addition & 0 deletions base/tests/EnvironmentPrecedence/secrets/DB_PASSWORD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DB_PASSWORD secret value
1 change: 1 addition & 0 deletions base/tests/EnvironmentPrecedence/secrets/JWT_ADMIN_TOKEN
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JWT_ADMIN_TOKEN secret value
1 change: 1 addition & 0 deletions base/tests/EnvironmentPrecedence/secrets/JWT_PRIVATE_KEY
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JWT_PRIVATE_KEY secret value
32 changes: 32 additions & 0 deletions base/tests/EnvironmentPrecedence/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/with-contenv bash

source /usr/local/share/isle/utilities.sh

# Check environment variables match expectations otherwise exit non-zero.
#
# For each level we specify an a value for that level and all levels that are
# lower precedence than it. We then check to see that precedence holds as
# expected:
#
# 1. Confd backend (highest)
# 2. Secrets kept in /run/secrets
# 3. Environment variables passed into the container
# 4. Environment variables defined in Dockerfile(s)
# 5. Environment variables defined in the /etc/defaults directory (lowest only used for multiline variables)

# For ease of reading overridden values follow the format:
# ENV_VAR_NAME="ENV_VAR_NAME SOURCE value"
expect "JWT_ADMIN_TOKEN" "JWT_ADMIN_TOKEN confd value" # Confd backend should take precedence
expect "DB_PASSWORD" "DB_PASSWORD secret value" # Secret should take precedence
expect "DB_NAME" "DB_NAME passed in value" # Environment passed into the container should take precedence
expect "DB_USER" "default" # Environment variables defined in Dockerfile should take precedence
expect "JWT_PUBLIC_KEY" "$(cat /etc/defaults/JWT_PUBLIC_KEY)" # Unspecified /etc/defaults value is used.

# Check templated output from confd backend matches expectations.
diff /opt/keys/jwt/syn-settings.xml <(cat /etc/confd/templates/syn-settings.xml.tmpl | sed -e "s|{{ getenv \"JWT_ADMIN_TOKEN\" }}|${JWT_ADMIN_TOKEN}|")

# Check templated output from secrets matches expectations.
diff /opt/keys/jwt/private.key <(echo -n "${JWT_PRIVATE_KEY}")

# All tests were successful
exit 0
Loading