Skip to content

Commit

Permalink
Split simple-smoke-test.sh to be used elsewhere [DI-215] (#790)
Browse files Browse the repository at this point in the history
`simple-smoke-test.sh` is a useful suite of tests to validate a packaged
Hazelcast instance - but is Docker-centric.

- Refactored to split the script into two halves:
- `abstract-simple-smoke-test` that tests against an abstract Hazelcast
instance
  - `simple-smoke-test` a Docker-specific implementation
- Refactored the metadata checks to search the instance's logs for the
variant and version (i.e. OSS/EE, `5.5.0` etc) rather than inspecting
the containers' filesystem
- an existing test elsewhere in the codebase already does this so we
already have some dependency on keeping the output consistent, although
I can't currently find the test in question
- Added extra coverage from [`hazelcast-packaging`'s
`check-hazelcast-health.sh`](https://github.com/hazelcast/hazelcast-packaging/blob/bd417d0604b57ae2f72234d8781929fdf86b0687/check-hazelcast-health.sh)

Required for [DI-215](https://hazelcast.atlassian.net/browse/DI-215)

[DI-215]:
https://hazelcast.atlassian.net/browse/DI-215?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
JackPGreen committed Nov 5, 2024
1 parent 3119434 commit cea9844
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 83 deletions.
87 changes: 87 additions & 0 deletions .github/scripts/abstract-simple-smoke-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash

set -o errexit -o nounset -o pipefail

# Performs simple validation tests on an already-running Hazelcast instance
# Abstract as could be from Docker, Homebrew, local binary etc
# Because abstract, expects callers to implement required, but absent functions
function test_package() {
local expected_distribution_type=$1
local expected_version=$2

test_health
test_map_read_write

# Deliberately last step as it doesn't block-and-wait until the instance is initialized
# Otherwise would have false positives if instance still starting and logs empty
check_metadata "${expected_distribution_type}" "${expected_version}"
}

# Search logs for entries _like_:
# Hazelcast Platform 5.5.0 (20240725) starting at [172.17.0.2]:5701
# To validate the version and distribution is correct
function check_metadata() {
local expected_distribution_type=$1
local expected_version=$2

logs=$(get_hz_logs)

if [[ -z "${logs}" ]]; then
echoerr "Failed to read logs"
exit 1;
fi

if grep -q "${expected_distribution_type} ${expected_version}" <<< "${logs}"; then
echo "Expected contents (${expected_distribution_type}) and version (${expected_version}) identified."
else
echoerr "Failed to find ${expected_distribution_type} ${expected_version} in logs:"
echoerr "${logs}"
exit 1;
fi
}

function test_health() {
local attempts=0
local max_attempts=30
until curl --silent --fail "127.0.0.1:5701/hazelcast/health/ready"; do
if [[ ${attempts} -eq ${max_attempts} ]];then
echoerr "Hazelcast not responding"
exit 1;
fi
printf '.'
attempts=$((attempts+1))
sleep 2
done
}

function test_map_read_write() {
install_clc

local key="some-key"
local expected="some-value"
echo "Putting value '${expected}' for key '${key}'"
clc --timeout 5s map set -n some-map "${key}" "${expected}" --log.path stderr
echo "Getting value for key '${key}'"
local actual
actual=$(clc map get --format delimited -n some-map "${key}" --log.path stderr)

if [[ "${expected}" != "${actual}" ]]; then
echoerr "Expected to read '${expected}' but got '${actual}'"
exit 1;
fi
}

function install_clc() {
while ! curl https://hazelcast.com/clc/install.sh | bash
do
echo "Retrying clc installation..."
sleep 3
done
export PATH=${PATH}:${HOME}/.hazelcast/bin
clc config add default cluster.name=dev cluster.address=localhost
}

# Prints the given message to stderr
function echoerr() {
echo "ERROR - $*" 1>&2;
}
92 changes: 9 additions & 83 deletions .github/scripts/simple-smoke-test.sh
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
#!/usr/bin/env bash

set -o errexit -o nounset -o pipefail
set -o errexit

function test_docker_image() {
local image=$1
local container_name=$2
local expected_distribution_type=$3
local expected_version=$4

remove_container_if_exists "${container_name}"

check_distribution_type "${image}" "${expected_distribution_type}"
check_image_hz_version "${image}" "${expected_version}"

test_map_read_write "${image}" "${container_name}"
}
# shellcheck source=../.github/scripts/abstract-simple-smoke-test.sh
. .github/scripts/abstract-simple-smoke-test.sh

function remove_container_if_exists() {
local container_name=$1

local containers
containers=$(docker ps --all --quiet --filter name="${container_name}")

Expand All @@ -28,77 +15,18 @@ function remove_container_if_exists() {
fi
}

function check_distribution_type() {
local image=$1
local expected_distribution_type=$2

echo "Checking ${image} distribution type"
if docker run --rm "${image}" bash -c 'compgen -G lib/*enterprise*'; then
echo "EE contents identified"
distribution_type="ee"
else
echo "No EE contents identified - assuming OSS"
distribution_type="oss"
fi

if [[ "${distribution_type}" != "${expected_distribution_type}" ]]; then
echoerr "Image ${image} should contain ${expected_distribution_type} distribution but ${distribution_type} was detected"
exit 1
fi
function start_container() {
echo "Starting container '${container_name}' from image '${image}'"
docker run -it --name "${container_name}" -e HZ_LICENSEKEY -e HZ_INSTANCETRACKING_FILENAME -d -p5701:5701 "${image}"
}

function check_image_hz_version() {
local image=$1
local expected_version=$2

echo "Checking ${image} version"
local version
version=$(docker run --rm "${image}" bin/hz-cli --version | awk '/Hazelcast/ {print $2}')
if [[ "${version}" == "${expected_version}" ]]; then
echo "${image} version identified as ${version}"
else
echoerr "${image} version was ${version}, not ${expected_version} as expected"
exit 1
fi
function get_hz_logs() {
docker logs "${container_name}"
}

function test_map_read_write() {
local image=$1
local expected_distribution_type=$2

echo "Starting container '${container_name}' from image '${image}'"
docker run -it --name "${container_name}" -e HZ_LICENSEKEY -e HZ_INSTANCETRACKING_FILENAME -d -p5701:5701 "${image}"
local key="some-key"
local expected="some-value"
echo "Putting value '${expected}' for key '${key}'"
while ! clc --timeout 5s map set -n some-map "${key}" "${expected}" --log.path stderr
do
echo "Retrying..."
sleep 3
done
echo "Getting value for key '${key}'"
local actual
actual=$(clc map get --format delimited -n some-map "${key}" --log.path stderr)
function stop_container() {
echo "Stopping container ${container_name}"
docker stop "${container_name}"

if [[ "${expected}" != "${actual}" ]]; then
echoerr "Expected to read '${expected}' but got '${actual}'"
exit 1;
fi
}

function check_java_version() {
local expected_major_version=$1
local actual_major_version
actual_major_version=$(docker run --rm "${image}" sh -c 'java -version 2>&1 | head -n 1 | awk -F "\"" "{print \$2}" | awk -F "." "{print \$1}"')

if [[ "${expected_major_version}" == "${actual_major_version}" ]]; then
echo "Expected Java version (${expected_distribution_type}) identified."
else
echoerr "Expected Java version '${expected_major_version}' but got '${actual_major_version}'"
exit 1;
fi
}

function derive_expected_distribution_type() {
Expand All @@ -122,7 +50,6 @@ image=$1
container_name=$2
input_distribution_type=$3
expected_version=$4
expected_java_major_version=$5


remove_container_if_exists
Expand All @@ -132,4 +59,3 @@ trap stop_container EXIT

expected_distribution_type=$(derive_expected_distribution_type "${input_distribution_type}")
test_package "${expected_distribution_type}" "${expected_version}"
check_java_version "${expected_java_major_version}"

0 comments on commit cea9844

Please sign in to comment.