aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2020-07-02 10:53:55 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2020-07-02 10:53:55 -0400
commit5803dc0fdb911a67ad9ca1ef9600edc58331d55a (patch)
tree0289621a8a98b3dd91a7d9b0e35ec62b5c160e24
parent8e0934853a374eb340ee0dd96fd21a3d7c74183d (diff)
downloadsplitfits-5803dc0fdb911a67ad9ca1ef9600edc58331d55a.tar.gz
Add basic test framework and a few tests
-rw-r--r--CMakeLists.txt6
-rwxr-xr-xtest.sh184
-rw-r--r--tests/test_split.sh35
-rw-r--r--tests/test_usage.sh9
4 files changed, 234 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ea12358..5287d06 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,5 +5,11 @@ set(CMAKE_C_STANDARD 99)
add_executable(splitfits splitfits.c)
+file(GLOB TEST_FRAMEWORK "tests")
+file(COPY "test.sh" DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${TEST_FRAMEWORK} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
+add_custom_target(check "${CMAKE_CURRENT_BINARY_DIR}/test.sh")
+
install(TARGETS splitfits
RUNTIME)
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..56f6abb
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,184 @@
+#!/usr/bin/env bash
+set -o pipefail
+
+RTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+test_program=${RTDIR}/splitfits
+test_data=${RTDIR}/data
+test_data_remote=https://nx.astroconda.org/repository
+test_data_remote_auth=${test_data_remote_auth:-}
+test_data_upload=generic/spb-splitfits/$(git describe --always)
+
+get_data_exists() {
+ local url
+ local response
+
+ url="${test_data_remote}/$1"
+ if [[ -z $url ]]; then
+ echo "get_data_exists: requires a path relative to $test_data_remote"
+ exit 1
+ fi
+
+ response=$(curl -s --head "$url" | head -n 1 | awk '{print $2}')
+ if (( $response != 200 )); then
+ return 1;
+ fi
+ return 0;
+}
+
+get_data() {
+ local url
+ local filename
+
+ if [[ ! -d "${test_data}" ]]; then
+ mkdir -p "${test_data}"
+ fi
+
+ url="${test_data_remote}/$1"
+ if [[ -z $url ]]; then
+ echo "get_data: requires a path relative to $test_data_remote"
+ exit 1
+ fi
+
+ filename=$(basename $url)
+ if ! get_data_exists "$1"; then
+ echo "${url}: not found on remote server" >&2
+ return 1
+ fi
+
+ if ! (cd $test_data && curl -L -O "$url"); then
+ echo "Could not download data" >&2
+ return 1
+ fi
+
+ echo "$test_data/$filename";
+}
+
+put_data() {
+ local url
+ local filename
+
+ url="${test_data_remote}/$2"
+ filename="$1"
+
+ if [[ -z $url ]]; then
+ echo "put_data: requires a path relative to $test_data_remote"
+ return 1
+ fi
+
+ if ! curl -s --user "${test_data_remote_auth}" --upload-file "${filename}" "${url}/${filename}"; then
+ echo "Could not upload '${filename}' to '${url}'" >&2
+ return 1
+ fi
+
+ return 0
+}
+
+put_result() {
+ local src;
+ local dest;
+ src="$1"
+ dest="$2"
+
+ if [[ ! -d "$src" ]]; then
+ echo "push_result: source directory does not exist: ${src}" >&2
+ return 1
+ fi
+
+ if [[ -z "$dest" ]]; then
+ echo "push_result: requires a destination relative to ${test_data_remote}" >&2
+ return 1
+ fi
+
+ for f in $(find "${src}" -type f); do
+ echo "Uploading '$f' to '$dest'"
+ if ! put_data "$f" "${dest}"; then
+ echo "Failed uploading '$src' to '$dest'" >&2
+ return 1
+ fi
+ done;
+ return 0
+}
+
+read_tests() {
+ for f in "${RTDIR}"/tests/test_*; do
+ source "$f" || return 0
+ done
+ return 1
+}
+
+export_tests() {
+ tests=(
+ $(declare -f | cut -d ' ' -f 1 | grep -E '^test_')
+ )
+ total_passed=0
+ total_failed=0
+ total_tests=${#tests[@]}
+}
+
+run_tests() {
+ for (( i=0; i < ${total_tests}; i++ )); do
+ just_failed=0
+ test_case="${tests[$i]}"
+ rm -rf "${test_case}"
+ mkdir -p "${test_case}"
+ pushd "${test_case}" &>/dev/null
+ log_file="output_${test_case}.log"
+
+ /bin/echo -n -e "[$i] ${test_case}... "
+ "$test_case" 2>&1 | tee ${log_file} &>/dev/null
+ retval=$?
+
+ if [[ "$retval" -ne "0" ]]; then
+ echo "FAILED ($retval)"
+ (( just_failed++ ))
+ (( total_failed++ ))
+ else
+ echo "PASSED"
+ (( total_passed++ ))
+ fi
+
+ if [[ ${just_failed} -ne 0 ]] && [[ -s ${log_file} ]]; then
+ echo "# OUTPUT:"
+ cat "${log_file}"
+ fi
+ popd &>/dev/null
+ done
+
+ # Upload all artifacts in all test directories
+ if [[ -n "$test_data_remote_auth" ]]; then
+ echo
+ for (( i=0; i < ${total_tests}; i++ )); do
+ test_case="${tests[i]}"
+ put_result ${test_case} ${test_data_upload}
+ done
+ fi
+}
+
+check_runtime() {
+ if [[ ! -f "${test_program}" ]]; then
+ echo "Tests cannot run without: ${test_program}" >&2
+ exit 1
+ fi
+}
+
+show_stats() {
+ printf "\n%d test(s): %d passed, %d failed\n" ${total_tests} ${total_passed} ${total_failed}
+}
+
+# main program
+check_runtime
+
+if read_tests; then
+ echo "Failed to aggregate tests." >&2
+ exit 1
+fi
+
+export_tests
+run_tests
+show_stats
+
+if (( total_failed )); then
+ exit 1
+fi
+
+exit 0
diff --git a/tests/test_split.sh b/tests/test_split.sh
new file mode 100644
index 0000000..141e320
--- /dev/null
+++ b/tests/test_split.sh
@@ -0,0 +1,35 @@
+test_splitfits_data1() {
+ local datafile
+ local retval
+
+ retval=0
+ datafile=$(get_data generic/fits/sample.fits)
+ [[ ! -f ${datafile} ]] && return 1
+
+ if ! ${test_program} -o ${test_case} ${datafile}; then
+ return 1
+ fi
+
+ set +x
+ return $retval
+}
+
+test_splitfits_combine_data1() {
+ local datafile
+ local retval
+
+ retval=0
+ datafile=$(get_data generic/fits/sample.fits)
+ [[ ! -f ${datafile} ]] && return 1
+
+ if ! ${test_program} -o ${test_case} ${datafile}; then
+ return 1
+ fi
+
+ if ! ${test_program} -c ${test_case}/$(basename ${datafile}).part_map; then
+ return 1
+ fi
+
+ set +x
+ return $retval
+}
diff --git a/tests/test_usage.sh b/tests/test_usage.sh
new file mode 100644
index 0000000..2a257d9
--- /dev/null
+++ b/tests/test_usage.sh
@@ -0,0 +1,9 @@
+test_splitfits_usage_longopt() {
+ ${test_program} --help
+ return $?
+}
+
+test_splitfits_usage_shortopt() {
+ ${test_program} -h
+ return $?
+}