diff --git a/.github/workflows/on-pull-request.yml b/.github/workflows/on-pull-request.yml
index b78701d..9977f1f 100644
--- a/.github/workflows/on-pull-request.yml
+++ b/.github/workflows/on-pull-request.yml
@@ -37,6 +37,7 @@ jobs:
- gantry_cleanup_images_spec.sh
- gantry_common_options_spec.sh
- gantry_filters_spec.sh
+ - gantry_login_negative_spec.sh
- gantry_login_spec.sh
- gantry_manifest_spec.sh
- gantry_notify_spec.sh
diff --git a/.github/workflows/on-push.yml b/.github/workflows/on-push.yml
index 1bcdf79..ecb931c 100644
--- a/.github/workflows/on-push.yml
+++ b/.github/workflows/on-push.yml
@@ -40,6 +40,7 @@ jobs:
- gantry_cleanup_images_spec.sh
- gantry_common_options_spec.sh
- gantry_filters_spec.sh
+ - gantry_login_negative_spec.sh
- gantry_login_spec.sh
- gantry_manifest_spec.sh
- gantry_notify_spec.sh
diff --git a/Dockerfile b/Dockerfile
index d2c3cc5..23b5fa8 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM alpine:3.20
+FROM alpine:3.20.3
LABEL org.opencontainers.image.title=gantry
LABEL org.opencontainers.image.description="Updating docker swarm services"
diff --git a/src/entrypoint.sh b/src/entrypoint.sh
index a915697..8c78a6b 100755
--- a/src/entrypoint.sh
+++ b/src/entrypoint.sh
@@ -15,8 +15,7 @@
# along with this program. If not, see .
#
-load_libraries() {
- local LOCAL_LOG_LEVEL="${GANTRY_LOG_LEVEL:-""}"
+_get_lib_dir() {
local LIB_DIR=
if [ -n "${GANTRY_LIB_DIR:-""}" ]; then
LIB_DIR="${GANTRY_LIB_DIR}"
@@ -29,10 +28,28 @@ load_libraries() {
elif [ -r "./lib-gantry.sh" ]; then
LIB_DIR="."
fi
+ echo "${LIB_DIR}"
+}
+
+_log_load_libraries() {
+ local LOG_LEVEL="${GANTRY_LOG_LEVEL:-""}"
+ local IMAGES_TO_REMOVE="${GANTRY_IMAGES_TO_REMOVE:-""}"
+ local LIB_DIR="${1}"
# log function is not available before loading the library.
- if ! echo "${LOCAL_LOG_LEVEL}" | grep -q -i "NONE"; then
- echo "Loading libraries from ${LIB_DIR}"
+ if echo "${LOG_LEVEL}" | grep -q -i "NONE"; then
+ return 0
+ fi
+ local TIMESTAMP=
+ if [ -z "${IMAGES_TO_REMOVE}" ]; then
+ TIMESTAMP="[$(date -Iseconds)] "
fi
+ echo "${TIMESTAMP}Loading libraries from ${LIB_DIR}" >&2
+}
+
+load_libraries() {
+ local LIB_DIR=
+ LIB_DIR=$(_get_lib_dir)
+ _log_load_libraries "${LIB_DIR}"
. "${LIB_DIR}/notification.sh"
. "${LIB_DIR}/docker_hub_rate.sh"
. "${LIB_DIR}/lib-common.sh"
@@ -155,7 +172,7 @@ main() {
if [ -n "${IMAGES_TO_REMOVE}" ]; then
# Image remover runs as a global job. The log will be collected via docker commands then formatted.
# Redefine the log function for the formater.
- log() { echo "${@}"; }
+ log() { echo "${@}" >&2; }
gantry_remove_images "${IMAGES_TO_REMOVE}"
return $?
fi
diff --git a/src/lib-common.sh b/src/lib-common.sh
index bc6b9a8..f6d6ca9 100755
--- a/src/lib-common.sh
+++ b/src/lib-common.sh
@@ -228,10 +228,15 @@ read_config() {
read_env() {
local VNAME="${1}"; shift
[ -z "${VNAME}" ] && return 1
- if env | grep -q "${VNAME}="; then
- eval "echo \"\${${VNAME}}\""
- else
+ # "grep -q" will exit immediately when the first line of data matches, and leading to broken pipe errors.
+ # Add "cat > /dev/null" to avoid broken pipe errors.
+ local GREP_RETURN=
+ env | (grep -q "^${VNAME}="; local R=$?; cat >/dev/null; test "${R}" == "0";);
+ GREP_RETURN=$?
+ if [ "${GREP_RETURN}" != "0" ]; then
echo "${@}"
+ else
+ eval "echo \"\${${VNAME}}\""
fi
return 0
}
@@ -418,6 +423,46 @@ docker_version() {
echo "Docker version client ${cver} (API ${capi}) server ${sver} (API ${sapi})"
}
+# echo the name of the current container.
+# echo nothing if unable to find the name.
+# return 1 when there is an error.
+docker_current_container_name() {
+ local ALL_NETWORKS=
+ ALL_NETWORKS=$(docker network ls --format '{{.ID}}') || return 1;
+ [ -z "${ALL_NETWORKS}" ] && return 0;
+ local IPS=;
+ IPS=$(ip route | grep src | sed -n "s/.* src \(\S*\).*$/\1/p");
+ [ -z "${IPS}" ] && return 0;
+ local GWBRIDGE_NETWORK HOST_NETWORK;
+ GWBRIDGE_NETWORK=$(docker network ls --format '{{.ID}}' --filter 'name=^docker_gwbridge$') || return 1;
+ HOST_NETWORK=$(docker network ls --format '{{.ID}}' --filter 'name=^host$') || return 1;
+ local NID=;
+ for NID in ${ALL_NETWORKS}; do
+ # The output of gwbridge does not contain the container name. It looks like gateway_8f55496ce4f1/172.18.0.5/16.
+ [ "${NID}" = "${GWBRIDGE_NETWORK}" ] && continue;
+ # The output of host does not contain an IP.
+ [ "${NID}" = "${HOST_NETWORK}" ] && continue;
+ local ALL_LOCAL_NAME_AND_IP=;
+ ALL_LOCAL_NAME_AND_IP=$(docker network inspect "${NID}" --format "{{range .Containers}}{{.Name}}/{{println .IPv4Address}}{{end}}") || return 1;
+ for NAME_AND_IP in ${ALL_LOCAL_NAME_AND_IP}; do
+ [ -z "${NAME_AND_IP}" ] && continue;
+ # NAME_AND_IP will be in one of the following formats:
+ # '//'
+ # '/' (when network mode is host)
+ local CNAME CIP
+ CNAME=$(echo "${NAME_AND_IP}/" | cut -d/ -f1);
+ CIP=$(echo "${NAME_AND_IP}/" | cut -d/ -f2);
+ # Unable to find the container IP when network mode is host.
+ [ -z "${CIP}" ] && continue;
+ for IP in ${IPS}; do
+ [ "${IP}" != "${CIP}" ] && continue;
+ echo "${CNAME}";
+ return 0;
+ done
+ done
+ done
+}
+
docker_service_remove() {
local SERVICE_NAME="${1}"
if ! docker service inspect --format '{{.JobStatus}}' "${SERVICE_NAME}" >/dev/null 2>&1; then
@@ -493,13 +538,15 @@ docker_run() {
local RETRIES=0
local MAX_RETRIES=5
local SLEEP_SECONDS=10
- while ! docker run "${@}" >/dev/null; do
+ local MSG=
+ while ! MSG=$(docker run "${@}" 2>&1); do
if [ ${RETRIES} -ge ${MAX_RETRIES} ]; then
- echo "Failed to run docker. Reached the max retries ${MAX_RETRIES}." >&2
+ log ERROR "Failed to run docker. Reached the max retries ${MAX_RETRIES}. ${MSG}"
return 1
fi
RETRIES=$((RETRIES + 1))
sleep ${SLEEP_SECONDS}
- echo "Retry docker run (${RETRIES})."
+ log WARN "Retry docker run (${RETRIES}). ${MSG}"
done
+ echo "${MSG}"
}
diff --git a/src/lib-gantry.sh b/src/lib-gantry.sh
index 51bb02b..3d54965 100755
--- a/src/lib-gantry.sh
+++ b/src/lib-gantry.sh
@@ -74,7 +74,6 @@ _read_env_or_label() {
echo "${VALUE}"
}
-
_login_registry() {
local USER="${1}"
local PASSWORD="${2}"
@@ -85,24 +84,30 @@ _login_registry() {
fi
[ -z "${USER}" ] && log ERROR "USER is empty." && return 1
[ -z "${PASSWORD}" ] && log ERROR "PASSWORD is empty." && return 1
- local DOCKER_CONFIG=
- local CONFIG_MESSAGE=" ${HOST}"
+ local REGISTRY_MESSAGE="registry ${HOST}"
if [ -z "${HOST}" ]; then
log WARN "HOST is empty. Will login to the default registry."
- CONFIG_MESSAGE=""
+ REGISTRY_MESSAGE="default registry"
fi
+ local DOCKER_CONFIG=
+ local CONFIG_TO_REPORT=
+ CONFIG_TO_REPORT=$(readlink -f ~/.docker)
+ local CONFIG_MESSAGE="with default configuration"
if [ -n "${CONFIG}" ]; then
DOCKER_CONFIG="--config ${CONFIG}"
- CONFIG_MESSAGE="${CONFIG_MESSAGE} for config ${CONFIG}"
+ CONFIG_TO_REPORT="${CONFIG}"
+ CONFIG_MESSAGE="with configuration ${CONFIG}"
fi
+ local REGISTRY_CONFIG_MESSAGE="${REGISTRY_MESSAGE} ${CONFIG_MESSAGE}"
local LOGIN_MSG=
# SC2086: Double quote to prevent globbing and word splitting.
# shellcheck disable=SC2086
if ! LOGIN_MSG=$(echo "${PASSWORD}" | docker ${DOCKER_CONFIG} login --username="${USER}" --password-stdin "${HOST}" 2>&1); then
- log ERROR "Failed to login to registry${CONFIG_MESSAGE}. ${LOGIN_MSG}"
+ log ERROR "Failed to login to ${REGISTRY_CONFIG_MESSAGE}. ${LOGIN_MSG}"
return 1
fi
- log INFO "Logged into registry${CONFIG_MESSAGE}. ${LOGIN_MSG}"
+ log INFO "Logged into ${REGISTRY_CONFIG_MESSAGE}. ${LOGIN_MSG}"
+ _static_variable_add_unique_to_list STATIC_VAR_SERVICES_DOCKER_CONFIGS "${CONFIG_TO_REPORT}"
return 0
}
@@ -407,7 +412,7 @@ _remove_images() {
docker_service_remove "${SERVICE_NAME}"
}
-_report_services_list() {
+_report_list() {
local PRE="${1}"; shift
local POST="${1}"; shift
local LIST="${*}"
@@ -415,7 +420,7 @@ _report_services_list() {
NUM=$(_get_number_of_elements "${LIST}")
local TITLE=
[ -n "${PRE}" ] && TITLE="${PRE} "
- TITLE="${TITLE}${NUM} service(s)"
+ TITLE="${TITLE}${NUM}"
[ -n "${POST}" ] && TITLE="${TITLE} ${POST}"
echo "${TITLE}:"
local ITEM=
@@ -424,7 +429,7 @@ _report_services_list() {
done
}
-_report_services_from_static_variable() {
+_report_from_static_variable() {
local VARIABLE_NAME="${1}"
local PRE="${2}"
local POST="${3}"
@@ -435,7 +440,20 @@ _report_services_from_static_variable() {
echo "${EMPTY}"
return 0
fi
- _report_services_list "${PRE}" "${POST}" "${LIST}"
+ _report_list "${PRE}" "${POST}" "${LIST}"
+}
+
+_report_services_from_static_variable() {
+ local VARIABLE_NAME="${1}"
+ local PRE="${2}"
+ local POST="${3}"
+ local EMPTY="${4}"
+ if [ -z "${POST}" ]; then
+ POST="service(s)"
+ else
+ POST="service(s) ${POST}"
+ fi
+ _report_from_static_variable "${VARIABLE_NAME}" "${PRE}" "${POST}" "${EMPTY}"
}
_get_number_of_elements() {
@@ -529,43 +547,15 @@ _current_container_name() {
local NO_CURRENT_CONTAINER_NAME=
NO_CURRENT_CONTAINER_NAME=$(_static_variable_read_list STATIC_VAR_NO_CURRENT_CONTAINER_NAME)
[ -n "${NO_CURRENT_CONTAINER_NAME}" ] && return 0
- local ALL_NETWORKS=
- ALL_NETWORKS=$(docker network ls --format '{{.ID}}') || return 1;
- [ -z "${ALL_NETWORKS}" ] && return 0;
- local IPS=;
- IPS=$(ip route | grep src | sed -n "s/.* src \(\S*\).*$/\1/p");
- [ -z "${IPS}" ] && return 0;
- local GWBRIDGE_NETWORK HOST_NETWORK;
- GWBRIDGE_NETWORK=$(docker network ls --format '{{.ID}}' --filter 'name=^docker_gwbridge$') || return 1;
- HOST_NETWORK=$(docker network ls --format '{{.ID}}' --filter 'name=^host$') || return 1;
- local NID=;
- for NID in ${ALL_NETWORKS}; do
- # The output of gwbridge does not contain the container name. It looks like gateway_8f55496ce4f1/172.18.0.5/16.
- [ "${NID}" = "${GWBRIDGE_NETWORK}" ] && continue;
- # The output of host does not contain an IP.
- [ "${NID}" = "${HOST_NETWORK}" ] && continue;
- local ALL_LOCAL_NAME_AND_IP=;
- ALL_LOCAL_NAME_AND_IP=$(docker network inspect "${NID}" --format "{{range .Containers}}{{.Name}}/{{println .IPv4Address}}{{end}}") || return 1;
- for NAME_AND_IP in ${ALL_LOCAL_NAME_AND_IP}; do
- [ -z "${NAME_AND_IP}" ] && continue;
- # NAME_AND_IP will be in one of the following formats:
- # '//'
- # '/' (when network mode is host)
- local CNAME CIP
- CNAME=$(echo "${NAME_AND_IP}/" | cut -d/ -f1);
- CIP=$(echo "${NAME_AND_IP}/" | cut -d/ -f2);
- # Unable to find the container IP when network mode is host.
- [ -z "${CIP}" ] && continue;
- for IP in ${IPS}; do
- [ "${IP}" != "${CIP}" ] && continue;
- _static_variable_add_unique_to_list STATIC_VAR_CURRENT_CONTAINER_NAME "${CNAME}"
- echo "${CNAME}";
- return 0;
- done
- done
- done
- # Explicitly set that we cannot find the name of current container.
- _static_variable_add_unique_to_list STATIC_VAR_NO_CURRENT_CONTAINER_NAME "NO_CURRENT_CONTAINER_NAME"
+ local CNAME=
+ CNAME=$(docker_current_container_name) || return 1;
+ if [ -n "${CNAME}" ]; then
+ _static_variable_add_unique_to_list STATIC_VAR_CURRENT_CONTAINER_NAME "${CNAME}"
+ else
+ # Explicitly set that we cannot find the name of current container.
+ _static_variable_add_unique_to_list STATIC_VAR_NO_CURRENT_CONTAINER_NAME "NO_CURRENT_CONTAINER_NAME"
+ fi
+ echo "${CNAME}"
return 0;
}
@@ -659,6 +649,11 @@ _get_config_from_service() {
local AUTH_CONFIG=
AUTH_CONFIG=$(_get_label_from_service "${SERVICE_NAME}" "${AUTH_CONFIG_LABEL}")
[ -z "${AUTH_CONFIG}" ] && return 0
+ if [ ! -d "${AUTH_CONFIG}" ]; then
+ log WARN "${AUTH_CONFIG} is not a directory that contains Docker configuration files."
+ local MSG="configuration(s) set via GANTRY_REGISTRY_CONFIG* or GANTRY_REGISTRY_CONFIGS_FILE"
+ _report_from_static_variable STATIC_VAR_SERVICES_DOCKER_CONFIGS "There are" "${MSG}" "There are no ${MSG}." | log_lines WARN
+ fi
echo "--config ${AUTH_CONFIG}"
}
@@ -708,7 +703,7 @@ _get_image_info() {
return 1
fi
if [ "${RETURN_VALUE}" != "0" ]; then
- log ERROR "Image ${IMAGE} does not exist or it is not available. ${MSG}"
+ log ERROR "Image ${IMAGE} does not exist or it is not available. Docker ${MANIFEST_CMD} returns: ${MSG}"
return 1
fi
echo "${MSG}"
diff --git a/tests/gantry_cleanup_images_spec.sh b/tests/gantry_cleanup_images_spec.sh
index 516aba0..b05629d 100644
--- a/tests/gantry_cleanup_images_spec.sh
+++ b/tests/gantry_cleanup_images_spec.sh
@@ -37,7 +37,9 @@ Describe 'cleanup-images'
When run test_CLEANUP_IMAGES_false "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -79,7 +81,9 @@ Describe 'cleanup-images'
When run test_CLEANUP_IMAGES_OPTIONS_bad "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -122,7 +126,9 @@ Describe 'cleanup-images'
When run test_CLEANUP_IMAGES_OPTIONS_good "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -209,11 +215,14 @@ Describe 'cleanup-images'
When run test_IMAGES_TO_REMOVE_none_empty "${TEST_NAME}" "${SERVICE_NAME}" "${IMAGE_WITH_TAG}"
The status should be success
The stdout should satisfy display_output
- The stdout should satisfy spec_expect_message "Removed exited container.*${SERVICE_NAME0}.*${IMAGE_WITH_TAG0}"
- The stdout should satisfy spec_expect_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG0}"
- The stdout should satisfy spec_expect_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG1}"
- The stdout should satisfy spec_expect_message "There is no image.*${IMAGE_WITH_TAG2}"
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ # It should not use the log function from the lib-common, the messages do not start with "[".
+ The stderr should satisfy spec_expect_no_message "^((?:\x1b\[[0-9;]*[mG])?\[)"
+ The stderr should satisfy spec_expect_message "Removed exited container.*${SERVICE_NAME0}.*${IMAGE_WITH_TAG0}"
+ The stderr should satisfy spec_expect_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG0}"
+ The stderr should satisfy spec_expect_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG1}"
+ The stderr should satisfy spec_expect_message "There is no image.*${IMAGE_WITH_TAG2}"
End
End
End # Describe 'Single service'
diff --git a/tests/gantry_common_options_spec.sh b/tests/gantry_common_options_spec.sh
index 292cde4..fad512c 100644
--- a/tests/gantry_common_options_spec.sh
+++ b/tests/gantry_common_options_spec.sh
@@ -40,7 +40,9 @@ Describe 'common-options'
When run test_common_DOCKER_HOST_not_swarm_manager "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_NOT_SWARM_MANAGER}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
@@ -107,7 +109,9 @@ Describe 'common-options'
When run test_common_PRE_POST_RUN_CMD "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "Pre update"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
@@ -157,7 +161,9 @@ Describe 'common-options'
When run test_common_SLEEP_SECONDS "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_multiple_messages "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_CURRENT_IS_LATEST}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -201,7 +207,9 @@ Describe 'common-options'
When run test_common_SLEEP_SECONDS_not_a_number "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "GANTRY_SLEEP_SECONDS ${MUST_BE_A_NUMBER}.*"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING_ALL}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
diff --git a/tests/gantry_filters_spec.sh b/tests/gantry_filters_spec.sh
index ce0a370..f4f7a1f 100644
--- a/tests/gantry_filters_spec.sh
+++ b/tests/gantry_filters_spec.sh
@@ -36,7 +36,9 @@ Describe 'filters'
When run test_SERVICES_FILTERS_bad "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "Failed to obtain services list.*"
The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_PREVIOUS_ERRORS}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
@@ -80,7 +82,7 @@ Describe 'filters'
local LABEL="gantry.test"
for NUM in $(seq "${NUM_SERVICES_EXCLUDED_FILTER_START}" "${MAX_SERVICES_NUM}"); do
local SERVICE_NAME_NUM="${SERVICE_NAME}-${NUM}"
- docker service update --quiet --label-add "${LABEL}=true" "${SERVICE_NAME_NUM}"
+ docker_service_update --label-add "${LABEL}=true" "${SERVICE_NAME_NUM}"
done
export GANTRY_SERVICES_EXCLUDED_FILTERS="label=${LABEL}=true"
run_gantry "${TEST_NAME}"
@@ -91,7 +93,9 @@ Describe 'filters'
When run test_SERVICES_EXCLUDED_multiple_services "${TEST_NAME}" "${SERVICE_NAME}" "${MAX_SERVICES_NUM}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING_ALL}"
The stderr should satisfy spec_expect_multiple_messages "${EXCLUDE_SERVICE}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
@@ -129,7 +133,7 @@ Describe 'filters'
local LABEL="gantry.services.excluded"
for NUM in $(seq 0 "${MAX_SERVICES_NUM}"); do
local SERVICE_NAME_NUM="${SERVICE_NAME}-${NUM}"
- docker service update --quiet --label-add "${LABEL}=true" "${SERVICE_NAME_NUM}"
+ docker_service_update --label-add "${LABEL}=true" "${SERVICE_NAME_NUM}"
done
# Do not set GANTRY_SERVICES_EXCLUDED_FILTERS, check the default one is working.
run_gantry "${TEST_NAME}"
@@ -140,7 +144,9 @@ Describe 'filters'
When run test_SERVICES_EXCLUDED_FILTERS_default "${TEST_NAME}" "${SERVICE_NAME}" "${MAX_SERVICES_NUM}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING_ALL}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
@@ -181,7 +187,9 @@ Describe 'filters'
When run test_SERVICES_EXCLUDED_FILTERS_bad "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "Failed to obtain services list.*"
The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_PREVIOUS_ERRORS}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
diff --git a/tests/gantry_login_negative_spec.sh b/tests/gantry_login_negative_spec.sh
new file mode 100644
index 0000000..c62f601
--- /dev/null
+++ b/tests/gantry_login_negative_spec.sh
@@ -0,0 +1,408 @@
+#!/bin/bash spellspec
+# Copyright (C) 2024 Shizun Ge
+#
+# 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 3 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 .
+#
+
+Describe 'login_negative'
+ SUITE_NAME="login_negative"
+ BeforeAll "initialize_all_tests ${SUITE_NAME} ENFORCE_LOGIN"
+ AfterAll "finish_all_tests ${SUITE_NAME} ENFORCE_LOGIN"
+ Describe "test_login_no_login" "container_test:false"
+ TEST_NAME="test_login_no_login"
+ IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
+ SERVICE_NAME="gantry-test-$(unique_id)"
+ CONFIG="C$(unique_id)"
+ TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
+ test_login_no_login() {
+ local TEST_NAME="${1}"
+ local SERVICE_NAME="${2}"
+ reset_gantry_env "${SERVICE_NAME}"
+ run_gantry "${TEST_NAME}"
+ }
+ BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ It 'run_test'
+ When run test_login_no_login "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
+ The status should be failure
+ The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
+ The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_no_message "${LOGGED_INTO_REGISTRY}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}"
+ The stderr should satisfy spec_expect_no_message "${CONFIG_IS_NOT_A_DIRECTORY}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config ${CONFIG}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_MANIFEST_FAILURE}"
+ The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
+ The stderr should satisfy spec_expect_message "${NUM_SERVICES_INSPECT_FAILURE}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--with-registry-auth.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_ROLLBACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLED_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${NO_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_message "${NUM_SERVICES_UPDATE_FAILED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_ERRORS}"
+ The stderr should satisfy spec_expect_message "${NO_IMAGES_TO_REMOVE}"
+ The stderr should satisfy spec_expect_no_message "${REMOVING_NUM_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_REMOVING_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
+ End
+ End
+ Describe "test_login_incorrect_password" "container_test:false"
+ TEST_NAME="test_login_incorrect_password"
+ IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
+ SERVICE_NAME="gantry-test-$(unique_id)"
+ CONFIG="C$(unique_id)"
+ TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
+ test_login_incorrect_password() {
+ local TEST_NAME="${1}"
+ local SERVICE_NAME="${2}"
+ local CONFIG="${3}"
+ local REGISTRY="${4}"
+ local USERNAME="${5}"
+ local PASSWORD="${6}"
+ check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1;
+ local INCORRECT_PASSWORD="${PASSWORD}-incorrect-password"
+ local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}";
+ local PASS_FILE=; PASS_FILE=$(mktemp); echo "${INCORRECT_PASSWORD}" > "${PASS_FILE}";
+ docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}"
+ reset_gantry_env "${SERVICE_NAME}"
+ export GANTRY_REGISTRY_CONFIG="${CONFIG}"
+ export GANTRY_REGISTRY_HOST="${REGISTRY}"
+ export GANTRY_REGISTRY_PASSWORD_FILE="${PASS_FILE}"
+ export GANTRY_REGISTRY_USER_FILE="${USER_FILE}"
+ local RETURN_VALUE=
+ run_gantry "${TEST_NAME}"
+ RETURN_VALUE="${?}"
+ rm "${USER_FILE}"
+ rm "${PASS_FILE}"
+ [ -d "${CONFIG}" ] && rm -r "${CONFIG}"
+ return "${RETURN_VALUE}"
+ }
+ BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ It 'run_test'
+ When run test_login_incorrect_password "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
+ The status should be failure
+ The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
+ The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_no_message "${LOGGED_INTO_REGISTRY}"
+ The stderr should satisfy spec_expect_message "${FAILED_TO_LOGIN_TO_REGISTRY}.*${TEST_REGISTRY}.*${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${CONFIG_IS_NOT_A_DIRECTORY}"
+ The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_PREVIOUS_ERRORS}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_INSPECT_FAILURE}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}"
+ The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_ROLLBACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLED_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${NO_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATE_FAILED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_ERRORS}"
+ The stderr should satisfy spec_expect_message "${NO_IMAGES_TO_REMOVE}"
+ The stderr should satisfy spec_expect_no_message "${REMOVING_NUM_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_REMOVING_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
+ End
+ End
+ Describe "test_login_read_only_file" "container_test:false"
+ TEST_NAME="test_login_read_only_file"
+ IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
+ SERVICE_NAME="gantry-test-$(unique_id)"
+ CONFIG="C$(unique_id)"
+ TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
+ test_login_read_only_file() {
+ local TEST_NAME="${1}"
+ local SERVICE_NAME="${2}"
+ local CONFIG="${3}"
+ local REGISTRY="${4}"
+ local USERNAME="${5}"
+ local PASSWORD="${6}"
+ check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1;
+ # Set the config folder to read only. (It won't work for container_test)
+ mkdir -p "${CONFIG}"
+ chmod 444 "${CONFIG}"
+ local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}";
+ local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}";
+ docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}"
+ reset_gantry_env "${SERVICE_NAME}"
+ export GANTRY_REGISTRY_CONFIG="${CONFIG}"
+ export GANTRY_REGISTRY_HOST="${REGISTRY}"
+ export GANTRY_REGISTRY_PASSWORD_FILE="${PASS_FILE}"
+ export GANTRY_REGISTRY_USER_FILE="${USER_FILE}"
+ local RETURN_VALUE=
+ run_gantry "${TEST_NAME}"
+ RETURN_VALUE="${?}"
+ rm "${USER_FILE}"
+ rm "${PASS_FILE}"
+ [ -d "${CONFIG}" ] && chmod 777 "${CONFIG}" && rm -r "${CONFIG}"
+ return "${RETURN_VALUE}"
+ }
+ BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ It 'run_test'
+ When run test_login_read_only_file "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
+ The status should be failure
+ The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
+ The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_no_message "${LOGGED_INTO_REGISTRY}"
+ The stderr should satisfy spec_expect_message "${FAILED_TO_LOGIN_TO_REGISTRY}.*${TEST_REGISTRY}.*${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${CONFIG_IS_NOT_A_DIRECTORY}"
+ The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_PREVIOUS_ERRORS}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_INSPECT_FAILURE}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}"
+ The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_ROLLBACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLED_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${NO_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATE_FAILED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_ERRORS}"
+ The stderr should satisfy spec_expect_message "${NO_IMAGES_TO_REMOVE}"
+ The stderr should satisfy spec_expect_no_message "${REMOVING_NUM_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_REMOVING_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
+ End
+ End
+ Describe "test_login_config_mismatch" "container_test:false"
+ TEST_NAME="test_login_config_mismatch"
+ IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
+ SERVICE_NAME="gantry-test-$(unique_id)"
+ CONFIG="C$(unique_id)"
+ TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
+ test_login_config_mismatch() {
+ local TEST_NAME="${1}"
+ local SERVICE_NAME="${2}"
+ local CONFIG="${3}"
+ local REGISTRY="${4}"
+ local USERNAME="${5}"
+ local PASSWORD="${6}"
+ check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1;
+ local INCORRECT_CONFIG="${CONFIG}-incorrect"
+ local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}";
+ local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}";
+ # The config name on the service is different from the config name used in GANTRY_REGISTRY_CONFIG
+ docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${INCORRECT_CONFIG}" "${SERVICE_NAME}"
+ reset_gantry_env "${SERVICE_NAME}"
+ export GANTRY_REGISTRY_CONFIG="${CONFIG}"
+ export GANTRY_REGISTRY_HOST="${REGISTRY}"
+ export GANTRY_REGISTRY_PASSWORD_FILE="${PASS_FILE}"
+ export GANTRY_REGISTRY_USER_FILE="${USER_FILE}"
+ local RETURN_VALUE=
+ run_gantry "${TEST_NAME}"
+ RETURN_VALUE="${?}"
+ rm "${USER_FILE}"
+ rm "${PASS_FILE}"
+ [ -d "${CONFIG}" ] && rm -r "${CONFIG}"
+ [ -d "${INCORRECT_CONFIG}" ] && rm -r "${INCORRECT_CONFIG}"
+ return "${RETURN_VALUE}"
+ }
+ BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ It 'run_test'
+ When run test_login_config_mismatch "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
+ The status should be failure
+ The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
+ The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}"
+ The stderr should satisfy spec_expect_message "${CONFIG_IS_NOT_A_DIRECTORY}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*\"--config ${CONFIG}\".*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*\"--config ${CONFIG}-incorrect\".*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_MANIFEST_FAILURE}"
+ The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
+ The stderr should satisfy spec_expect_message "${NUM_SERVICES_INSPECT_FAILURE}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--with-registry-auth.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_ROLLBACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLED_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${NO_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_message "${NUM_SERVICES_UPDATE_FAILED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_ERRORS}"
+ The stderr should satisfy spec_expect_message "${NO_IMAGES_TO_REMOVE}"
+ The stderr should satisfy spec_expect_no_message "${REMOVING_NUM_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_REMOVING_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
+ End
+ End
+ Describe "test_login_REGISTRY_CONFIGS_FILE_bad_format" "container_test:false"
+ TEST_NAME="test_login_REGISTRY_CONFIGS_FILE_bad_format"
+ IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
+ SERVICE_NAME="gantry-test-$(unique_id)"
+ CONFIG="C$(unique_id)"
+ TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
+ test_login_REGISTRY_CONFIGS_FILE_bad_format() {
+ local TEST_NAME="${1}"
+ local SERVICE_NAME="${2}"
+ local CONFIG="${3}"
+ local REGISTRY="${4}"
+ local USERNAME="${5}"
+ local PASSWORD="${6}"
+ check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1;
+ local CONFIGS_FILE=
+ CONFIGS_FILE=$(mktemp)
+ # Add an extra item to the line.
+ echo "${CONFIG} ${REGISTRY} ${USERNAME} ${PASSWORD} Extra" >> "${CONFIGS_FILE}"
+ # Missing an item from the line.
+ echo "The-Only-Item-In-The-Line" >> "${CONFIGS_FILE}"
+ docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}"
+ reset_gantry_env "${SERVICE_NAME}"
+ export GANTRY_REGISTRY_CONFIGS_FILE="${CONFIGS_FILE}"
+ local RETURN_VALUE=
+ run_gantry "${TEST_NAME}"
+ RETURN_VALUE="${?}"
+ rm "${CONFIGS_FILE}"
+ [ -d "${CONFIG}" ] && rm -r "${CONFIG}"
+ return "${RETURN_VALUE}"
+ }
+ BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ It 'run_test'
+ When run test_login_REGISTRY_CONFIGS_FILE_bad_format "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
+ The status should be failure
+ The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
+ The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_message "format error.*Found extra item\(s\)"
+ The stderr should satisfy spec_expect_message "format error.*Missing item\(s\)"
+ The stderr should satisfy spec_expect_no_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}"
+ The stderr should satisfy spec_expect_no_message "${CONFIG_IS_NOT_A_DIRECTORY}"
+ The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_PREVIOUS_ERRORS}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_INSPECT_FAILURE}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*"
+ The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_ROLLBACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLED_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${NO_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATE_FAILED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_ERRORS}"
+ The stderr should satisfy spec_expect_message "${NO_IMAGES_TO_REMOVE}"
+ The stderr should satisfy spec_expect_no_message "${REMOVING_NUM_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_REMOVING_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
+ End
+ End
+ Describe "test_login_file_not_exist" "container_test:false"
+ TEST_NAME="test_login_file_not_exist"
+ IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
+ SERVICE_NAME="gantry-test-$(unique_id)"
+ CONFIG="C$(unique_id)"
+ TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
+ test_login_file_not_exist() {
+ local TEST_NAME="${1}"
+ local SERVICE_NAME="${2}"
+ local CONFIG="${3}"
+ local REGISTRY="${4}"
+ local USERNAME="${5}"
+ local PASSWORD="${6}"
+ check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1;
+ docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}"
+ local FILE_NOT_EXIST="/tmp/${CONFIG}"
+ reset_gantry_env "${SERVICE_NAME}"
+ export GANTRY_REGISTRY_CONFIG_FILE="${FILE_NOT_EXIST}"
+ export GANTRY_REGISTRY_CONFIGS_FILE="${FILE_NOT_EXIST}"
+ export GANTRY_REGISTRY_HOST_FILE="${FILE_NOT_EXIST}"
+ export GANTRY_REGISTRY_PASSWORD_FILE="${FILE_NOT_EXIST}"
+ export GANTRY_REGISTRY_USER_FILE="${FILE_NOT_EXIST}"
+ local RETURN_VALUE=
+ run_gantry "${TEST_NAME}"
+ RETURN_VALUE="${?}"
+ [ -d "${CONFIG}" ] && rm -r "${CONFIG}"
+ return "${RETURN_VALUE}"
+ }
+ BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
+ It 'run_test'
+ When run test_login_file_not_exist "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
+ The status should be failure
+ The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
+ The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_no_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}"
+ The stderr should satisfy spec_expect_no_message "${CONFIG_IS_NOT_A_DIRECTORY}"
+ The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_PREVIOUS_ERRORS}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_INSPECT_FAILURE}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*"
+ The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_ROLLBACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ROLLED_BACK}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${NO_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATE_FAILED}"
+ The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_ERRORS}"
+ The stderr should satisfy spec_expect_message "${NO_IMAGES_TO_REMOVE}"
+ The stderr should satisfy spec_expect_no_message "${REMOVING_NUM_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${SKIP_REMOVING_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
+ End
+ End
+End # Describe 'login_negative'
diff --git a/tests/gantry_login_spec.sh b/tests/gantry_login_spec.sh
index 5116e40..9f8e8a9 100644
--- a/tests/gantry_login_spec.sh
+++ b/tests/gantry_login_spec.sh
@@ -17,9 +17,8 @@
Describe 'login'
SUITE_NAME="login"
- BeforeAll "initialize_all_tests ${SUITE_NAME}"
- AfterAll "finish_all_tests ${SUITE_NAME}"
- # Here are just simple login tests.
+ BeforeAll "initialize_all_tests ${SUITE_NAME} ENFORCE_LOGIN"
+ AfterAll "finish_all_tests ${SUITE_NAME} ENFORCE_LOGIN"
Describe "test_login_config" "container_test:true"
TEST_NAME="test_login_config"
IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
@@ -33,17 +32,10 @@ Describe 'login'
local REGISTRY="${4}"
local USERNAME="${5}"
local PASSWORD="${6}"
- if [ -z "${REGISTRY}" ] || [ -z "${USERNAME}" ] || [ -z "${PASSWORD}" ]; then
- echo "No REGISTRY, USERNAME or PASSWORD provided." >&2
- return 1
- fi
- local LABEL="gantry.auth.config"
- local USER_FILE PASS_FILE
- USER_FILE=$(mktemp)
- PASS_FILE=$(mktemp)
- docker service update --quiet --label-add "${LABEL}=${CONFIG}" "${SERVICE_NAME}"
- echo "${USERNAME}" > "${USER_FILE}"
- echo "${PASSWORD}" > "${PASS_FILE}"
+ check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1;
+ local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}";
+ local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}";
+ docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}"
reset_gantry_env "${SERVICE_NAME}"
export GANTRY_REGISTRY_CONFIG="${CONFIG}"
export GANTRY_REGISTRY_HOST="${REGISTRY}"
@@ -63,8 +55,12 @@ Describe 'login'
When run test_login_config "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
- The stderr should satisfy spec_expect_message "Logged into registry *${TEST_REGISTRY} for config ${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}"
+ The stderr should satisfy spec_expect_no_message "${CONFIG_IS_NOT_A_DIRECTORY}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -89,61 +85,57 @@ Describe 'login'
The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
End
End
- Describe "test_login_REGISTRY_CONFIGS_FILE" "container_test:true"
- TEST_NAME="test_login_REGISTRY_CONFIGS_FILE"
+ Describe "test_login_default_config" "container_test:true"
+ TEST_NAME="test_login_default_config"
IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
SERVICE_NAME="gantry-test-$(unique_id)"
- CONFIG="C$(unique_id)"
+ CONFIG="NotUsed"
TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
- test_login_REGISTRY_CONFIGS_FILE() {
+ test_login_default_config() {
local TEST_NAME="${1}"
local SERVICE_NAME="${2}"
local CONFIG="${3}"
local REGISTRY="${4}"
local USERNAME="${5}"
local PASSWORD="${6}"
- if [ -z "${REGISTRY}" ] || [ -z "${USERNAME}" ] || [ -z "${PASSWORD}" ]; then
- echo "No REGISTRY, USERNAME or PASSWORD provided." >&2
- return 1
- fi
- local LABEL="gantry.auth.config"
- local CONFIGS_FILE=
- CONFIGS_FILE=$(mktemp)
- docker service update --quiet --label-add "${LABEL}=${CONFIG}" "${SERVICE_NAME}"
- echo "# Test comments: CONFIG REGISTRY USERNAME PASSWORD" >> "${CONFIGS_FILE}"
- echo "${CONFIG} ${REGISTRY} ${USERNAME} ${PASSWORD}" >> "${CONFIGS_FILE}"
+ check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1;
+ local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}";
+ local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}";
+ # Do not set GANTRY_AUTH_CONFIG_LABEL on the service.
reset_gantry_env "${SERVICE_NAME}"
- export GANTRY_REGISTRY_CONFIGS_FILE="${CONFIGS_FILE}"
- # Since we pass credentials via the configs file, we can use other envs to login to docker hub and check the rate.
- # However we do not actually check whether we read rates correctly, in case password or usrename for docker hub is not set.
- # It seems there is no rate limit when running from the github actions, which also gives us a NaN error.
- # Do not set GANTRY_REGISTRY_HOST to test the default config.
- # export GANTRY_REGISTRY_HOST="docker.io"
- export GANTRY_REGISTRY_PASSWORD="${DOCKERHUB_PASSWORD:-""}"
- export GANTRY_REGISTRY_USER="${DOCKERHUB_USERNAME:-""}"
+ # Do not set GANTRY_REGISTRY_CONFIG
+ export GANTRY_REGISTRY_HOST="${REGISTRY}"
+ export GANTRY_REGISTRY_PASSWORD_FILE="${PASS_FILE}"
+ export GANTRY_REGISTRY_USER_FILE="${USER_FILE}"
local RETURN_VALUE=
run_gantry "${TEST_NAME}"
RETURN_VALUE="${?}"
- rm "${CONFIGS_FILE}"
- [ -d "${CONFIG}" ] && rm -r "${CONFIG}"
+ rm "${USER_FILE}"
+ rm "${PASS_FILE}"
+ [ -d "${CONFIG}" ] && rm -r "${CONFIG}" && echo "${CONFIG} should not exist." >&2 && return 1
return "${RETURN_VALUE}"
}
BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
It 'run_test'
- When run test_login_REGISTRY_CONFIGS_FILE "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
+ When run test_login_default_config "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
- The stderr should satisfy spec_expect_message "Logged into registry *${TEST_REGISTRY} for config ${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*default configuration"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}"
+ The stderr should satisfy spec_expect_no_message "${CONFIG_IS_NOT_A_DIRECTORY}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_INSPECT_FAILURE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
The stderr should satisfy spec_expect_message "${NUM_SERVICES_UPDATING}"
- The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config ${CONFIG}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--with-registry-auth.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config ${CONFIG}.*${SERVICE_NAME}"
+ # When using the default configuration, user must manually set --with-registry-auth.
+ The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--with-registry-auth.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
@@ -160,33 +152,34 @@ Describe 'login'
The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
End
End
- Describe "test_login_REGISTRY_CONFIGS_FILE_bad_format" "container_test:false"
- TEST_NAME="test_login_REGISTRY_CONFIGS_FILE_bad_format"
+ Describe "test_login_REGISTRY_CONFIGS_FILE" "container_test:true"
+ TEST_NAME="test_login_REGISTRY_CONFIGS_FILE"
IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
SERVICE_NAME="gantry-test-$(unique_id)"
CONFIG="C$(unique_id)"
TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
- test_login_REGISTRY_CONFIGS_FILE_bad_format() {
+ test_login_REGISTRY_CONFIGS_FILE() {
local TEST_NAME="${1}"
local SERVICE_NAME="${2}"
local CONFIG="${3}"
local REGISTRY="${4}"
local USERNAME="${5}"
local PASSWORD="${6}"
- if [ -z "${REGISTRY}" ] || [ -z "${USERNAME}" ] || [ -z "${PASSWORD}" ]; then
- echo "No REGISTRY, USERNAME or PASSWORD provided." >&2
- return 1
- fi
- local LABEL="gantry.auth.config"
+ check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1;
local CONFIGS_FILE=
CONFIGS_FILE=$(mktemp)
- docker service update --quiet --label-add "${LABEL}=${CONFIG}" "${SERVICE_NAME}"
- # Add an extra item to the line.
- echo "${CONFIG} ${REGISTRY} ${USERNAME} ${PASSWORD} Extra" >> "${CONFIGS_FILE}"
- # Missing an item from the line.
- echo "The-Only-Item-In-The-Line" >> "${CONFIGS_FILE}"
+ echo "# Test comments: CONFIG REGISTRY USERNAME PASSWORD" >> "${CONFIGS_FILE}"
+ echo "${CONFIG} ${REGISTRY} ${USERNAME} ${PASSWORD}" >> "${CONFIGS_FILE}"
+ docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}"
reset_gantry_env "${SERVICE_NAME}"
export GANTRY_REGISTRY_CONFIGS_FILE="${CONFIGS_FILE}"
+ # Since we pass credentials via the configs file, we can use other envs to login to docker hub and check the rate.
+ # However we do not actually check whether we read rates correctly, in case password or usrename for docker hub is not set.
+ # It seems there is no rate limit when running from the github actions, which also gives us a NaN error.
+ # Do not set GANTRY_REGISTRY_HOST to test the default config.
+ # export GANTRY_REGISTRY_HOST="docker.io"
+ export GANTRY_REGISTRY_PASSWORD="${DOCKERHUB_PASSWORD:-""}"
+ export GANTRY_REGISTRY_USER="${DOCKERHUB_USERNAME:-""}"
local RETURN_VALUE=
run_gantry "${TEST_NAME}"
RETURN_VALUE="${?}"
@@ -197,98 +190,36 @@ Describe 'login'
BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
It 'run_test'
- When run test_login_REGISTRY_CONFIGS_FILE_bad_format "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
- The status should be failure
- The stdout should satisfy display_output
- The stderr should satisfy display_output
- The stderr should satisfy spec_expect_message "format error.*Found extra item\(s\)"
- The stderr should satisfy spec_expect_message "format error.*Missing item\(s\)"
- The stderr should satisfy spec_expect_no_message "Logged into registry *${TEST_REGISTRY} for config ${CONFIG}"
- The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_PREVIOUS_ERRORS}"
- The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_INSPECT_FAILURE}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}"
- The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*"
- The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_no_message "${FAILED_TO_ROLLBACK}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_no_message "${ROLLED_BACK}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_message "${NO_SERVICES_UPDATED}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATED}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATE_FAILED}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_ERRORS}"
- The stderr should satisfy spec_expect_message "${NO_IMAGES_TO_REMOVE}"
- The stderr should satisfy spec_expect_no_message "${REMOVING_NUM_IMAGES}"
- The stderr should satisfy spec_expect_no_message "${SKIP_REMOVING_IMAGES}"
- The stderr should satisfy spec_expect_no_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
- The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
- End
- End
- Describe "test_login_file_not_exist" "container_test:false"
- TEST_NAME="test_login_file_not_exist"
- IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
- SERVICE_NAME="gantry-test-$(unique_id)"
- CONFIG="C$(unique_id)"
- TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
- test_login_file_not_exist() {
- local TEST_NAME="${1}"
- local SERVICE_NAME="${2}"
- local CONFIG="${3}"
- local REGISTRY="${4}"
- local USERNAME="${5}"
- local PASSWORD="${6}"
- if [ -z "${REGISTRY}" ] || [ -z "${USERNAME}" ] || [ -z "${PASSWORD}" ]; then
- echo "No REGISTRY, USERNAME or PASSWORD provided." >&2
- return 1
- fi
- local LABEL="gantry.auth.config"
- docker service update --quiet --label-add "${LABEL}=${CONFIG}" "${SERVICE_NAME}"
- local FILE_NOT_EXIST="/tmp/${CONFIG}"
- reset_gantry_env "${SERVICE_NAME}"
- export GANTRY_REGISTRY_CONFIG_FILE="${FILE_NOT_EXIST}"
- export GANTRY_REGISTRY_CONFIGS_FILE="${FILE_NOT_EXIST}"
- export GANTRY_REGISTRY_HOST_FILE="${FILE_NOT_EXIST}"
- export GANTRY_REGISTRY_PASSWORD_FILE="${FILE_NOT_EXIST}"
- export GANTRY_REGISTRY_USER_FILE="${FILE_NOT_EXIST}"
- local RETURN_VALUE=
- run_gantry "${TEST_NAME}"
- RETURN_VALUE="${?}"
- [ -d "${CONFIG}" ] && rm -r "${CONFIG}"
- return "${RETURN_VALUE}"
- }
- BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
- AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
- It 'run_test'
- When run test_login_file_not_exist "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
- The status should be failure
+ When run test_login_REGISTRY_CONFIGS_FILE "${TEST_NAME}" "${SERVICE_NAME}" "${CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}"
+ The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
- The stderr should satisfy spec_expect_no_message "Logged into registry *${TEST_REGISTRY} for config ${CONFIG}"
- The stderr should satisfy spec_expect_message "${SKIP_UPDATING_ALL}.*${SKIP_REASON_PREVIOUS_ERRORS}"
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
+ The stderr should satisfy spec_expect_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${CONFIG}"
+ The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}"
+ The stderr should satisfy spec_expect_no_message "${CONFIG_IS_NOT_A_DIRECTORY}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_INSPECT_FAILURE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}"
- The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*"
- The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${NUM_SERVICES_UPDATING}"
+ The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config ${CONFIG}.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--with-registry-auth.*${SERVICE_NAME}"
+ The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${FAILED_TO_ROLLBACK}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${ROLLED_BACK}.*${SERVICE_NAME}"
- The stderr should satisfy spec_expect_message "${NO_SERVICES_UPDATED}"
- The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_no_message "${NO_SERVICES_UPDATED}"
+ The stderr should satisfy spec_expect_message "1 ${SERVICES_UPDATED}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATE_FAILED}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_ERRORS}"
- The stderr should satisfy spec_expect_message "${NO_IMAGES_TO_REMOVE}"
- The stderr should satisfy spec_expect_no_message "${REMOVING_NUM_IMAGES}"
+ The stderr should satisfy spec_expect_no_message "${NO_IMAGES_TO_REMOVE}"
+ The stderr should satisfy spec_expect_message "${REMOVING_NUM_IMAGES}"
The stderr should satisfy spec_expect_no_message "${SKIP_REMOVING_IMAGES}"
- The stderr should satisfy spec_expect_no_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
+ The stderr should satisfy spec_expect_message "${REMOVED_IMAGE}.*${IMAGE_WITH_TAG}"
The stderr should satisfy spec_expect_no_message "${FAILED_TO_REMOVE_IMAGE}.*${IMAGE_WITH_TAG}"
End
End
diff --git a/tests/gantry_manifest_spec.sh b/tests/gantry_manifest_spec.sh
index df3539e..278e560 100644
--- a/tests/gantry_manifest_spec.sh
+++ b/tests/gantry_manifest_spec.sh
@@ -37,11 +37,13 @@ Describe 'manifest-command'
When run test_MANIFEST_CMD_none "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
# Do not set GANTRY_SERVICES_SELF, it should be set autoamtically
# If we are not testing gantry inside a container, it should failed to find the service name.
# To test gantry container, we need to use run_gantry_container.
- The stderr should satisfy spec_expect_no_message ".*GRANTRY_SERVICES_SELF.*"
+ The stderr should satisfy spec_expect_no_message ".*GANTRY_SERVICES_SELF.*"
# Gantry is still trying to update the service.
# But it will see no new images.
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
@@ -87,7 +89,9 @@ Describe 'manifest-command'
When run test_MANIFEST_CMD_none_SERVICES_SELF "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message ".*GANTRY_SERVICES_SELF.*"
The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}"
The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_CURRENT_IS_LATEST}"
@@ -130,7 +134,9 @@ Describe 'manifest-command'
When run test_MANIFEST_CMD_manifest "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--insecure.*"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
@@ -166,9 +172,9 @@ Describe 'manifest-command'
# export GANTRY_MANIFEST_CMD="manifest"
# export GANTRY_MANIFEST_OPTIONS="--insecure"
local LABEL_AND_VALUE="gantry.manifest.cmd=manifest"
- docker service update --quiet --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
LABEL_AND_VALUE="gantry.manifest.options=--insecure"
- docker service update --quiet --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
run_gantry "${TEST_NAME}"
}
BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
@@ -177,7 +183,9 @@ Describe 'manifest-command'
When run test_MANIFEST_CMD_label "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--insecure.*"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
@@ -219,7 +227,9 @@ Describe 'manifest-command'
When run test_MANIFEST_CMD_unsupported_cmd "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
# No options are added to the unknwon command.
The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}"
The stderr should satisfy spec_expect_message "Unknown MANIFEST_CMD.*unsupported_cmd"
@@ -272,7 +282,9 @@ Describe 'manifest-command'
When run test_MANIFEST_CMD_failure "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}"
The stderr should satisfy spec_expect_message "Image.*${IMAGE_WITH_TAG}.*${IMAGE_NOT_EXIST}"
The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_MANIFEST_FAILURE}"
diff --git a/tests/gantry_notify_spec.sh b/tests/gantry_notify_spec.sh
index 8d56b5c..f2d58c8 100644
--- a/tests/gantry_notify_spec.sh
+++ b/tests/gantry_notify_spec.sh
@@ -97,6 +97,7 @@ Describe 'notify'
The stdout should satisfy spec_expect_message "Subject.*1 services updated 0 failed TEST_TITLE"
The stdout should satisfy spec_expect_message "${TOTAL_EMAIL_COUNT_IS_ONE}"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -149,6 +150,7 @@ Describe 'notify'
The stdout should satisfy spec_expect_message "Subject.*0 services updated 0 failed TEST_TITLE"
The stdout should satisfy spec_expect_message "${TOTAL_EMAIL_COUNT_IS_ONE}"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_CURRENT_IS_LATEST}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -191,7 +193,9 @@ Describe 'notify'
When run test_notify_apprise_bad_url "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -245,6 +249,7 @@ Describe 'notify'
The stdout should satisfy spec_expect_message "Subject.*1 services updated 0 failed TEST_TITLE"
The stdout should satisfy spec_expect_message "${TOTAL_EMAIL_COUNT_IS_ONE}"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -290,8 +295,10 @@ Describe 'notify'
When run test_notify_on_change_no_updates "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stdout should satisfy spec_expect_no_message "TEST_TITLE"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_CURRENT_IS_LATEST}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -346,6 +353,7 @@ Describe 'notify'
The stdout should satisfy spec_expect_message "Subject.*0 services updated 1 failed TEST_TITLE"
The stdout should satisfy spec_expect_message "${TOTAL_EMAIL_COUNT_IS_ONE}"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
diff --git a/tests/gantry_parallel_spec.sh b/tests/gantry_parallel_spec.sh
index 37d5677..6271a7e 100644
--- a/tests/gantry_parallel_spec.sh
+++ b/tests/gantry_parallel_spec.sh
@@ -61,7 +61,9 @@ Describe 'service-parallel'
When run test_parallel_less_workers "${TEST_NAME}" "${SERVICE_NAME}" "${MAX_SERVICES_NUM}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
for NUM in $(seq 0 "${MAX_SERVICES_NUM}"); do
SERVICE_NAME_NUM="${SERVICE_NAME}-${NUM}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.* ${SERVICE_NAME_NUM} "
@@ -112,7 +114,9 @@ Describe 'service-parallel'
When run test_parallel_more_workers "${TEST_NAME}" "${SERVICE_NAME}" "${MAX_SERVICES_NUM}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
for NUM in $(seq 0 "${MAX_SERVICES_NUM}"); do
SERVICE_NAME_NUM="${SERVICE_NAME}-${NUM}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.* ${SERVICE_NAME_NUM} "
@@ -152,7 +156,9 @@ Describe 'service-parallel'
When run test_parallel_GANTRY_MANIFEST_NUM_WORKERS_not_a_number "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "GANTRY_MANIFEST_NUM_WORKERS ${MUST_BE_A_NUMBER}.*"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
@@ -193,7 +199,9 @@ Describe 'service-parallel'
When run test_parallel_GANTRY_UPDATE_NUM_WORKERS_not_a_number "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "GANTRY_UPDATE_NUM_WORKERS ${MUST_BE_A_NUMBER}.*"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
diff --git a/tests/gantry_rollback_spec.sh b/tests/gantry_rollback_spec.sh
index 3f97ad5..aff493c 100644
--- a/tests/gantry_rollback_spec.sh
+++ b/tests/gantry_rollback_spec.sh
@@ -39,7 +39,9 @@ Describe 'rollback'
When run test_rollback_due_to_timeout "${TEST_NAME}" "${SERVICE_NAME}" "${TIMEOUT}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -86,7 +88,9 @@ Describe 'rollback'
When run test_rollback_failed "${TEST_NAME}" "${SERVICE_NAME}" "${TIMEOUT}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -131,7 +135,9 @@ Describe 'rollback'
When run test_rollback_ROLLBACK_ON_FAILURE_false "${TEST_NAME}" "${SERVICE_NAME}" "${TIMEOUT}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -169,7 +175,7 @@ Describe 'rollback'
export GANTRY_UPDATE_TIMEOUT_SECONDS="NotANumber"
# Assume service update won't be done within TIMEOUT second.
local LABEL_AND_VALUE="gantry.update.timeout_seconds=${TIMEOUT}"
- docker service update --quiet --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
run_gantry "${TEST_NAME}"
}
BeforeEach "common_setup_timeout ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME} ${TIMEOUT}"
@@ -178,7 +184,9 @@ Describe 'rollback'
When run test_rollback_lable_due_to_timeout "${TEST_NAME}" "${SERVICE_NAME}" "${TIMEOUT}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -217,11 +225,11 @@ Describe 'rollback'
export GANTRY_ROLLBACK_OPTIONS="--insecure"
# Assume service update won't be done within TIMEOUT second.
local LABEL_AND_VALUE="gantry.update.timeout_seconds=${TIMEOUT}"
- docker service update --quiet --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
# Rollback would fail due to the incorrect option.
# --with-registry-auth cannot be combined with --rollback.
LABEL_AND_VALUE="gantry.rollback.options=--with-registry-auth"
- docker service update --quiet --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
run_gantry "${TEST_NAME}"
}
BeforeEach "common_setup_timeout ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME} ${TIMEOUT}"
@@ -230,7 +238,9 @@ Describe 'rollback'
When run test_rollback_label_failed "${TEST_NAME}" "${SERVICE_NAME}" "${TIMEOUT}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -268,9 +278,9 @@ Describe 'rollback'
export GANTRY_UPDATE_TIMEOUT_SECONDS="NotANumber"
# Assume service update won't be done within TIMEOUT second.
local LABEL_AND_VALUE="gantry.update.timeout_seconds=${TIMEOUT}"
- docker service update --quiet --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
LABEL_AND_VALUE="gantry.rollback.on_failure=false"
- docker service update --quiet --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
run_gantry "${TEST_NAME}"
}
BeforeEach "common_setup_timeout ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME} ${TIMEOUT}"
@@ -279,7 +289,9 @@ Describe 'rollback'
When run test_rollback_label_ROLLBACK_ON_FAILURE_false "${TEST_NAME}" "${SERVICE_NAME}" "${TIMEOUT}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
diff --git a/tests/gantry_service_multiple_spec.sh b/tests/gantry_service_multiple_spec.sh
index 8a087ae..90ac14e 100644
--- a/tests/gantry_service_multiple_spec.sh
+++ b/tests/gantry_service_multiple_spec.sh
@@ -86,7 +86,9 @@ Describe 'service-multiple-services'
When run test_multiple_services_excluded_filters "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
# Service 0 and 3 should get updated.
# Service 1 and 2 should be excluded.
# Service 4 and 5 created with new image, no update.
diff --git a/tests/gantry_service_no_running_tasks_spec.sh b/tests/gantry_service_no_running_tasks_spec.sh
index 2f8144e..461c6af 100644
--- a/tests/gantry_service_no_running_tasks_spec.sh
+++ b/tests/gantry_service_no_running_tasks_spec.sh
@@ -38,15 +38,14 @@ Describe "service-no-running-tasks"
start_replicated_service "${SERVICE_NAME}" "${IMAGE_WITH_TAG}"
start_replicated_service "${SERVICE_NAME_SUFFIX}" "${IMAGE_WITH_TAG}"
build_and_push_test_image "${IMAGE_WITH_TAG}"
+ # Set running tasks to 0 for SERVICE_NAME.
+ # But keep tasks running for SERVICE_NAME_SUFFIX.
+ docker_service_update --replicas=0 "${SERVICE_NAME}"
+ wait_zero_running_tasks "${SERVICE_NAME}"
}
test_no_running_tasks_replicated() {
local TEST_NAME="${1}"
local SERVICE_NAME="${2}"
- local SERVICE_NAME_SUFFIX="${SERVICE_NAME}-suffix"
- # Set running tasks to 0 for SERVICE_NAME.
- # But keep tasks running for SERVICE_NAME_SUFFIX.
- docker service update --quiet --replicas=0 "${SERVICE_NAME}"
- wait_zero_running_tasks "${SERVICE_NAME}"
reset_gantry_env "${SERVICE_NAME}"
run_gantry "${TEST_NAME}"
}
@@ -66,7 +65,9 @@ Describe "service-no-running-tasks"
When run test_no_running_tasks_replicated "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
# Add "--detach=true" when there is no running tasks.
# https://github.com/docker/cli/issues/627
The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--detach=true.*${SERVICE_NAME}\."
@@ -126,7 +127,9 @@ Describe "service-no-running-tasks"
When run test_no_running_tasks_global "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
# Add "--detach=true" when there is no running tasks.
# https://github.com/docker/cli/issues/627
The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--detach=true.*${SERVICE_NAME}"
diff --git a/tests/gantry_service_single_spec.sh b/tests/gantry_service_single_spec.sh
index 061963b..5f9ea18 100644
--- a/tests/gantry_service_single_spec.sh
+++ b/tests/gantry_service_single_spec.sh
@@ -35,7 +35,9 @@ Describe 'service-single-service'
When run test_new_image_no "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_CURRENT_IS_LATEST}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -76,7 +78,9 @@ Describe 'service-single-service'
When run test_new_image_yes "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -127,7 +131,9 @@ Describe 'service-single-service'
When run test_new_image_no_digest "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_DIGEST_IS_EMPTY}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
diff --git a/tests/gantry_update_options_spec.sh b/tests/gantry_update_options_spec.sh
index deca3d8..8ff1e17 100644
--- a/tests/gantry_update_options_spec.sh
+++ b/tests/gantry_update_options_spec.sh
@@ -56,7 +56,9 @@ Describe 'update-options'
When run test_update_jobs_skipping "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
# Check whether it is a job before checking whether there is a new image.
The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME_SUFFIX}.*${SKIP_REASON_IS_JOB}"
The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME_SUFFIX}"
@@ -101,7 +103,9 @@ Describe 'update-options'
When run test_update_jobs_UPDATE_JOBS_true "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -137,12 +141,12 @@ Describe 'update-options'
# label should override the global environment variable.
export GANTRY_UPDATE_JOBS="false"
local LABEL_AND_VALUE="gantry.update.jobs=true"
- docker service update --quiet --detach=true --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --detach=true --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
# label should override the global environment variable.
export GANTRY_UPDATE_OPTIONS="--incorrect-option"
# The job may not reach the desired "Complete" state and blocking update CLI. So add "--detach=true"
LABEL_AND_VALUE="gantry.update.options=--detach=true"
- docker service update --quiet --detach=true --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --detach=true --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
run_gantry "${TEST_NAME}"
}
BeforeEach "common_setup_job ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
@@ -151,7 +155,9 @@ Describe 'update-options'
When run test_update_jobs_label_UPDATE_JOBS_true "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -181,23 +187,32 @@ Describe 'update-options'
IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}")
SERVICE_NAME="gantry-test-$(unique_id)"
TASK_SECONDS=15
- test_update_jobs_no_running_tasks() {
+ test_start() {
local TEST_NAME="${1}"
- local SERVICE_NAME="${2}"
+ local IMAGE_WITH_TAG="${2}"
+ local SERVICE_NAME="${3}"
+ local TASK_SECONDS="${4}"
+ common_setup_job "${TEST_NAME}" "${IMAGE_WITH_TAG}" "${SERVICE_NAME}" "${TASK_SECONDS}"
# The tasks should exit after TASK_SECONDS seconds sleep. Then it will have 0 running tasks.
wait_zero_running_tasks "${SERVICE_NAME}"
+ }
+ test_update_jobs_no_running_tasks() {
+ local TEST_NAME="${1}"
+ local SERVICE_NAME="${2}"
reset_gantry_env "${SERVICE_NAME}"
export GANTRY_UPDATE_JOBS="true"
run_gantry "${TEST_NAME}"
}
# The task will finish in ${TASK_SECONDS} seconds
- BeforeEach "common_setup_job ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME} ${TASK_SECONDS}"
+ BeforeEach "test_start ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME} ${TASK_SECONDS}"
AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}"
It 'run_test'
When run test_update_jobs_no_running_tasks "${TEST_NAME}" "${SERVICE_NAME}"
The status should be success
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--detach=true.*${SERVICE_NAME}"
# Cannot add "--replicas" to replicated job
The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--replicas=0"
@@ -258,6 +273,7 @@ Describe 'update-options'
The stdout should satisfy spec_expect_no_message "Before updating: LABEL_VALUE=.*${SERVICE_NAME}"
The stdout should satisfy spec_expect_message "After updating: LABEL_VALUE=.*${SERVICE_NAME}"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -301,7 +317,7 @@ Describe 'update-options'
# label should override the global environment variable.
export GANTRY_UPDATE_OPTIONS="--incorrect-option"
local LABEL_AND_VALUE="gantry.update.options=--label-add=${LABEL}=${SERVICE_NAME}"
- docker service update --quiet --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
+ docker_service_update --label-add "${LABEL_AND_VALUE}" "${SERVICE_NAME}"
local RETURN_VALUE=
run_gantry "${TEST_NAME}"
RETURN_VALUE="${?}"
@@ -319,6 +335,7 @@ Describe 'update-options'
The stdout should satisfy spec_expect_no_message "Before updating: LABEL_VALUE=.*${SERVICE_NAME}"
The stdout should satisfy spec_expect_message "After updating: LABEL_VALUE=.*${SERVICE_NAME}"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}"
@@ -359,7 +376,9 @@ Describe 'update-options'
When run test_update_UPDATE_TIMEOUT_SECONDS_not_a_number "${TEST_NAME}" "${SERVICE_NAME}"
The status should be failure
The stdout should satisfy display_output
+ The stdout should satisfy spec_expect_no_message ".+"
The stderr should satisfy display_output
+ The stderr should satisfy spec_expect_no_message "${NOT_START_WITH_A_SQUARE_BRACKET}"
The stderr should satisfy spec_expect_message "UPDATE_TIMEOUT_SECONDS ${MUST_BE_A_NUMBER}.*"
The stderr should satisfy spec_expect_no_message "${SKIP_UPDATING}.*${SERVICE_NAME}"
The stderr should satisfy spec_expect_message "${PERFORM_UPDATING}.*${SERVICE_NAME}.*${PERFORM_REASON_HAS_NEWER_IMAGE}"
diff --git a/tests/spec_gantry_test_helper.sh b/tests/spec_gantry_test_helper.sh
index 5c36196..84080ff 100644
--- a/tests/spec_gantry_test_helper.sh
+++ b/tests/spec_gantry_test_helper.sh
@@ -18,7 +18,12 @@
set -a
# Constant strings for checks.
+# NOT_START_WITH_A_SQUARE_BRACKET ignores color codes. Use test_log not to trigger this check.
+export NOT_START_WITH_A_SQUARE_BRACKET="^(?!(?:\x1b\[[0-9;]*[mG])?\[)"
+export GANTRY_AUTH_CONFIG_LABEL="gantry.auth.config"
export MUST_BE_A_NUMBER="must be a number"
+export LOGGED_INTO_REGISTRY="Logged into registry"
+export FAILED_TO_LOGIN_TO_REGISTRY="Failed to login to registry"
export SKIP_UPDATING_ALL="Skip updating all services"
export SKIP_REASON_NOT_SWARM_MANAGER="is not a swarm manager"
export SKIP_REASON_PREVIOUS_ERRORS="due to previous error\(s\)"
@@ -34,6 +39,7 @@ export PERFORM_REASON_KNOWN_NEWER_IMAGE="because there is a known newer version
export PERFORM_REASON_DIGEST_IS_EMPTY="because DIGEST is empty"
export PERFORM_REASON_HAS_NEWER_IMAGE="because there is a newer version"
export IMAGE_NOT_EXIST="does not exist or it is not available"
+export CONFIG_IS_NOT_A_DIRECTORY="is not a directory that contains Docker configuration files"
export ADDING_OPTIONS="Adding options"
export NUM_SERVICES_SKIP_JOBS="Skip updating [0-9]+ service\(s\) due to they are job\(s\)"
export NUM_SERVICES_INSPECT_FAILURE="Failed to inspect [0-9]+ service\(s\)"
@@ -57,10 +63,27 @@ export FAILED_TO_REMOVE_IMAGE="Failed to remove image"
export SCHEDULE_NEXT_UPDATE_AT="Schedule next update at"
export SLEEP_SECONDS_BEFORE_NEXT_UPDATE="Sleep [0-9]+ seconds before next update"
+test_log() {
+ echo "${GANTRY_LOG_LEVEL}" | grep -q -i "^NONE$" && return 0;
+ [ -n "${GANTRY_IMAGES_TO_REMOVE}" ] && echo "${*}" >&2 && return 0;
+ echo "[$(date -Iseconds)] Test: ${*}" >&2
+}
+
display_output() {
echo "${display_output:-""}"
}
+check_login_input() {
+ local REGISTRY="${1}"
+ local USERNAME="${2}"
+ local PASSWORD="${3}"
+ if [ -z "${REGISTRY}" ] || [ -z "${USERNAME}" ] || [ -z "${PASSWORD}" ]; then
+ echo "No REGISTRY, USERNAME or PASSWORD provided." >&2
+ return 1
+ fi
+ return 0
+}
+
common_setup_new_image() {
local TEST_NAME="${1}"
local IMAGE_WITH_TAG="${2}"
@@ -200,12 +223,73 @@ _next_available_port() {
echo "${PORT}"
}
+_get_docker_config_file() {
+ local REGISTRY="${1:?}"
+ REGISTRY=$(echo "${REGISTRY}" | tr ':' '-')
+ echo "/tmp/TEST_DOCKER_CONFIG-${REGISTRY}"
+}
+
+_get_docker_config_argument() {
+ local IMAGE_WITH_TAG="${1:?}"
+ local REGISTRY=
+ REGISTRY=$(echo "${IMAGE_WITH_TAG}" | cut -d '/' -f 1)
+ local CONFIG=
+ CONFIG=$(_get_docker_config_file "${REGISTRY}") || return 1
+ [ -d "${CONFIG}" ] && echo "--config ${CONFIG}"
+}
+
+_login_test_registry() {
+ local ENFORCE_LOGIN="${1}"
+ local REGISTRY="${2}"
+ local USERNAME="${3}"
+ local PASSWORD="${4}"
+ if ! _enforce_login_enabled "${ENFORCE_LOGIN}"; then
+ return 0
+ fi
+ echo "Logging in ${REGISTRY}."
+ local CONFIG=
+ CONFIG=$(_get_docker_config_file "${REGISTRY}") || return 1
+ echo "${PASSWORD}" | docker --config "${CONFIG}" login --username="${USERNAME}" --password-stdin "${REGISTRY}" 2>&1
+}
+
+_logout_test_registry() {
+ local ENFORCE_LOGIN="${1}"
+ local REGISTRY="${2}"
+ if ! _enforce_login_enabled "${ENFORCE_LOGIN}"; then
+ return 0
+ fi
+ echo "Logging out ${REGISTRY}."
+ local CONFIG=
+ CONFIG=$(_get_docker_config_file "${REGISTRY}") || return 1
+ docker --config "${CONFIG}" logout
+ [ -d "${CONFIG}" ] && rm -r "${CONFIG}"
+}
+
_get_test_registry_file() {
local SUITE_NAME="${1:?}"
SUITE_NAME=$(echo "${SUITE_NAME}" | tr ' ' '-')
echo "/tmp/TEST_REGISTRY-${SUITE_NAME}"
}
+_remove_test_registry_file() {
+ local SUITE_NAME="${1:?}"
+ local REGISTRY_FILE=
+ REGISTRY_FILE=$(_get_test_registry_file "${SUITE_NAME}") || return 1
+ rm "${REGISTRY_FILE}"
+}
+
+_store_test_registry() {
+ local SUITE_NAME="${1:?}"
+ local TEST_REGISTRY="${2}"
+ local REGISTRY_FILE=
+ if ! REGISTRY_FILE=$(_get_test_registry_file "${SUITE_NAME}" 2>&1); then
+ echo "_store_test_registry error: ${REGISTRY_FILE}" >&2
+ return 1
+ fi
+ echo "Suite \"${SUITE_NAME}\" uses registry ${TEST_REGISTRY}."
+ echo "${TEST_REGISTRY}" > "${REGISTRY_FILE}"
+}
+
load_test_registry() {
local SUITE_NAME="${1:?}"
local REGISTRY_FILE=
@@ -216,6 +300,7 @@ load_test_registry() {
_start_registry() {
local SUITE_NAME="${1:?}"
+ local ENFORCE_LOGIN="${2}"
SUITE_NAME=$(echo "${SUITE_NAME}" | tr ' ' '-')
local SUITE_NAME_LENGTH="${#SUITE_NAME}"
local REGISTRY_SERVICE_NAME="gantry-test-registry-${SUITE_NAME}"
@@ -239,9 +324,10 @@ _start_registry() {
fi
stop_service "${REGISTRY_SERVICE_NAME}" 1>/dev/null 2>&1
TEST_REGISTRY="${REGISTRY_BASE}:${REGISTRY_PORT}"
- echo "${SUITE_NAME} starting registry ${TEST_REGISTRY} "
+ echo "Suite \"${SUITE_NAME}\" starts registry ${TEST_REGISTRY} "
# SC2046 (warning): Quote this to prevent word splitting.
- # shellcheck disable=SC2046
+ # SC2086 (info): Double quote to prevent globbing and word splitting.
+ # shellcheck disable=SC2046,SC2086
if docker service create --quiet \
--name "${REGISTRY_SERVICE_NAME}" \
--restart-condition "on-failure" \
@@ -249,6 +335,7 @@ _start_registry() {
$(_location_constraints) \
--mode=replicated \
-p "${REGISTRY_PORT}:5000" \
+ $(_add_htpasswd "${ENFORCE_LOGIN}" "${TEST_USERNAME}" "${TEST_PASSWORD}") \
"${REGISTRY_IMAGE}" 2>&1; then
break;
fi
@@ -260,31 +347,27 @@ _start_registry() {
REGISTRY_PORT=$((REGISTRY_PORT+1))
sleep 1
done
- local REGISTRY_FILE=
- if ! REGISTRY_FILE=$(_get_test_registry_file "${SUITE_NAME}" 2>&1); then
- echo "_start_registry _get_test_registry_file error: ${REGISTRY_FILE}" >&2
- return 1
- fi
- echo "${SUITE_NAME} uses registry ${TEST_REGISTRY}."
- echo "${TEST_REGISTRY}" > "${REGISTRY_FILE}"
+ _store_test_registry "${SUITE_NAME}" "${TEST_REGISTRY}" || return 1;
+ _login_test_registry "${ENFORCE_LOGIN}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}" || return 1;
}
_stop_registry() {
local SUITE_NAME="${1:?}"
+ local ENFORCE_LOGIN="${2}"
SUITE_NAME=$(echo "${SUITE_NAME}" | tr ' ' '-')
local REGISTRY_SERVICE_NAME="gantry-test-registry-${SUITE_NAME}"
local REGISTRY=
REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1
echo "Removing registry ${REGISTRY} "
stop_service "${REGISTRY_SERVICE_NAME}"
- local REGISTRY_FILE=
- REGISTRY_FILE=$(_get_test_registry_file "${SUITE_NAME}") || return 1
- rm "${REGISTRY_FILE}"
+ _logout_test_registry "${ENFORCE_LOGIN}" "${REGISTRY}" || return 1
+ _remove_test_registry_file "${SUITE_NAME}" || return 1
return 0
}
initialize_all_tests() {
local SUITE_NAME="${1:-"gantry"}"
+ local ENFORCE_LOGIN="${2}"
SUITE_NAME=$(echo "${SUITE_NAME}" | tr ' ' '-')
local SCRIPT_DIR=
SCRIPT_DIR="$(_get_script_dir)" || return 1
@@ -293,14 +376,15 @@ initialize_all_tests() {
echo "== Starting suite ${SUITE_NAME}"
echo "=============================="
_init_swarm
- _start_registry "${SUITE_NAME}"
+ _start_registry "${SUITE_NAME}" "${ENFORCE_LOGIN}"
}
# finish_all_tests should return non zero when there are errors.
finish_all_tests() {
local SUITE_NAME="${1:-"gantry"}"
+ local ENFORCE_LOGIN="${2}"
SUITE_NAME=$(echo "${SUITE_NAME}" | tr ' ' '-')
- _stop_registry "${SUITE_NAME}"
+ _stop_registry "${SUITE_NAME}" "${ENFORCE_LOGIN}"
echo "=============================="
echo "== Finished all tests in ${SUITE_NAME}"
echo "=============================="
@@ -442,7 +526,8 @@ unique_id() {
# To reduce the possibility that tests run in parallel on the same machine affect each other.
local PID="$$"
local RANDOM_STR=
- RANDOM_STR=$(head /dev/urandom | LANG=C tr -dc 'A-Za-z0-9' | head -c 8)
+ # repository name must be lowercase
+ RANDOM_STR=$(head /dev/urandom | LANG=C tr -dc 'a-z0-9' | head -c 8)
echo "$(date +%s)-${PID}-${RANDOM_STR}"
}
@@ -474,16 +559,22 @@ build_and_push_test_image() {
local TASK_SECONDS="${2}"
local EXIT_SECONDS="${3}"
build_test_image "${IMAGE_WITH_TAG}" "${TASK_SECONDS}" "${EXIT_SECONDS}"
- echo "Pushing image "
- docker push --quiet "${IMAGE_WITH_TAG}"
+ echo -n "Pushing image "
+ # SC2046 (warning): Quote this to prevent word splitting.
+ # shellcheck disable=SC2046
+ docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") push --quiet "${IMAGE_WITH_TAG}"
}
prune_local_test_image() {
local IMAGE_WITH_TAG="${1}"
- echo "Removing image ${IMAGE_WITH_TAG} "
+ echo -n "Removing image ${IMAGE_WITH_TAG} "
docker image rm "${IMAGE_WITH_TAG}" --force
}
+docker_service_update() {
+ docker service update --quiet "${@}" >/dev/null
+}
+
wait_zero_running_tasks() {
local SERVICE_NAME="${1}"
local TIMEOUT_SECONDS="${2}"
@@ -540,6 +631,32 @@ _location_constraints() {
echo "${ARGS}"
}
+_enforce_login_enabled() {
+ local ENFORCE_LOGIN="${1}"
+ test "${ENFORCE_LOGIN}" == "ENFORCE_LOGIN"
+}
+
+_add_htpasswd() {
+ local ENFORCE_LOGIN="${1}"
+ local USER="${2}"
+ local PASS="${3}"
+ if ! _enforce_login_enabled "${ENFORCE_LOGIN}"; then
+ return 0
+ fi
+ local HTTPD_IMAGE="httpd:2"
+ # https://distribution.github.io/distribution/about/deploying/#native-basic-auth
+ local PASSWD=
+ PASSWD="$(mktemp)"
+ if ! docker image inspect "${HTTPD_IMAGE}" > /dev/null 2>&1; then
+ docker pull "${HTTPD_IMAGE}" > /dev/null
+ fi
+ docker_run --entrypoint htpasswd "${HTTPD_IMAGE}" -Bbn "${USER}" "${PASS}" > "${PASSWD}"
+ echo "--mount type=bind,source=${PASSWD},target=${PASSWD} \
+ -e REGISTRY_AUTH=htpasswd \
+ -e REGISTRY_AUTH_HTPASSWD_REALM=RegistryRealm \
+ -e REGISTRY_AUTH_HTPASSWD_PATH=${PASSWD} "
+}
+
_wait_service_state() {
local SERVICE_NAME="${1}"
local STATE="${2}"
@@ -562,10 +679,11 @@ start_replicated_service() {
echo "Creating service ${SERVICE_NAME} in replicated mode "
# SC2046 (warning): Quote this to prevent word splitting.
# shellcheck disable=SC2046
- timeout 120 docker service create --quiet \
+ timeout 120 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \
--name "${SERVICE_NAME}" \
--restart-condition "on-failure" \
--restart-max-attempts 5 \
+ --with-registry-auth \
$(_location_constraints) \
--mode=replicated \
"${IMAGE_WITH_TAG}"
@@ -578,10 +696,11 @@ start_global_service() {
echo "Creating service ${SERVICE_NAME} in global mode "
# SC2046 (warning): Quote this to prevent word splitting.
# shellcheck disable=SC2046
- timeout 120 docker service create --quiet \
+ timeout 120 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \
--name "${SERVICE_NAME}" \
--restart-condition "on-failure" \
--restart-max-attempts 5 \
+ --with-registry-auth \
$(_location_constraints) \
--mode=global \
"${IMAGE_WITH_TAG}"
@@ -594,10 +713,11 @@ _start_replicated_job() {
echo "Creating service ${SERVICE_NAME} in replicated job mode "
# SC2046 (warning): Quote this to prevent word splitting.
# shellcheck disable=SC2046
- timeout 120 docker service create --quiet \
+ timeout 120 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \
--name "${SERVICE_NAME}" \
--restart-condition "on-failure" \
--restart-max-attempts 5 \
+ --with-registry-auth \
$(_location_constraints) \
--mode=replicated-job --detach=true \
"${IMAGE_WITH_TAG}"
@@ -607,7 +727,7 @@ _start_replicated_job() {
stop_service() {
local SERVICE_NAME="${1}"
- echo "Removing service "
+ echo -n "Removing service "
docker service rm "${SERVICE_NAME}"
}
@@ -668,9 +788,7 @@ _run_gantry_container() {
MOUNT_OPTIONS=$(_add_file_to_mount_options "${MOUNT_OPTIONS}" "${GANTRY_REGISTRY_HOST_FILE}")
MOUNT_OPTIONS=$(_add_file_to_mount_options "${MOUNT_OPTIONS}" "${GANTRY_REGISTRY_PASSWORD_FILE}")
MOUNT_OPTIONS=$(_add_file_to_mount_options "${MOUNT_OPTIONS}" "${GANTRY_REGISTRY_USER_FILE}")
- if [ "${GANTRY_LOG_LEVEL}" != "NONE" ]; then
- echo "Starting SUT service ${SERVICE_NAME} with image ${SUT_REPO_TAG}."
- fi
+ test_log "Starting SUT service ${SERVICE_NAME} with image ${SUT_REPO_TAG}."
local RETURN_VALUE=0
local CMD_OUTPUT=
# SC2086 (info): Double quote to prevent globbing and word splitting.