Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

More shared functions and test log readability #545

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 58 additions & 71 deletions test/run_test
Original file line number Diff line number Diff line change
Expand Up @@ -91,39 +91,30 @@ cleanup_volume_dir ()
rmdir "$1"
}

function get_cid() {
local id="$1" ; shift || return 1
echo $(cat "$CID_FILE_DIR/$id")
}

function get_container_ip() {
local id="$1" ; shift
docker inspect --format='{{.NetworkSettings.IPAddress}}' $(get_cid "$id")
}

function get_ip_from_cid() {
local cid="$1"; shift
docker inspect --format='{{.NetworkSettings.IPAddress}}' $cid
}

function postgresql_cmd() {
docker run --rm -e PGPASSWORD="$PASS" "$IMAGE_NAME" psql "postgresql://$PGUSER@$CONTAINER_IP:5432/${DB-db}" "$@"
docker run --rm -e PGPASSWORD="$PASS" "$IMAGE_NAME" psql -v ON_ERROR_STOP=1 "postgresql://$PGUSER@$CONTAINER_IP:5432/${DB-db}" "$@"
}

function test_connection() {
local name=$1 ; shift
ip=$(get_container_ip $name)
ip=$(ct_get_cip $name)
echo " Testing PostgreSQL connection to $ip..."
local max_attempts=20
local sleep_time=2
echo -n " Trying to connect, waiting for 1: ..."
for i in $(seq $max_attempts); do
echo " Trying to connect..."
echo -n "."
# Don't let the code come here if neither user nor admin is able to
# connect.
if [ -v PGUSER ] && [ -v PASS ]; then
CONTAINER_IP=$ip postgresql_cmd <<< "SELECT 1;"
CONTAINER_IP=$ip postgresql_cmd -At -c "SELECT 1;" 2>/dev/null
else
PGUSER=postgres PASS=$ADMIN_PASS CONTAINER_IP=$ip DB=postgres postgresql_cmd <<< "SELECT 1;"
PGUSER=postgres PASS=$ADMIN_PASS CONTAINER_IP=$ip DB=postgres postgresql_cmd -At -c "SELECT 1;" 2>/dev/null
fi
status=$?
if [ $status -eq 0 ]; then
Expand All @@ -132,19 +123,25 @@ function test_connection() {
fi
sleep $sleep_time
done
echo " Failure to connect to server $ip :("
return 1
}

function test_postgresql() {
local ret=0
local user=${1:-user}
echo " Testing PostgreSQL"
postgresql_cmd <<< "CREATE EXTENSION 'uuid-ossp';" || ret=1 # to test contrib package
postgresql_cmd <<< "CREATE TABLE tbl (col1 VARCHAR(20), col2 VARCHAR(20));" || ret=2
postgresql_cmd <<< "INSERT INTO tbl VALUES ('foo1', 'bar1');" || ret=3
postgresql_cmd <<< "INSERT INTO tbl VALUES ('foo2', 'bar2');" || ret=4
postgresql_cmd <<< "INSERT INTO tbl VALUES ('foo3', 'bar3');" || ret=5
postgresql_cmd <<< "SELECT * FROM tbl;" || ret=6
#postgresql_cmd <<< "DROP TABLE tbl;"
# test contrib only when having admin privileges
if [ "$user" == "admin" ] ; then
postgresql_cmd -At -c "CREATE EXTENSION \"uuid-ossp\";" || ret=1 # to test contrib package
fi
postgresql_cmd -At -c "CREATE TABLE tbl (col1 VARCHAR(20), col2 VARCHAR(20));" || ret=2
postgresql_cmd -At -c "INSERT INTO tbl VALUES ('foo1', 'bar1');" || ret=3
postgresql_cmd -At -c "INSERT INTO tbl VALUES ('foo2', 'bar2');" || ret=4
postgresql_cmd -At -c "INSERT INTO tbl VALUES ('foo3', 'bar3');" || ret=5
postgresql_cmd -At -c "SELECT * FROM tbl;" || ret=6
# not droping table, other tests depend on having it created after this function is run
#postgresql_cmd -At -c "DROP TABLE tbl;"
if [ $ret -eq 0 ]; then
echo " Success!"
fi
Expand Down Expand Up @@ -195,7 +192,7 @@ function assert_login_access() {

echo "testing login as $PGUSER:$PASS; should_success=$success"

if postgresql_cmd <<<'SELECT 1;' ; then
if postgresql_cmd -At -c 'SELECT 1;' 2>/dev/null ; then
if $success ; then
echo " $PGUSER($PASS) access granted as expected"
return
Expand All @@ -206,28 +203,31 @@ function assert_login_access() {
return
fi
fi
echo " $PGUSER($PASS) login assertion failed"
echo " $PGUSER($PASS) login assertion failed (expected: $success)"
return 1
}

function assert_local_access() {
local id="$1" ; shift
docker exec -i $(get_cid "$id") bash -c psql <<< "SELECT 1;"
docker exec -i $(ct_get_cid "$id") bash -c psql <<< "SELECT 1;"
}


# Make sure the invocation of docker run fails.
function assert_container_creation_fails() {
local ret=0
local out=

# Time the docker run command. It should fail. If it doesn't fail,
# postgresql will keep running so we kill it with SIGKILL to make sure
# timeout returns a non-zero value.
timeout -s 9 --preserve-status 60s docker run --rm "$@" $IMAGE_NAME
out=$(timeout -s 9 --preserve-status 60s docker run --rm "$@" $IMAGE_NAME 2>&1)
ret=$?

# Timeout will exit with a high number.
if [ $ret -gt 30 ]; then
echo "Output of container that did not fail:"
echo "$out"
return 1
fi
}
Expand Down Expand Up @@ -312,7 +312,7 @@ function test_config_option() {
local setting=$1 ; shift
local value=$1 ; shift

docker exec $(get_cid ${name}) grep -q "${setting} = ${value}" /var/lib/pgsql/openshift-custom-postgresql.conf
docker exec $(ct_get_cid ${name}) grep -q "${setting} = ${value}" /var/lib/pgsql/openshift-custom-postgresql.conf
}


Expand All @@ -321,7 +321,7 @@ function test_config_option() {
# Wait until the PG container becomes ready
wait_ready ()
{
while ! docker exec "$(get_cid "$1")" /usr/libexec/check-container ; do
while ! docker exec "$(ct_get_cid "$1")" /usr/libexec/check-container ; do
sleep 1
done
}
Expand All @@ -333,7 +333,7 @@ assert_runtime_option ()
{
local name=$1 option=$2 value=$3
wait_ready "$name"
set -- $(docker exec "$(get_cid "$name")" bash -c "psql -tA -c 'SHOW $option;'")
set -- $(docker exec "$(ct_get_cid "$name")" bash -c "psql -tA -c 'SHOW $option;'")
test "$value" = "$1"
}

Expand Down Expand Up @@ -362,12 +362,12 @@ test_scl_usage() {
echo "ERROR[/bin/bash -c "${run_cmd}"] Expected '${expected}', got '${out}'"
return 1
fi
out=$(docker exec $(get_cid $name) /bin/bash -c "${run_cmd}" 2>&1)
out=$(docker exec $(ct_get_cid $name) /bin/bash -c "${run_cmd}" 2>&1)
if ! echo "${out}" | grep -q "${expected}"; then
echo "ERROR[exec /bin/bash -c "${run_cmd}"] Expected '${expected}', got '${out}'"
return 1
fi
out=$(docker exec $(get_cid $name) /bin/sh -ic "${run_cmd}" 2>&1)
out=$(docker exec $(ct_get_cid $name) /bin/sh -ic "${run_cmd}" 2>&1)
if ! echo "${out}" | grep -q "${expected}"; then
echo "ERROR[exec /bin/sh -ic "${run_cmd}"] Expected '${expected}', got '${out}'"
return 1
Expand Down Expand Up @@ -406,7 +406,7 @@ function run_tests() {
envs="$envs -e POSTGRESQL_SHARED_BUFFERS=$POSTGRESQL_SHARED_BUFFERS"
fi
DOCKER_ARGS="${DOCKER_ARGS:-} $envs" create_container $name
CONTAINER_IP=$(get_container_ip $name)
CONTAINER_IP=$(ct_get_cip $name)
test_connection $name || ret=1
echo " Testing scl usage"
test_scl_usage $name 'psql --version' "$VERSION" || ret=2
Expand All @@ -422,11 +422,11 @@ function run_tests() {
run_configuration_tests $name || ret=8

if $user_login; then
test_postgresql $name || ret=9
test_postgresql || ret=9
fi

if $admin_login; then
DB=postgres PGUSER=postgres PASS=$ADMIN_PASS test_postgresql $name || ret=10
DB=postgres PGUSER=postgres PASS=$ADMIN_PASS test_postgresql admin || ret=10
fi
if [ $ret -eq 0 ]; then
echo " Success!"
Expand Down Expand Up @@ -459,7 +459,7 @@ function test_slave_visibility() {
return 1
fi
for i in $(seq $max_attempts); do
result="$(postgresql_cmd -c "select client_addr from pg_stat_replication;" | grep "$slave_ip" || true)"
result="$(postgresql_cmd -c "select client_addr from pg_stat_replication;" 2>/dev/null | grep "$slave_ip" || true)"
if [[ -n "${result}" ]]; then
echo "${slave_ip} successfully registered as SLAVE for ${master_ip}"
break
Expand Down Expand Up @@ -488,7 +488,7 @@ function test_value_replication() {
slave_ip=$(get_ip_from_cid $slave)
CONTAINER_IP=$slave_ip
for i in $(seq $max_attempts); do
result="$(postgresql_cmd -At -c "select * from $table_name" || :)"
result="$(postgresql_cmd -At -c "select * from $table_name" 2>/dev/null || :)"
if [[ "$result" == "$value" ]]; then
echo "${slave_ip} successfully got value from MASTER ${master_ip}"
break
Expand All @@ -510,7 +510,7 @@ function setup_replication_cluster() {

# Run the PostgreSQL slaves
local i
master_ip=$(get_container_ip "master-$cid_suffix.cid")
master_ip=$(ct_get_cip "master-$cid_suffix.cid")
local cluster_args="$cluster_args --add-host postgresql-master:$master_ip"
local master_hostname="postgresql-master"
for i in $(seq ${slave_num:-1}); do
Expand Down Expand Up @@ -553,7 +553,7 @@ function run_master_restart_test() {
rm $cidfile

run_master $cid_suffix
CONTAINER_IP=$(get_container_ip master-$cid_suffix.cid)
CONTAINER_IP=$(ct_get_cip master-$cid_suffix.cid)

# Update master_ip in slaves
for slave in $slave_cids; do
Expand Down Expand Up @@ -624,20 +624,23 @@ $volume_options
PASS=${password}

# need this to wait for the container to start up
CONTAINER_IP=$(get_container_ip ${name})
CONTAINER_IP=$(ct_get_cip ${name})
test_connection ${name} || ret=3

echo " Testing login"

assert_login_access ${user} ${password} true || ret=4
assert_login_access 'postgres' ${admin_password} true || ret=5
test_postgresql || ret 5

echo " Changing passwords"

# create separate mounting directory for second container, as selinux does
# not allow two containers accesing one mounting directory if mounted with
# Z option
create_volume_dir || ret=1
echo "Kill the previous container and create a new one"
local cidfile=$CID_FILE_DIR/"${name}"
docker kill $(cat $cidfile)
docker rm -f $(cat $cidfile)
# Don't forget to remove its .cid file
rm $cidfile

DOCKER_ARGS="
-e POSTGRESQL_DATABASE=${database}
Expand All @@ -651,7 +654,7 @@ $volume_options
PASS="NEW_${password}"

# need this to wait for the container to start up
CONTAINER_IP=$(get_container_ip "${name}_NEW")
CONTAINER_IP=$(ct_get_cip "${name}_NEW")
test_connection "${name}_NEW" || ret=7

echo " Testing login with new passwords"
Expand All @@ -662,6 +665,9 @@ $volume_options
assert_login_access 'postgres' "NEW_${admin_password}" true || ret=10
assert_login_access 'postgres' ${admin_password} false || ret=11

# check that we still work with the original volume
postgresql_cmd -At -c "SELECT * FROM tbl;" | grep bar3 || ret=12

if [ $ret -eq 0 ]; then
echo " Success!"
fi
Expand Down Expand Up @@ -722,27 +728,8 @@ run_migration_test ()
}

run_doc_test() {
local tmpdir=$(mktemp -d)
local f
echo " Testing documentation in the container image"
# Extract the help files from the container
for f in help.1 ; do
docker run --rm ${IMAGE_NAME} /bin/bash -c "cat /${f}" >${tmpdir}/$(basename ${f})
# Check whether the files include some important information
for term in 'POSTGRESQL\\?_ADMIN\\?_PASSWORD' Volume 5432 ; do
if ! cat ${tmpdir}/$(basename ${f}) | grep -E -q -e "${term}" ; then
echo "ERROR: File /${f} does not include '${term}'."
return 1
fi
done
done
# Check whether the files use the correct format
if ! file ${tmpdir}/help.1 | grep -q roff ; then
echo "ERROR: /help.1 is not in troff or groff format"
return 1
fi
echo " Success!"
echo
ct_doc_content_old 'POSTGRESQL\\?_ADMIN\\?_PASSWORD' Volume 5432
return $?
}

test_the_app_image () {
Expand Down Expand Up @@ -863,7 +850,7 @@ run_s2i_enable_ssl_test()
IMAGE_NAME="$s2i_image_name" create_container "$container_name"

wait_ready "$container_name"
CONTAINER_IP=$(get_container_ip $container_name)
CONTAINER_IP=$(ct_get_cip $container_name)

DB=postgres assert_login_access postgres password true

Expand All @@ -884,7 +871,7 @@ run_s2i_bake_data_test ()

wait_ready "$container_name"

test "hello world" == "$(docker exec "$(get_cid "$container_name")" \
test "hello world" == "$(docker exec "$(ct_get_cid "$container_name")" \
bash -c "psql -tA -c 'SELECT * FROM test;'")"
}

Expand Down Expand Up @@ -921,14 +908,14 @@ run_pgaudit_test()
# enable the pgaudit extension
# Deliberately moving heredoc into the container, otherwise it does not work
# in podman 1.6.x due to https://bugzilla.redhat.com/show_bug.cgi?id=1827324
docker exec -i $(get_cid "$name") bash -c "psql <<EOSQL
docker exec -i $(ct_get_cid "$name") bash -c "psql <<EOSQL
CREATE EXTENSION pgaudit;
SET pgaudit.log = 'read, ddl';
CREATE DATABASE pgaudittest;
EOSQL" || ret=2

# simulate some trafic that should be audited
docker exec -i $(get_cid "$name") bash -c "psql pgaudittest <<EOSQL
docker exec -i $(ct_get_cid "$name") bash -c "psql pgaudittest <<EOSQL
SET pgaudit.log = 'read, ddl';
CREATE TABLE account (id int, name text, password text, description text);
INSERT INTO account (id, name, password, description) VALUES (1, 'user1', 'HASH1', 'blah, blah');
Expand Down Expand Up @@ -964,13 +951,13 @@ run_logging_test()
wait_ready "$name"

# try loggin in as a user that does not exist to trigger an error log message
echo 'psql -U nonexistent' | docker exec -i $(get_cid "$name") bash || :
echo 'psql -U nonexistent' | docker exec -i $(ct_get_cid "$name") bash || :

# give server some time for write all audit messages
sleep 1

# check whether we have a correct output in the container log
if docker logs $(get_cid "$name") 2>&1 | grep -q 'FATAL: role "nonexistent" does not exist' ; then
if docker logs $(ct_get_cid "$name") 2>&1 | grep -q 'FATAL: role "nonexistent" does not exist' ; then
echo " PASS: the container log does include expected error message"
else
echo "ERROR: the container log does not include expected error message"
Expand Down