blob: 1215ebde2c833c1c5c2b51aa350253f43c2d9880 [file] [log] [blame]
#!/bin/bash
# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
LOCAL_ENV="$( cd "${LOCATION}/../setup_local_env" >/dev/null 2>&1 && pwd )"
GERRIT_BRANCH=stable-3.4
GERRIT_CI=https://gerrit-ci.gerritforge.com/view/Plugins-$GERRIT_BRANCH/job
LAST_BUILD=lastSuccessfulBuild/artifact/bazel-bin/plugins
DEF_MULTISITE_LOCATION=${LOCATION}/../../../bazel-bin/plugins/multi-site/multi-site.jar
DEF_GERRIT_IMAGE=3.4.0-centos8
DEF_GERRIT_HEALTHCHECK_START_PERIOD=60s
DEF_GERRIT_HEALTHCHECK_INTERVAL=5s
DEF_GERRIT_HEALTHCHECK_TIMEOUT=5s
DEF_GERRIT_HEALTHCHECK_RETRIES=5
function check_application_requirements {
type java >/dev/null 2>&1 || { echo >&2 "Require java but it's not installed. Aborting."; exit 1; }
type docker >/dev/null 2>&1 || { echo >&2 "Require docker but it's not installed. Aborting."; exit 1; }
type docker-compose >/dev/null 2>&1 || { echo >&2 "Require docker-compose but it's not installed. Aborting."; exit 1; }
type wget >/dev/null 2>&1 || { echo >&2 "Require wget but it's not installed. Aborting."; exit 1; }
type envsubst >/dev/null 2>&1 || { echo >&2 "Require envsubst but it's not installed. Aborting."; exit 1; }
type openssl >/dev/null 2>&1 || { echo >&2 "Require openssl but it's not installed. Aborting."; exit 1; }
type git >/dev/null 2>&1 || { echo >&2 "Require git but it's not installed. Aborting."; exit 1; }
}
function setup_zookeeper_config {
SOURCE_ZOOKEEPER_CONFIG=${LOCAL_ENV}/configs/zookeeper-refdb.config
DESTINATION_ZOOKEEPER_CONFIG=$1
export ZK_HOST=zookeeper
export ZK_PORT=2181
echo "Replacing variables for file ${SOURCE_ZOOKEEPER_CONFIG} and copying to ${DESTINATION_ZOOKEEPER_CONFIG}"
cat $SOURCE_ZOOKEEPER_CONFIG | envsubst | sed 's/#{name}#/${name}/g' > $DESTINATION_ZOOKEEPER_CONFIG
}
function setup_replication_config {
SOURCE_REPLICATION_CONFIG=${LOCAL_ENV}/configs/replication.config
DESTINATION_REPLICATION_CONFIG=$1
export REPLICATION_URL="url = $2"
export REPLICATION_DELAY_SEC=1
echo "Replacing variables for file ${SOURCE_REPLICATION_CONFIG} and copying to ${DESTINATION_REPLICATION_CONFIG}"
cat $SOURCE_REPLICATION_CONFIG | envsubst | sed 's/#{name}#/${name}/g' > $DESTINATION_REPLICATION_CONFIG
}
function setup_gerrit_config {
SOURCE_RGERRIT_CONFIG=${LOCAL_ENV}/configs/gerrit.config
DESTINATION_GERRIT_CONFIG=$1
export BROKER_HOST=$2
export BROKER_PORT=$3
export INSTANCE_ID=$4
export SSH_ADVERTISED_PORT=$5
export LOCATION_TEST_SITE=/var/gerrit
export REMOTE_DEBUG_PORT=5005
export GERRIT_SSHD_PORT=29418
export HTTP_PROTOCOL=http
export GERRIT_HTTPD_PORT=8080
echo "Replacing variables for file ${SOURCE_RGERRIT_CONFIG} and copying to ${DESTINATION_GERRIT_CONFIG}"
cat $SOURCE_RGERRIT_CONFIG | envsubst | sed 's/#{name}#/${name}/g' > $DESTINATION_GERRIT_CONFIG
# set plugins for multi-site as mandatory so that gerrit will not start if they are not loaded
declare -a MANDATORY_PLUGINS=(${BROKER_PLUGIN} multi-site replication websession-broker zookeeper-refdb)
for plugin in "${MANDATORY_PLUGINS[@]}"
do
git config --file $DESTINATION_GERRIT_CONFIG --add plugins.mandatory "${plugin}"
done
}
function cleanup_tests_hook {
echo "Shutting down the setup"
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml down -v
echo "Removing setup dir"
rm -rf ${DEPLOYMENT_LOCATION}
}
function check_result {
local CONTAINER_ID=$1
local OLD_RES=$2
if [ $OLD_RES -ne 0 ]; then
return $OLD_RES;
fi
local RES_VAL=$(docker inspect -f '{{ .State.ExitCode }}' "${CONTAINER_ID}")
# first check if RES_VAL (output) is a number
if [[ -z "${RES_VAL##*[!0-9]*}" || $RES_VAL -ne 0 ]]; then
echo "Tests failed. Here is [docker-compose.yaml] content:"
cat "${DEPLOYMENT_LOCATION}/docker-compose.yaml"
echo "Docker logs:"
cat "${DEPLOYMENT_LOCATION}/site.log"
return 1
fi
return 0
}
# Check application requirements
check_application_requirements
while [ $# -ne 0 ]
do
case "$1" in
"--help" )
echo "Usage: sh $0 [--option $value]"
echo
echo "[--gerrit-image] Gerrit docker image to be used for testing; defaults to [${DEF_GERRIT_IMAGE}]"
echo "[--multisite-lib-file] Location to lib multi-site.jar file; defaults to [${DEF_MULTISITE_LOCATION}]"
echo "[--broker-type] events broker type; 'kafka', 'kinesis' or 'gcloud-pubsub'. Default 'kafka' TODO: so far only 'kafka'"
echo "[--start-period] Gerrit start period timeout (until it gets healthy); defaults to [${DEF_GERRIT_HEALTHCHECK_START_PERIOD}]"
echo "[--healthcheck-interval] Every interval Gerrit health check is performed; defaults to [${DEF_GERRIT_HEALTHCHECK_INTERVAL}]"
echo "[--healthcheck-timeout] If a single run of the check takes longer than timeout it is considered a failure; defaults to [${DEF_GERRIT_HEALTHCHECK_TIMEOUT}]"
echo "[--healthcheck-retries] How many consequtive times health check can fail to consider Gerrit server unhealthy; defaults to [${DEF_GERRIT_HEALTHCHECK_RETRIES}]"
echo "[--location] Directory in which this script resides. Needed only when called from 'bazel test'."
echo "[--local-env] 'setup_local_env' directory location. Needed only when called from 'bazel test'."
echo
exit 0
;;
"--gerrit-image" )
GERRIT_IMAGE=$2
shift
shift
;;
"--multisite-lib-file" )
MULTISITE_LIB_LOCATION=$2
shift
shift
;;
"--replication-lib-file" )
REPLICATION_LIB_LOCATION=$2
shift
shift
;;
"--broker-type" )
BROKER_TYPE=$2
shift
shift
if [ ! "$BROKER_TYPE" = "kafka" ] && [ ! "$BROKER_TYPE" = "kinesis" ] && [ ! "$BROKER_TYPE" = "gcloud-pubsub" ]; then
echo >&2 "broker type: '$BROKER_TYPE' not valid. Please supply 'kafka','kinesis' or 'gcloud-pubsub'. Aborting"
exit 1
fi
;;
"--start-period" )
GERRIT_HEALTHCHECK_START_PERIOD=$2
shift
shift
;;
"--healthcheck-interval" )
GERRIT_HEALTHCHECK_INTERVAL=$2
shift
shift
;;
"--healthcheck-timeout" )
GERRIT_HEALTHCHECK_TIMEOUT=$2
shift
shift
;;
"--healthcheck-retries" )
GERRIT_HEALTHCHECK_RETRIES=$2
shift
shift
;;
"--location" )
LOCATION=$2
shift
shift
;;
"--local-env" )
LOCAL_ENV=$2
shift
shift
;;
* )
echo "Unknown option argument: $1"
shift
shift
;;
esac
done
# Defaults
EVENTS_BROKER_VER=`grep 'com.gerritforge:events-broker' ${LOCATION}/../external_plugin_deps.bzl | cut -d '"' -f 2 | cut -d ':' -f 3`
GLOBAL_REFDB_VER=`grep 'com.gerritforge:global-refdb' ${LOCATION}/../external_plugin_deps.bzl | cut -d '"' -f 2 | cut -d ':' -f 3`
DEPLOYMENT_LOCATION=$(mktemp -d || $(echo >&2 "Could not create temp dir" && exit 1))
MULTISITE_LIB_LOCATION=${MULTISITE_LIB_LOCATION:-${DEF_MULTISITE_LOCATION}}
BROKER_TYPE=${BROKER_TYPE:-"kafka"}
GERRIT_IMAGE=${GERRIT_IMAGE:-${DEF_GERRIT_IMAGE}}
GERRIT_HEALTHCHECK_START_PERIOD=${GERRIT_HEALTHCHECK_START_PERIOD:-${DEF_GERRIT_HEALTHCHECK_START_PERIOD}}
GERRIT_HEALTHCHECK_INTERVAL=${GERRIT_HEALTHCHECK_INTERVAL:-${DEF_GERRIT_HEALTHCHECK_INTERVAL}}
GERRIT_HEALTHCHECK_TIMEOUT=${GERRIT_HEALTHCHECK_TIMEOUT:-${DEF_GERRIT_HEALTHCHECK_TIMEOUT}}
GERRIT_HEALTHCHECK_RETRIES=${GERRIT_HEALTHCHECK_RETRIES:-${DEF_GERRIT_HEALTHCHECK_RETRIES}}
# Gerrit primary
GERRIT_1_ETC=${DEPLOYMENT_LOCATION}/etc_1
GERRIT_1_PLUGINS=${DEPLOYMENT_LOCATION}/plugins_1
GERRIT_1_LIBS=${DEPLOYMENT_LOCATION}/libs_1
# Gerrit secondary
GERRIT_2_ETC=${DEPLOYMENT_LOCATION}/etc_2
GERRIT_2_PLUGINS=${DEPLOYMENT_LOCATION}/plugins_2
GERRIT_2_LIBS=${DEPLOYMENT_LOCATION}/libs_2
echo "Deployment location: [${DEPLOYMENT_LOCATION}]"
echo "Downloading common plugins"
COMMON_PLUGINS=${DEPLOYMENT_LOCATION}/common_plugins
mkdir -p ${COMMON_PLUGINS}
echo "plugin location[${MULTISITE_LIB_LOCATION}]"
cp -f $MULTISITE_LIB_LOCATION $COMMON_PLUGINS/multi-site.jar >/dev/null 2>&1 || \
{ echo >&2 "$MULTISITE_LIB_LOCATION: Not able to copy the file. Aborting"; exit 1; }
echo "Downloading websession-broker plugin $GERRIT_BRANCH"
wget $GERRIT_CI/plugin-websession-broker-bazel-$GERRIT_BRANCH/$LAST_BUILD/websession-broker/websession-broker.jar \
-O $COMMON_PLUGINS/websession-broker.jar || { echo >&2 "Cannot download websession-broker plugin: Check internet connection. Aborting"; exit 1; }
echo "Downloading healthcheck plugin $GERRIT_BRANCH"
wget $GERRIT_CI/plugin-healthcheck-bazel-$GERRIT_BRANCH/$LAST_BUILD/healthcheck/healthcheck.jar \
-O $COMMON_PLUGINS/healthcheck.jar || { echo >&2 "Cannot download healthcheck plugin: Check internet connection. Aborting"; exit 1; }
echo "Downloading zookeeper plugin $GERRIT_BRANCH"
wget $GERRIT_CI/plugin-zookeeper-refdb-bazel-$GERRIT_BRANCH/$LAST_BUILD/zookeeper-refdb/zookeeper-refdb.jar \
-O $COMMON_PLUGINS/zookeeper-refdb.jar || { echo >&2 "Cannot download zookeeper plugin: Check internet connection. Aborting"; exit 1; }
if [ "$BROKER_TYPE" = "kafka" ]; then
echo "Downloading events-kafka plugin $GERRIT_BRANCH"
wget $GERRIT_CI/plugin-events-kafka-bazel-$GERRIT_BRANCH/$LAST_BUILD/events-kafka/events-kafka.jar \
-O $COMMON_PLUGINS/events-kafka.jar || { echo >&2 "Cannot download events-kafka plugin: Check internet connection. Aborting"; exit 1; }
BROKER_PORT=9092
BROKER_HOST=kafka
BROKER_PLUGIN=events-kafka
else
#TODO add more broker types handling
echo >&2 "Broker type [${BROKER_TYPE}] not supported. Aborting";
exit 1;
fi
echo "Downloading common libs"
COMMON_LIBS=${DEPLOYMENT_LOCATION}/common_libs
mkdir -p ${COMMON_LIBS}
echo "Getting replication.jar as a library"
CONTAINER_NAME=$(docker create -ti --entrypoint /bin/bash gerritcodereview/gerrit:"${GERRIT_IMAGE}") && \
docker cp ${CONTAINER_NAME}:/var/gerrit/plugins/replication.jar $COMMON_LIBS/
docker rm -fv ${CONTAINER_NAME}
echo "Downloading global-refdb library $GERRIT_BRANCH"
wget https://repo1.maven.org/maven2/com/gerritforge/global-refdb/$GLOBAL_REFDB_VER/global-refdb-$GLOBAL_REFDB_VER.jar \
-O $COMMON_LIBS/global-refdb.jar || { echo >&2 "Cannot download global-refdb library: Check internet connection. Aborting"; exit 1; }
echo "Downloading events-broker library $GERRIT_BRANCH"
wget https://repo1.maven.org/maven2/com/gerritforge/events-broker/$EVENTS_BROKER_VER/events-broker-$EVENTS_BROKER_VER.jar \
-O $COMMON_LIBS/events-broker.jar || { echo >&2 "Cannot download events-broker library: Check internet connection. Aborting"; exit 1; }
echo "Setting up directories"
mkdir -p ${GERRIT_1_ETC} ${GERRIT_1_PLUGINS} ${GERRIT_1_LIBS} ${GERRIT_2_ETC} ${GERRIT_2_PLUGINS} ${GERRIT_2_LIBS}
echo "Copying plugins"
cp -f $COMMON_PLUGINS/* ${GERRIT_1_PLUGINS}
cp -f $COMMON_PLUGINS/* ${GERRIT_2_PLUGINS}
echo "Copying libs"
cp -f $COMMON_LIBS/* ${GERRIT_1_LIBS}
cp -f $COMMON_PLUGINS/multi-site.jar ${GERRIT_1_LIBS}
cp -f $COMMON_LIBS/* ${GERRIT_2_LIBS}
cp -f $COMMON_PLUGINS/multi-site.jar ${GERRIT_2_LIBS}
echo "Setting up configuration"
echo "Setup healthcheck config"
cp -f ${LOCAL_ENV}/configs/healthcheck.config $GERRIT_1_ETC
cp -f ${LOCAL_ENV}/configs/healthcheck.config $GERRIT_2_ETC
echo "Setup multi-site config"
cp -f ${LOCAL_ENV}/configs/multi-site.config $GERRIT_1_ETC
cp -f ${LOCAL_ENV}/configs/multi-site.config $GERRIT_2_ETC
echo "Setup zookeeper config"
setup_zookeeper_config "${GERRIT_1_ETC}/zookeeper-refdb.config"
setup_zookeeper_config "${GERRIT_2_ETC}/zookeeper-refdb.config"
echo "Setup replication config"
setup_replication_config "${GERRIT_1_ETC}/replication.config" 'file:///var/gerrit/git-instance2/${name}.git'
setup_replication_config "${GERRIT_2_ETC}/replication.config" 'file:///var/gerrit/git-instance1/${name}.git'
echo "Setup gerrit config"
setup_gerrit_config "${GERRIT_1_ETC}/gerrit.config" $BROKER_HOST $BROKER_PORT instance-1 29418
setup_gerrit_config "${GERRIT_2_ETC}/gerrit.config" $BROKER_HOST $BROKER_PORT instance-2 29419
echo "Generating common SSH key for tests"
COMMON_SSH=${DEPLOYMENT_LOCATION}/common_ssh
mkdir -p ${COMMON_SSH}
ssh-keygen -b 2048 -t rsa -f ${COMMON_SSH}/id_rsa -q -N "" || { echo >&2 "Cannot generate common SSH keys. Aborting"; exit 1; }
SCENARIOS="$( cd "${LOCATION}" >/dev/null 2>&1 && pwd )/scenarios.sh"
echo "Starting containers"
COMPOSE_FILES="-f ${LOCATION}/docker-compose.yaml -f ${LOCATION}/docker-compose-kafka.yaml -f ${LOCATION}/docker-tester.yaml"
# store setup in single file (under ${DEPLOYMENT_LOCATION}) with all variables resolved
export GERRIT_IMAGE; \
export GERRIT_HEALTHCHECK_START_PERIOD; \
export GERRIT_HEALTHCHECK_INTERVAL; \
export GERRIT_HEALTHCHECK_TIMEOUT; \
export GERRIT_HEALTHCHECK_RETRIES; \
docker-compose ${COMPOSE_FILES} config > ${DEPLOYMENT_LOCATION}/docker-compose.yaml
trap cleanup_tests_hook EXIT
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml up -d zookeeper kafka
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml ps -a
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml logs -f --no-color -t > ${DEPLOYMENT_LOCATION}/site.log &
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml up --no-start gerrit1 gerrit2
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml ps -a
GERRIT1_CONTAINER=$(docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml ps -q gerrit1)
GERRIT2_CONTAINER=$(docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml ps -q gerrit2)
#copy files to gerrit containers
echo "Copying files to Gerrit containers"
docker cp "${GERRIT_1_ETC}/" "${GERRIT1_CONTAINER}:/var/gerrit/etc"
docker cp "${GERRIT_1_PLUGINS}/" "${GERRIT1_CONTAINER}:/var/gerrit/plugins"
docker cp "${GERRIT_1_LIBS}/" "${GERRIT1_CONTAINER}:/var/gerrit/libs"
docker cp "${COMMON_SSH}/" "${GERRIT1_CONTAINER}:/var/gerrit/.ssh"
docker cp "${GERRIT_2_ETC}/" "${GERRIT2_CONTAINER}:/var/gerrit/etc"
docker cp "${GERRIT_2_PLUGINS}/" "${GERRIT2_CONTAINER}:/var/gerrit/plugins"
docker cp "${GERRIT_2_LIBS}/" "${GERRIT2_CONTAINER}:/var/gerrit/libs"
docker cp "${COMMON_SSH}/" "${GERRIT2_CONTAINER}:/var/gerrit/.ssh"
echo "Starting Gerrit servers"
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml up -d gerrit1 gerrit2
echo "Waiting for services to start (and being healthy) and calling e2e tests"
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml up --no-start tester
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml ps -a
TEST_CONTAINER=$(docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml ps -q tester)
docker cp "${COMMON_SSH}/" "${TEST_CONTAINER}:/var/gerrit/.ssh"
docker cp "${SCENARIOS}" "${TEST_CONTAINER}:/var/gerrit/scenarios.sh"
docker-compose -f ${DEPLOYMENT_LOCATION}/docker-compose.yaml up tester
# inspect test container exit code as 'up' always returns '0'
check_result "${TEST_CONTAINER}" 0
RES_VAL=$?
check_result "${GERRIT1_CONTAINER}" ${RES_VAL}
RES_VAL=$?
check_result "${GERRIT2_CONTAINER}" ${RES_VAL}
RES_VAL=$?
exit $RES_VAL