diff --git a/.github/scripts/abstract-simple-smoke-test.sh b/.github/scripts/abstract-simple-smoke-test.sh new file mode 100755 index 00000000..0765e9d4 --- /dev/null +++ b/.github/scripts/abstract-simple-smoke-test.sh @@ -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; +} diff --git a/.github/scripts/simple-smoke-test.sh b/.github/scripts/simple-smoke-test.sh index 73c9a5ce..ca143ac0 100755 --- a/.github/scripts/simple-smoke-test.sh +++ b/.github/scripts/simple-smoke-test.sh @@ -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}") @@ -28,81 +15,47 @@ 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 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 +function derive_expected_distribution_type() { + local input_distribution_type=$1 + + case "${input_distribution_type}" in + "oss") + echo "Hazelcast Platform" + ;; + "ee") + echo "Hazelcast Enterprise" + ;; + *) + echoerr "Unrecognized distribution type ${input_distribution_type}" + exit 1 + ;; + esac } -# Prints the given message to stderr -function echoerr() { - echo "ERROR - $*" 1>&2; -} +image=$1 +container_name=$2 +input_distribution_type=$3 +expected_version=$4 + + +remove_container_if_exists +start_container +trap stop_container EXIT -install_clc -test_docker_image "$@" +expected_distribution_type=$(derive_expected_distribution_type "${input_distribution_type}") +test_package "${expected_distribution_type}" "${expected_version}" diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 67bc5815..64289444 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -85,8 +85,9 @@ jobs: - name: Run smoke test against OSS image timeout-minutes: 2 - run: | - .github/scripts/simple-smoke-test.sh hazelcast-oss:test ${{ env.test_container_name_oss }} oss ${{ needs.prepare.outputs.HZ_VERSION_OSS }} + run: | + . .github/scripts/docker.functions.sh + .github/scripts/simple-smoke-test.sh hazelcast-oss:test ${{ env.test_container_name_oss }} oss ${{ needs.prepare.outputs.HZ_VERSION_OSS }} "$(get_default_jdk hazelcast-oss)" - name: Build Test EE image run: | @@ -102,8 +103,9 @@ jobs: - name: Run smoke test against EE image timeout-minutes: 2 run: | + . .github/scripts/docker.functions.sh export HZ_LICENSEKEY=${{ secrets.HZ_ENTERPRISE_LICENSE }} - .github/scripts/simple-smoke-test.sh hazelcast-ee:test ${{ env.test_container_name_ee }} ee ${{ needs.prepare.outputs.HZ_VERSION_EE }} + .github/scripts/simple-smoke-test.sh hazelcast-ee:test ${{ env.test_container_name_ee }} ee ${{ needs.prepare.outputs.HZ_VERSION_EE }} "$(get_default_jdk hazelcast-enterprise)" - name: Get docker logs if: ${{ always() }} @@ -162,7 +164,7 @@ jobs: - name: Run smoke test against OSS image timeout-minutes: 2 run: | - .github/scripts/simple-smoke-test.sh hazelcast-oss:test ${{ env.test_container_name_oss }} oss ${{ needs.prepare.outputs.HZ_VERSION_OSS }} + .github/scripts/simple-smoke-test.sh hazelcast-oss:test ${{ env.test_container_name_oss }} oss ${{ needs.prepare.outputs.HZ_VERSION_OSS }} ${{ matrix.jdk }} - name: Build Test EE image run: | @@ -180,7 +182,7 @@ jobs: timeout-minutes: 2 run: | export HZ_LICENSEKEY=${{ secrets.HZ_ENTERPRISE_LICENSE }} - .github/scripts/simple-smoke-test.sh hazelcast-ee:test ${{ env.test_container_name_ee }} ee ${{ needs.prepare.outputs.HZ_VERSION_EE }} + .github/scripts/simple-smoke-test.sh hazelcast-ee:test ${{ env.test_container_name_ee }} ee ${{ needs.prepare.outputs.HZ_VERSION_EE }} ${{ matrix.jdk }} - name: Get docker logs if: ${{ always() }} diff --git a/.github/workflows/ee-nlc-snapshot-push.yml b/.github/workflows/ee-nlc-snapshot-push.yml index d4357af2..8942938d 100644 --- a/.github/workflows/ee-nlc-snapshot-push.yml +++ b/.github/workflows/ee-nlc-snapshot-push.yml @@ -73,7 +73,7 @@ jobs: timeout-minutes: 2 run: | export HZ_INSTANCETRACKING_FILENAME=instance-tracking.txt - .github/scripts/simple-smoke-test.sh hazelcast-nlc:test ${{ env.test_container_name_ee }} ee ${HZ_VERSION} + .github/scripts/simple-smoke-test.sh hazelcast-nlc:test ${{ env.test_container_name_ee }} ee ${HZ_VERSION} ${{ matrix.jdk }} - name: Get docker logs if: ${{ always() }} diff --git a/.github/workflows/ee-nlc-tag-push.yml b/.github/workflows/ee-nlc-tag-push.yml index 147c6591..7f16c5b8 100644 --- a/.github/workflows/ee-nlc-tag-push.yml +++ b/.github/workflows/ee-nlc-tag-push.yml @@ -87,7 +87,7 @@ jobs: timeout-minutes: 2 run: | export HZ_INSTANCETRACKING_FILENAME=instance-tracking.txt - .github/scripts/simple-smoke-test.sh hazelcast-nlc:test ${{ env.test_container_name_ee }} ee ${HZ_VERSION} + .github/scripts/simple-smoke-test.sh hazelcast-nlc:test ${{ env.test_container_name_ee }} ee ${HZ_VERSION} ${{ matrix.jdk }} - name: Get docker logs if: ${{ always() }} diff --git a/.github/workflows/ee_latest_snapshot_push.yml b/.github/workflows/ee_latest_snapshot_push.yml index 63ffb3ed..393d3159 100644 --- a/.github/workflows/ee_latest_snapshot_push.yml +++ b/.github/workflows/ee_latest_snapshot_push.yml @@ -75,7 +75,7 @@ jobs: timeout-minutes: 2 run: | export HZ_LICENSEKEY=${{ secrets.HZ_ENTERPRISE_LICENSE }} - .github/scripts/simple-smoke-test.sh hazelcast-ee:test ${{ env.test_container_name_ee }} ee ${HZ_VERSION} + .github/scripts/simple-smoke-test.sh hazelcast-ee:test ${{ env.test_container_name_ee }} ee ${HZ_VERSION} ${{ matrix.jdk }} - name: Get docker logs if: ${{ always() }} diff --git a/.github/workflows/oss_latest_snapshot_push.yml b/.github/workflows/oss_latest_snapshot_push.yml index f79cddf7..befa48ba 100644 --- a/.github/workflows/oss_latest_snapshot_push.yml +++ b/.github/workflows/oss_latest_snapshot_push.yml @@ -83,7 +83,7 @@ jobs: - name: Run smoke test against OSS image timeout-minutes: 2 run: | - .github/scripts/simple-smoke-test.sh hazelcast-oss:test ${{ env.test_container_name_oss }} oss ${HZ_VERSION} + .github/scripts/simple-smoke-test.sh hazelcast-oss:test ${{ env.test_container_name_oss }} oss ${HZ_VERSION} ${{ matrix.jdk }} - name: Get docker logs if: ${{ always() }} diff --git a/.github/workflows/tag_image_push.yml b/.github/workflows/tag_image_push.yml index 368c0895..99cba73e 100644 --- a/.github/workflows/tag_image_push.yml +++ b/.github/workflows/tag_image_push.yml @@ -147,7 +147,7 @@ jobs: if: needs.prepare.outputs.should_build_oss == 'yes' timeout-minutes: 2 run: | - .github/scripts/simple-smoke-test.sh hazelcast-oss:test ${{ env.test_container_name_oss }} oss ${{ env.HZ_VERSION }} + .github/scripts/simple-smoke-test.sh hazelcast-oss:test ${{ env.test_container_name_oss }} oss ${{ env.HZ_VERSION }} ${{ matrix.jdk }} - name: Get EE dist ZIP URL run: | @@ -170,7 +170,7 @@ jobs: timeout-minutes: 2 run: | export HZ_LICENSEKEY=${{ secrets.HZ_ENTERPRISE_LICENSE }} - .github/scripts/simple-smoke-test.sh hazelcast-ee:test ${{ env.test_container_name_ee }} ee ${{ env.HZ_VERSION }} + .github/scripts/simple-smoke-test.sh hazelcast-ee:test ${{ env.test_container_name_ee }} ee ${{ env.HZ_VERSION }} ${{ matrix.jdk }} - name: Get docker logs if: ${{ always() }}