diff --git a/.VERSION b/.VERSION index 0759e2270..4ae7c18f0 100644 --- a/.VERSION +++ b/.VERSION @@ -2,4 +2,4 @@ # version, i.e., code is from SCM/git. This project uses semantic # versioning. For details see http://semver.org -1.8.9 +1.8.11 diff --git a/.pullapprove.yml b/.pullapprove.yml index cd22d6060..258cd3862 100644 --- a/.pullapprove.yml +++ b/.pullapprove.yml @@ -1,5 +1,6 @@ +--- version: 2 -extends: Default # see https://pullapprove.com/sourceryinstitute/ +extends: Default # see https://pullapprove.com/sourceryinstitute/ groups: # These have all the group_defaults Maintainers: @@ -13,9 +14,9 @@ groups: - caffeinate-opencoarrays teams: - team-opencoarrays - # https://github.com/orgs/sourceryinstitute/teams/team-opencoarrays + # https://github.com/orgs/sourceryinstitute/teams/team-opencoarrays OpenCoarrays: - # Whenever someone has a PR, on any branch require at least 1 + # Whenever someone has a PR, on any branch require at least 1 # collaborator to explicitly review it required: 1 users: all diff --git a/.travis.yml b/.travis.yml index b4dc2ea14..834a7d0a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,37 +1,41 @@ +--- language: generic +os: osx + env: global: - - CACHE="$HOME/.local" + - CACHE="${HOME}/.local" - MPICH_VER="3.2" - - MPICH_URL_HEAD="http://www.mpich.org/static/downloads/$MPICH_VER" + - MPICH_URL_HEAD="http://www.mpich.org/static/downloads/${MPICH_VER}" - MPICH_URL_TAIL="mpich-${MPICH_VER}.tar.gz" - - MPICH_DIR="$HOME/.local/usr/mpich" - - MPICH_BOT_URL_HEAD="https://github.com/sourceryinstitute/OpenCoarrays/files/976766/" + - MPICH_DIR="${HOME}/.local/usr/mpich" + - MPICH_GCC6_BOT_URL_HEAD="https://github.com/sourceryinstitute/OpenCoarrays/files/979804/" + - MPICH_GCC7_BOT_URL_HEAD="https://github.com/sourceryinstitute/OpenCoarrays/files/976779/" - MPICH_BOT_URL_TAIL="mpich-3.2_3.yosemite.bottle.1.tar.gz" - - FC=gfortran-6 - - CC=gcc-6 - - CXX=g++-6 + - BUILD_TYPES="Release Debug RelWithDebInfo CodeCoverage" + matrix: + - GCC=6 OSX_PACKAGES="gcc@6 cmake" + - GCC=7 OSX_PACKAGES="gcc cmake" matrix: + fast_finish: true include: - os: osx env: - - BUILD_TYPE="CodeCoverage" - OSX_PACKAGES="gcc@6 cmake" - - os: osx - env: - - BUILD_TYPE="Release" - OSX_PACKAGES="gcc@6 cmake" + - BUILD_TYPE="InstallScript" + OSX_PACKAGES="gcc@6" + GCC=6 - os: osx env: - - BUILD_TYPE="InstallScript" - OSX_PACKAGES="gcc@6" + - OSX_PACKAGES="gcc cmake" + GCC=7 + OPENCOARRAYS_DEVELOPER=ON - &ubuntu os: linux sudo: false env: - - BUILD_TYPE="CodeCoverage" + - GCC=6 cache: apt: false directories: @@ -48,14 +52,27 @@ matrix: - binutils - cmake-data - cmake - - - <<: *ubuntu - env: - - BUILD_TYPE="Release" + # - + # <<: *ubuntu + # env: + # - GCC=7 + # addons: + # apt: + # sources: + # - ubuntu-toolchain-r-test + # - george-edison55-precise-backports + # packages: + # - gcc-7 + # - gfortran-7 + # - g++-7 + # - binutils + # - cmake-data + # - cmake - <<: *ubuntu env: - BUILD_TYPE="InstallScript" + GCC=6 cache: false addons: apt: @@ -65,86 +82,92 @@ matrix: - gcc-6 - gfortran-6 - g++-6 + allow_failures: + - os: osx + env: + - OSX_PACKAGES="gcc cmake" + GCC=7 + OPENCOARRAYS_DEVELOPER=ON before_install: + - export FC=gfortran-${GCC} + - export CC=gcc-${GCC} + - export CXX=g++-${GCC} + - export MPICH_BOT_URL_HEAD=MPICH_GCC${GCC}_BOT_URL_HEAD - | set -o errexit - if [[ "$TRAVIS_TAG" ]] && [[ "X$TRAVIS_OS_NAME" = "Xosx" ]] && $TRAVIS_SECURE_ENV_VARS ; then + if [[ (-n ${TRAVIS_TAG}) && (${TRAVIS_OS_NAME} == osx) ]] && ${TRAVIS_SECURE_ENV_VARS} ; then brew update > /dev/null [[ "$(brew ls --versions gpg2)" ]] || brew install gpg2 brew outdated gpg2 || brew upgrade gpg2 - which openssl || brew install openssl + type -P openssl || brew install openssl fi - if ! [[ "$TRAVIS_TAG" ]] || ! $TRAVIS_SECURE_ENV_VARS ; then + if ! [[ "${TRAVIS_TAG}" ]] || ! ${TRAVIS_SECURE_ENV_VARS} ; then unset encrypted_ef4535c39461_key || true unset encrypted_ef4535c39461_iv || true rm subkey-328B3A0E-secret.asc{,.enc} || true fi - if [[ "$TRAVIS_TAG" ]] ; then + if [[ "${TRAVIS_TAG}" ]] ; then curl https://izaakbeekman.com/izaak.pubkey.txt | gpg --import git tag -v ${TRAVIS_TAG} fi set +o errexit - - - - - - - | set -o errexit - if [[ $TRAVIS ]] && [[ "X$TRAVIS_OS_NAME" = "Xosx" ]]; then - export PATH="$PATH:$HOME/Library/Python/2.7/bin" + if [[ (-n ${TRAVIS}) && (${TRAVIS_OS_NAME} == osx) ]]; then + export PATH="${PATH}:${HOME}/Library/Python/2.7/bin" else - [[ -d "$CACHE/bin" ]] || mkdir -p "$CACHE/bin" - [[ -d "$MPICH_DIR" ]] || mkdir -p "$MPICH_DIR" - export PATH="$CACHE/bin:$PATH" - $FC --version - $CC --version - $CXX --version + [[ -d "${CACHE}/bin" ]] || mkdir -p "${CACHE}/bin" + [[ -d "${MPICH_DIR}" ]] || mkdir -p "${MPICH_DIR}" + export PATH="${CACHE}/bin:${PATH}" + ${FC} --version + ${CC} --version + ${CXX} --version fi set +o errexit install: - | set -o errexit - if [[ $TRAVIS ]] && [[ "X$TRAVIS_OS_NAME" = "Xosx" ]]; then + if [[ (-n ${TRAVIS}) && (${TRAVIS_OS_NAME} == osx) ]]; then brew update > /dev/null - for pkg in $OSX_PACKAGES; do - [[ "$(brew ls --versions $pkg)" ]] || brew install --force-bottle $pkg - brew outdated $pkg || brew upgrade --force-bottle $pkg + for pkg in ${OSX_PACKAGES}; do + [[ "$(brew ls --versions ${pkg})" ]] || brew install --force-bottle ${pkg} + brew outdated ${pkg} || brew upgrade --force-bottle ${pkg} done - if ! [[ "$(brew ls --versions mpich)" ]] && [[ "X$BUILD_TYPE" != "XInstallScript" ]]; then - wget ${MPICH_BOT_URL_HEAD}${MPICH_BOT_URL_TAIL} + if [[ ${BUILD_TYPE} == InstallScript ]]; then # uninstall some stuff if present + brew uninstall --force --ignore-dependencies cmake || true + brew uninstall --force --ignore-dependencies mpich || true + brew uninstall --force --ignore-dependencies openmpi || true + else + wget "${!MPICH_BOT_URL_HEAD}${MPICH_BOT_URL_TAIL}" brew install --force-bottle ${MPICH_BOT_URL_TAIL} if ! [[ "$(brew ls --versions mpich)" ]]; then brew install --force-bottle mpich fi - rm -rf /usr/local/opt/gcc || true - ln -s /usr/local/opt/gcc@6 /usr/local/opt/gcc # hack to get dynamic linker to find gcc 6 stuff - mpif90 --version || mpif90 -show - mpicc --version || mpicc -show - cmake --version - elif [[ "X$BUILD_TYPE" = "XInstallScript" ]]; then # uninstall some stuff if present - [[ "$(brew ls --versions cmake)" ]] && brew rm cmake || true - [[ "$(brew ls --versions mpich)" ]] && brew rm mpich || true - [[ "$(brew ls --versions openmpi)" ]] && brew rm openmpi || true fi - elif [[ "X$BUILD_TYPE" != "XInstallScript" ]]; then # Ubuntu on Travis-CI, NOT testing install.sh - if ! ( [[ -x "$HOME/.local/bin/mpif90" ]] && [[ -x "$HOME/.local/bin/mpicc" ]] ); then + mpif90 --version || mpif90 -show || true + mpicc --version || mpicc -show || true + cmake --version || true + + elif [[ ${BUILD_TYPE} != InstallScript ]]; then # Ubuntu on Travis-CI, NOT testing install.sh + if ! [[ -x "${HOME}/.local/bin/mpif90" && -x "${HOME}/.local/bin/mpicc" ]]; then # mpich install not cached # could use prerequisites/build instead... wget "${MPICH_URL_HEAD}/${MPICH_URL_TAIL}" - mv "$MPICH_URL_TAIL" "$MPICH_DIR/.." - pushd "$MPICH_DIR/.." - tar -xzvf "$MPICH_URL_TAIL" + mv "${MPICH_URL_TAIL}" "${MPICH_DIR}/.." + pushd "${MPICH_DIR}/.." + tar -xzvf "${MPICH_URL_TAIL}" cd "${MPICH_URL_TAIL%.tar.gz}" - ./configure --prefix="$MPICH_DIR" + ./configure --prefix="${MPICH_DIR}" make -j 4 make install popd - for f in "$MPICH_DIR/bin/"*; do - if [[ -x "$f" ]]; then - ln -fs "$f" "$HOME/.local/bin/${f##*/}" + for f in "${MPICH_DIR}/bin/"*; do + if [[ -x "${f}" ]]; then + ln -fs "${f}" "${HOME}/.local/bin/${f##*/}" fi done fi @@ -157,55 +180,55 @@ install: script: - | set -o errexit - if [[ "X$BUILD_TYPE" = "XInstallScript" ]]; then - [[ -d "$HOME/opt" ]] || mkdir "$HOME/opt" - [[ -d "$HOME/bin" ]] || mkdir "$HOME/bin" - ln -fs "$(which gfortran-6)" "$HOME/bin/gfortran" - ln -fs "$(which gcc-6)" "$HOME/bin/gcc" - ln -fs "$(which g++-6)" "$HOME/bin/g++" - export PATH="$PATH:$HOME/bin" - ./install.sh --yes-to-all -i "$HOME/opt/opencoarrays" -j 4 -f "$HOME/bin/gfortran" -c "$HOME/bin/gcc" -C "$HOME/bin/g++" + if [[ ${BUILD_TYPE} == InstallScript ]]; then + ./install.sh --yes-to-all -i "${HOME}/opencoarrays" -j 4 -f "$(type -P "${FC}")" -c "$(type -P "${CC}")" -C "$(type -P "${CXX}")" cd prerequisites/builds/opencoarrays/* ../../../installations/cmake/*/bin/ctest --output-on-failure --schedule-random --repeat-until-fail 7 cd - else mkdir cmake-build - cd cmake-build - cmake -DCMAKE_INSTALL_PREFIX:PATH="$HOME/OpenCoarrays" -DCMAKE_BUILD_TYPE="$BUILD_TYPE" .. - make -j 4 - ctest --output-on-failure --schedule-random --repeat-until-fail 7 - make install - cd .. + for BUILD_TYPE in ${BUILD_TYPES}; do + rm -rf cmake-build/* || true + cd cmake-build + cmake -DCMAKE_INSTALL_PREFIX:PATH="${HOME}/OpenCoarrays" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. + make -j 4 + ctest --output-on-failure --schedule-random --repeat-until-fail 7 + make install + make uninstall + cd .. + done fi set +o errexit after_script: - | - if [ "$TRAVIS_TAG" ]; then - if [[ "v$TRAVIS_TAG" != "v$(sed -n 's/\([0-9]\{1,\}\(\.[0-9]\{1,\}\)\{1,\}\)/\1/p' .VERSION)" ]]; then + set -o errexit + if [[ "${TRAVIS_TAG}" ]]; then + if [[ "v${TRAVIS_TAG}" != "v$(sed -n 's/\([0-9]\{1,\}\(\.[0-9]\{1,\}\)\{1,\}\)/\1/p' .VERSION)" ]]; then echo "ERROR: You are trying to tag a new release but have a version missmatch in \`.VERSION\`" false # throw an error fi fi + set +o errexit after_success: - find . -name '*.gcno' -print - - gcov-6 --version - - bash <(curl -s https://codecov.io/bash) -x $(which gcov-6) + - gcov-${GCC} --version + - bash <(curl -s https://codecov.io/bash) -x $(type -P gcov-${GCC}) # before_deploy: # - git archive -v --prefix "OpenCoarrays-${TRAVIS_TAG}/" -o "OpenCoarrays-${TRAVIS_TAG}.tar.gz" ${TRAVIS_TAG} # - | # echo '# To verify cryptographic checksums `shasum -c opencoarrays-'"${TRAVIS_TAG}"'-SHA256.txt` on Mac OS X,' > "opencoarrays-${TRAVIS_TAG}-SHA256.txt # echo '# `sha256sum -c opencoarrays-'"${TRAVIS_TAG}"'-SHA256.txt` on Linux.' >> "opencoarrays-${TRAVIS_TAG}-SHA256.txt -# if [[ "X$(uname -s)" == "XDarwin" ]]; then +# if [[ $(uname -s) == Darwin ]]; then # shasum -a 256 "OpenCoarrays-${TRAVIS_TAG}.tar.gz" >> "opencoarrays-${TRAVIS_TAG}-SHA256.txt # else # sha256sum "OpenCoarrays-${TRAVIS_TAG}.tar.gz" >> "opencoarrays-${TRAVIS_TAG}-SHA256.txt # fi # - | # set -o errexit -# openssl aes-256-cbc -K $encrypted_ef4535c39461_key -iv $encrypted_ef4535c39461_iv -in subkey-328B3A0E-secret.asc.enc -out ./subkey-328B3A0E-secret.asc -d +# openssl aes-256-cbc -K ${encrypted_ef4535c39461_key} -iv ${encrypted_ef4535c39461_iv} -in subkey-328B3A0E-secret.asc.enc -out ./subkey-328B3A0E-secret.asc -d # gpg --allow-secret-key-import --import ./subkey-328B3A0E-secret.asc && rm subkey-328B3A0E-secret.asc # rm subkey-328B3A0E-secret.* || true # unset encrypted_ef4535c39461_key || true diff --git a/CMakeLists.txt b/CMakeLists.txt index f7f7b61e9..465574ba0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set ( CMAKE_BUILD_TYPE "Release" set_property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} ) # Add option and check environment to determine if developer tests should be run -if(ENV{OPENCOARRAYS_DEVELOPER}) +if($ENV{OPENCOARRAYS_DEVELOPER}) option(RUN_DEVELOPER_TESTS "Run tests intended only for developers" ON) else() option(RUN_DEVELOPER_TESTS "Run tests intended only for developers" OFF) @@ -477,6 +477,7 @@ if(opencoarrays_aware_compiler) add_mpi_test(register_alloc_comp_2 2 ${tests_root}/unit/init_register/register_alloc_comp_2) add_mpi_test(register_alloc_comp_3 2 ${tests_root}/unit/init_register/register_alloc_comp_3) if (RUN_DEVELOPER_TESTS) + message ( STATUS "Running Developer tests is enabled." ) add_mpi_test(async_comp_alloc 6 ${tests_root}/unit/init_register/async_comp_alloc) # Timeout async_comp_alloc test after 3 seconds to progess past the known failure set_property(TEST async_comp_alloc PROPERTY TIMEOUT_AFTER_MATCH 3 "known failure") diff --git a/codecov.yml b/codecov.yml index 77876980a..4ce203af2 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,23 +1,24 @@ +--- comment: layout: header, changes, diff, sunburst coverage: ignore: - - src/tests - - src/single - - src/gasnet - - src/mpi_cuda - - src/armci + - src/tests + - src/single + - src/gasnet + - src/mpi_cuda + - src/armci notify: gitter: default: branches: - - master + - master threshold: '0.1' url: https://webhooks.gitter.im/e/cd081feecb000a89d36b slack: default: branches: - - master + - master threshold: '0.01' url: https://hooks.slack.com/services/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 status: @@ -25,7 +26,6 @@ coverage: project: default: branches: - - master - - devel + - master + - devel target: auto - diff --git a/src/tests/installation/installation-scripts.sh b/src/tests/installation/installation-scripts.sh index 177f9ce1f..e4567ce7a 100755 --- a/src/tests/installation/installation-scripts.sh +++ b/src/tests/installation/installation-scripts.sh @@ -81,12 +81,23 @@ set -o errtrace +if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then + # shellcheck disable=SC2154 + if [[ "${__usage+x}" ]]; then + __b3bp_tmp_source_idx=1 + fi +fi + +# Set magic variables for current file, directory, os, etc. +__dir="$(cd "$(dirname "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" && pwd)" +__file="${__dir}/$(basename "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" + # requires `set -o errtrace` __b3bp_err_report() { - local error_code - error_code=${?} - error "Error in ${__file} in function ${1} on line ${2}" - exit ${error_code} + local error_code + error_code=${?} + error "Error in ${__file} in function ${1} on line ${2}" + exit ${error_code} } # Uncomment the following line for always providing an error backtrace trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR @@ -103,8 +114,8 @@ if [[ ! -f "${B3B_USE_CASE:-}/bootstrap.sh" ]]; then echo "Please set B3B_USE_CASE to the bash3boilerplate use-case directory path." exit 2 else - # shellcheck source=../../../prerequisites/use-case/bootstrap.sh - source "${B3B_USE_CASE}/bootstrap.sh" "$@" + # shellcheck source=../../../prerequisites/use-case/bootstrap.sh + source "${B3B_USE_CASE}/bootstrap.sh" "$@" fi ### End of boilerplate -- start user edits below ######################### @@ -113,12 +124,11 @@ export __flag_present=1 # Set up a function to call when receiving an EXIT signal to do some cleanup. Remove if # not needed. Other signals can be trapped too, like SIGINT and SIGTERM. -function cleanup_before_exit () { +function cleanup_before_exit() { info "Cleaning up. Done" } trap cleanup_before_exit EXIT # The signal is specified here. Could be SIGINT, SIGTERM etc. - pushd "${OPENCOARRAYS_SRC_DIR}"/src/tests/installation # shellcheck source=../../../prerequisites/stack.sh diff --git a/src/tests/installation/test-stack.sh b/src/tests/installation/test-stack.sh old mode 100644 new mode 100755 index 09ae41b5f..3a90b914d --- a/src/tests/installation/test-stack.sh +++ b/src/tests/installation/test-stack.sh @@ -1,139 +1,136 @@ -functions_exist() -{ - : "${1?'Missing function name list'}" +# shellcheck shell=bash +functions_exist() { + : "${1?'Missing function name list'}" - for function_name - do - if [[ "`type -t $function_name`" != "function" ]]; then + for function_name; do + if [[ "$(type -t "${function_name}")" != "function" ]]; then emergency "function ${function_name} does not exist" - fi - done + fi + done } -detect_missing_variable_name() -{ - : "${1?'detect_missing_variable name: Missing function name'}" +detect_missing_variable_name() { + : "${1?'detect_missing_variable name: Missing function name'}" - stack_new __dummy_stack + stack_new __dummy_stack - for function_name - do - expected_error="Missing variable name in ${function_name}" - error_message="$($function_name _dummy_stack_name 2>&1 > /dev/null)" || true - error_message="${error_message##*: }" # grab text after final colon/space sequence - if [[ "${error_message}" != ${expected_error} ]]; then - emergency "$function_name failed to detect '${expected_error}'" - fi + for function_name; do + expected_error="Missing variable name in ${function_name}" + error_message="$(${function_name} _dummy_stack_name 2>&1 >/dev/null)" || true + error_message="${error_message##*: }" # grab text after final colon/space sequence + if [[ "${error_message}" != "${expected_error}" ]]; then + emergency "${function_name} failed to detect '${expected_error}'" + fi done - stack_destroy __dummy_stack + stack_destroy __dummy_stack } -detect_missing_stack_name() -{ - : "${1?'detect_missing_name: Missing function name'}" - - expected_error="Missing stack name" - debug "detect_missing_stack_name: \${expected_error}=${expected_error}" - - for function_name - do - debug "detect_missing_stack_name: executing \"\$($function_name 2>&1 > /dev/null)\" || true" - error_message="$($function_name 2>&1 > /dev/null)" || true - error_message="${error_message##*: }" # grab text after final colon/space sequence - debug "detect_missing_stack_name: \${error_message}=${error_message}" - if [[ "${error_message}" != ${expected_error} ]]; then - emergency "$function_name failed to detect '${expected_error}'" - fi - done +detect_missing_stack_name() { + : "${1?'detect_missing_name: Missing function name'}" + + expected_error="Missing stack name" + debug "detect_missing_stack_name: \${expected_error}=${expected_error}" + + for function_name; do + debug "detect_missing_stack_name: executing \"\$(${function_name} 2>&1 > /dev/null)\" || true" + error_message="$(${function_name} 2>&1 >/dev/null)" || true + error_message="${error_message##*: }" # grab text after final colon/space sequence + debug "detect_missing_stack_name: \${error_message}=${error_message}" + if [[ "${error_message}" != "${expected_error}" ]]; then + emergency "${function_name} failed to detect '${expected_error}'" + fi + done } -detect_no_such_stack() -{ - : "${1?'detect_no_such_name: Missing function name'}" - - stack_name="__nonexistent_stack" - expected_error="No such stack -- " - debug "detect_no_such_stack: \${expected_error}=${expected_error}" - - dummy_variable="" - - for function_name - do - debug "detect_no_such_stack: executing \"\$($function_name $stack_name dummy_variable 2>&1 > /dev/null)\" || true" - error_message="$($function_name $stack_name dummy_variable 2>&1 > /dev/null)" || true - missing_stack="${error_message##${expected_error}}" # grab text after final colon/space sequence - debug "detect_no_such_stack: \${missing_stack}=${missing_stack}" - if [[ "${missing_stack}" != ${stack_name} ]]; then - emergency "$function_name failed to detect missing '${stack_name}'" - fi - done +detect_no_such_stack() { + : "${1?'detect_no_such_name: Missing function name'}" + + stack_name="__nonexistent_stack" + expected_error="No such stack -- " + debug "detect_no_such_stack: \${expected_error}=${expected_error}" + + # shellcheck disable=SC2034 + dummy_variable="" + + for function_name; do + debug "detect_no_such_stack: executing \"\$(${function_name} ${stack_name} dummy_variable 2>&1 > /dev/null)\" || true" + error_message="$(${function_name} ${stack_name} dummy_variable 2>&1 >/dev/null)" || true + missing_stack="${error_message##${expected_error}}" # grab text after final colon/space sequence + debug "detect_no_such_stack: \${missing_stack}=${missing_stack}" + if [[ "${missing_stack}" != "${stack_name}" ]]; then + emergency "${function_name} failed to detect missing '${stack_name}'" + fi + done } -detect_duplicate_stack_creation() -{ - : "${1?'detect_duplicate_stack_creation: Missing function name'}" - - stack_name="__dummy_stack" - stack_new "${stack_name}" - - expected_error="Stack already exists -- " - debug "detect_duplicate_stack_creation: \${expected_error}=${expected_error}" - function_name="stack_new" - - debug "detect_duplicate_stack_creation: executing \"\$($function_name $stack_name 2>&1 > /dev/null)\" || true" - error_message="$($function_name $stack_name dummy_variable 2>&1 > /dev/null)" || true - duplicate_stack="${error_message##${expected_error}}" # grab text after final colon/space sequence - debug "detect_no_such_stack: \${duplicate_stack}=${duplicate_stack}" - if [[ "${duplicate_stack}" != ${stack_name} ]]; then - emergency "$function_name failed to detect duplicate '${stack_name}'" - fi - stack_destroy ${stack_name} +detect_duplicate_stack_creation() { + : "${1?'detect_duplicate_stack_creation: Missing function name'}" + + stack_name="__dummy_stack" + stack_new "${stack_name}" + + expected_error="Stack already exists -- " + debug "detect_duplicate_stack_creation: \${expected_error}=${expected_error}" + function_name="stack_new" + + debug "detect_duplicate_stack_creation: executing \"\$(${function_name} ${stack_name} 2>&1 > /dev/null)\" || true" + error_message="$(${function_name} ${stack_name} dummy_variable 2>&1 >/dev/null)" || true + duplicate_stack="${error_message##${expected_error}}" # grab text after final colon/space sequence + debug "detect_no_such_stack: \${duplicate_stack}=${duplicate_stack}" + if [[ "${duplicate_stack}" != "${stack_name}" ]]; then + emergency "${function_name} failed to detect duplicate '${stack_name}'" + fi + stack_destroy ${stack_name} } -verify_stack_size_changes() -{ +verify_stack_size_changes() { stack_new foobar stack_size foobar __foobar_size expected_size=0 - if [[ "${__foobar_size}" != "${expected_size}" ]]; then + # shellcheck disable=SC2154 + if [[ "${__foobar_size}" != "${expected_size}" ]]; then emergency "verify_stack_size_changes: size=${__foobar_size} (expected ${expected_size})" fi stack_push foobar kernel stack_size foobar __foobar_new_size - (( expected_size += 1 )) - if [[ "${__foobar_new_size}" != "${expected_size}" ]]; then + ((expected_size += 1)) + # shellcheck disable=SC2154 + if [[ "${__foobar_new_size}" != "${expected_size}" ]]; then emergency "verify_stack_size_changes: size=${__foobar_new_size} (expected 1)" fi stack_peek foobar tmp - if [[ "${tmp}" != "kernel" ]]; then + # shellcheck disable=SC2154 + if [[ "${tmp}" != "kernel" ]]; then emergency "verify_stack_size_changes: peeked item ('${tmp}') mismatch with pushed item ('kernel')" fi stack_size foobar __should_be_unchanged - if [[ "${__should_be_unchanged}" != "${expected_size}" ]]; then + # shellcheck disable=SC2154 + if [[ "${__should_be_unchanged}" != "${expected_size}" ]]; then emergency "verify_stack_size_changes: size=${__should_be_unchanged} (expected ${expected_size})" fi stack_pop foobar popped - if [[ "${popped}" != "kernel" ]]; then + # shellcheck disable=SC2154 + if [[ "${popped}" != "kernel" ]]; then emergency "verify_stack_size_changes: popped item ('${popped}') mismatch with pushed item ('kernel')" fi - (( expected_size -= 1 )) || true + ((expected_size -= 1)) || true stack_size foobar __final_size - if [[ "${__final_size}" != "${expected_size}" ]]; then + # shellcheck disable=SC2154 + if [[ "${__final_size}" != "${expected_size}" ]]; then emergency "verify_stack_size_changes: size=${__final_size} (expected ${expected_size})" fi } -test_stack() -{ +test_stack() { # Verify availability of expected functions: functions_exist \ stack_new stack_exists stack_print stack_push stack_peek stack_pop stack_size stack_destroy - + # Verify that each named function detects missing stack-name arguments: detect_missing_stack_name \ stack_new stack_exists stack_print stack_push stack_peek stack_pop stack_size stack_destroy @@ -148,7 +145,7 @@ test_stack() # Verify that duplicate creation generates the expected error: detect_duplicate_stack_creation \ - stack_new + stack_new # Verify that push, peek, and pop yield correct size changes or lack thereof: verify_stack_size_changes