|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# The 'run' performs a simple test that verifies the S2I image. |
| 4 | +# The main focus here is to exercise the S2I scripts. |
| 5 | +# |
| 6 | +# For more information see the documentation: |
| 7 | +# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md |
| 8 | +# |
| 9 | +# IMAGE_NAME specifies a name of the candidate image used for testing. |
| 10 | +# The image has to be available before this script is executed. |
| 11 | +# |
| 12 | +IMAGE_NAME=${IMAGE_NAME-daeploy/s2i-python-candidate} |
| 13 | + |
| 14 | +# Determining system utility executables (darwin compatibility check) |
| 15 | +READLINK_EXEC="readlink -zf" |
| 16 | +MKTEMP_EXEC="mktemp --suffix=.cid" |
| 17 | +if [[ "$OSTYPE" =~ 'darwin' ]]; then |
| 18 | + READLINK_EXEC="readlink" |
| 19 | + MKTEMP_EXEC="mktemp" |
| 20 | + ! type -a "greadlink" &>"/dev/null" || READLINK_EXEC="greadlink" |
| 21 | + ! type -a "gmktemp" &>"/dev/null" || MKTEMP_EXEC="gmktemp" |
| 22 | +fi |
| 23 | + |
| 24 | +_dir="$(dirname "${BASH_SOURCE[0]}")" |
| 25 | +test_dir="$($READLINK_EXEC ${_dir} || echo ${_dir})" |
| 26 | +image_dir=$($READLINK_EXEC ${test_dir}/.. || echo ${test_dir}/..) |
| 27 | +scripts_url="${image_dir}/.s2i/bin" |
| 28 | +cid_file=$($MKTEMP_EXEC -u) |
| 29 | + |
| 30 | +# Since we built the candidate image locally, we don't want S2I to attempt to pull |
| 31 | +# it from Docker hub |
| 32 | +s2i_args="--pull-policy=never --loglevel=2" |
| 33 | + |
| 34 | +# Port the image exposes service to be tested |
| 35 | +test_port=8080 |
| 36 | + |
| 37 | +image_exists() { |
| 38 | + docker inspect $1 &>/dev/null |
| 39 | +} |
| 40 | + |
| 41 | +container_exists() { |
| 42 | + image_exists $(cat $cid_file) |
| 43 | +} |
| 44 | + |
| 45 | +container_ip() { |
| 46 | + docker inspect --format="{{(index .NetworkSettings.Ports \"$test_port/tcp\" 0).HostIp }}" $(cat $cid_file) | sed 's/0.0.0.0/localhost/' |
| 47 | +} |
| 48 | + |
| 49 | +container_port() { |
| 50 | + docker inspect --format="{{(index .NetworkSettings.Ports \"$test_port/tcp\" 0).HostPort }}" "$(cat "${cid_file}")" |
| 51 | +} |
| 52 | + |
| 53 | +run_s2i_build() { |
| 54 | + s2i build --incremental=true ${s2i_args} ${test_dir}/test-app ${IMAGE_NAME} ${IMAGE_NAME}-testapp |
| 55 | +} |
| 56 | + |
| 57 | +prepare() { |
| 58 | + if ! image_exists ${IMAGE_NAME}; then |
| 59 | + echo "ERROR: The image ${IMAGE_NAME} must exist before this script is executed." |
| 60 | + exit 1 |
| 61 | + fi |
| 62 | + # s2i build requires the application is a valid 'Git' repository |
| 63 | + pushd ${test_dir}/test-app >/dev/null |
| 64 | + git init |
| 65 | + git config user.email "build@localhost" && git config user.name "builder" |
| 66 | + git add -A && git commit -m "Sample commit" |
| 67 | + popd >/dev/null |
| 68 | + run_s2i_build |
| 69 | +} |
| 70 | + |
| 71 | +run_test_application() { |
| 72 | + docker run --rm --cidfile=${cid_file} -p ${test_port}:${test_port} ${IMAGE_NAME}-testapp |
| 73 | +} |
| 74 | + |
| 75 | +cleanup() { |
| 76 | + if [ -f $cid_file ]; then |
| 77 | + if container_exists; then |
| 78 | + docker stop $(cat $cid_file) |
| 79 | + fi |
| 80 | + fi |
| 81 | + if image_exists ${IMAGE_NAME}-testapp; then |
| 82 | + docker rmi ${IMAGE_NAME}-testapp |
| 83 | + fi |
| 84 | +} |
| 85 | + |
| 86 | +check_result() { |
| 87 | + local result="$1" |
| 88 | + if [[ "$result" != "0" ]]; then |
| 89 | + echo "S2I image '${IMAGE_NAME}' test FAILED (exit code: ${result})" |
| 90 | + cleanup |
| 91 | + exit $result |
| 92 | + fi |
| 93 | +} |
| 94 | + |
| 95 | +wait_for_cid() { |
| 96 | + local max_attempts=10 |
| 97 | + local sleep_time=1 |
| 98 | + local attempt=1 |
| 99 | + local result=1 |
| 100 | + while [ $attempt -le $max_attempts ]; do |
| 101 | + [ -f $cid_file ] && break |
| 102 | + echo "Waiting for container to start..." |
| 103 | + attempt=$(( $attempt + 1 )) |
| 104 | + sleep $sleep_time |
| 105 | + done |
| 106 | +} |
| 107 | + |
| 108 | +test_usage() { |
| 109 | + echo "Testing 's2i usage'..." |
| 110 | + s2i usage ${s2i_args} ${IMAGE_NAME} &>/dev/null |
| 111 | +} |
| 112 | + |
| 113 | +test_connection() { |
| 114 | + echo "Testing HTTP connection (http://$(container_ip):$(container_port))" |
| 115 | + local max_attempts=10 |
| 116 | + local sleep_time=1 |
| 117 | + local attempt=1 |
| 118 | + local result=1 |
| 119 | + while [ $attempt -le $max_attempts ]; do |
| 120 | + echo "Sending GET request to http://$(container_ip):$(container_port)/" |
| 121 | + response_code=$(curl -s -w %{http_code} -o /dev/null http://$(container_ip):$(container_port)/) |
| 122 | + status=$? |
| 123 | + if [ $status -eq 0 ]; then |
| 124 | + if [ $response_code -eq 200 ]; then |
| 125 | + result=0 |
| 126 | + fi |
| 127 | + break |
| 128 | + fi |
| 129 | + attempt=$(( $attempt + 1 )) |
| 130 | + sleep $sleep_time |
| 131 | + done |
| 132 | + return $result |
| 133 | +} |
| 134 | + |
| 135 | +# Build the application image twice to ensure the 'save-artifacts' and |
| 136 | +# 'restore-artifacts' scripts are working properly |
| 137 | +prepare |
| 138 | +run_s2i_build |
| 139 | +check_result $? |
| 140 | + |
| 141 | +# Verify the 'usage' script is working properly |
| 142 | +test_usage |
| 143 | +check_result $? |
| 144 | + |
| 145 | +# Verify that the HTTP connection can be established to test application container |
| 146 | +run_test_application & |
| 147 | + |
| 148 | +# Wait for the container to write its CID file |
| 149 | +wait_for_cid |
| 150 | + |
| 151 | +test_connection |
| 152 | +check_result $? |
| 153 | + |
| 154 | +cleanup |
0 commit comments