aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2024-10-30 12:21:20 -0400
committerGitHub <noreply@github.com>2024-10-30 12:21:20 -0400
commitf25f05d8ac309b343f8e34e882d92cb8bc78eca3 (patch)
tree740bbf4fa413357d1e839bd308ab545d1271de96
parentec55ea8fc503ad3fb53635d7e9e6d58a63c6684a (diff)
parent3da6e513cc64990aa865613bd0bb9ba5d6624570 (diff)
downloadstasis-f25f05d8ac309b343f8e34e882d92cb8bc78eca3.tar.gz
Merge pull request #65 from jhunkeler/more-rt
More RT
-rw-r--r--.github/workflows/cmake-multi-platform.yml1
-rw-r--r--src/lib/core/conda.c4
-rw-r--r--tests/CMakeLists.txt16
-rw-r--r--tests/README.md48
-rw-r--r--tests/_rt_boilerplate.sh27
-rw-r--r--tests/_test_boilerplate.c12
-rw-r--r--tests/data/generic_based_on.ini65
-rw-r--r--tests/data/generic_based_on.yml9
-rw-r--r--tests/rt_generic.sh125
-rw-r--r--tests/rt_generic_based_on.sh30
-rw-r--r--tests/setup.sh267
-rw-r--r--tests/test_download.c21
-rw-r--r--tests/test_junitxml.c4
13 files changed, 514 insertions, 115 deletions
diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml
index f141141..ef41555 100644
--- a/.github/workflows/cmake-multi-platform.yml
+++ b/.github/workflows/cmake-multi-platform.yml
@@ -58,6 +58,7 @@ jobs:
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DBUILD_TESTING=ON
+ -DBUILD_TESTING_RT=ON
-S ${{ github.workspace }}
- name: Build
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c
index 5954f20..c2cea0e 100644
--- a/src/lib/core/conda.c
+++ b/src/lib/core/conda.c
@@ -218,11 +218,13 @@ int conda_activate(const char *root, const char *env_name) {
const char *init_script_mamba = "/etc/profile.d/mamba.sh";
char path_conda[PATH_MAX] = {0};
char path_mamba[PATH_MAX] = {0};
+ char path_bin[PATH_MAX] = {0};
char logfile[PATH_MAX] = {0};
struct Process proc;
memset(&proc, 0, sizeof(proc));
// Where to find conda's init scripts
+ sprintf(path_bin, "%s/bin", root);
sprintf(path_conda, "%s%s", root, init_script_conda);
sprintf(path_mamba, "%s%s", root, init_script_mamba);
@@ -256,7 +258,7 @@ int conda_activate(const char *root, const char *env_name) {
// Fully activate conda and record its effect on the runtime environment
char command[PATH_MAX * 3];
- snprintf(command, sizeof(command) - 1, "set -a; source %s; source %s; conda activate %s &>/dev/null; env -0", path_conda, path_mamba, env_name);
+ snprintf(command, sizeof(command) - 1, "set -a; source %s; source %s; PATH=\"%s:$PATH\" conda activate %s &>/dev/null; env -0", path_conda, path_mamba, path_bin, env_name);
int retval = shell(&proc, command);
if (retval) {
// it didn't work; drop out for cleanup
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 0da290f..e35d88d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -9,17 +9,25 @@ set(nix_gnu_cflags -Wno-format-truncation -Wno-error -Wno-unused-parameter -Wno-
set(nix_clang_cflags -Wno-format-truncation -Wno-unused-parameter -Wno-unused-result -Wno-incompatible-pointer-types-discards-qualifiers)
set(win_msvc_cflags /Wall)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/data/generic.ini ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/data/result.xml ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/data/result_error.xml ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
file(GLOB source_files "test_*.c")
+file(GLOB rt_files "rt_*.sh")
+set(ext_pattern "(^.*/|\\.[^.]*$)")
+
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
if (BASH_PROGRAM AND BUILD_TESTING_RT)
+ foreach(rt_file ${rt_files})
+ file(REAL_PATH ${rt_file} rt_name)
+ string(REGEX REPLACE ${ext_pattern} "" rt_name ${rt_file})
+ add_test (${rt_name} ${BASH_PROGRAM} ${rt_file})
+ endforeach()
+ add_test (rt_generic_based_on ${BASH_PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/rt_generic_based_on.sh)
add_test (rt_generic ${BASH_PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/rt_generic.sh)
endif()
foreach(source_file ${source_files})
- string(REGEX REPLACE "(^.*/|\\.[^.]*$)" "" test_executable ${source_file})
+ string(REGEX REPLACE ${ext_pattern} "" test_executable ${source_file})
add_executable(${test_executable} ${source_file})
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_compile_options(${test_executable} PRIVATE ${nix_cflags} ${nix_gnu_cflags})
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 0000000..bb1f896
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,48 @@
+# Testing STASIS
+
+## Unit tests
+
+Rules:
+
+* Use the boilerplate `_test_boilerplate.c`
+ * ```shell
+ cp _test_boilerplate.c test_mynewtest.c
+ ```
+* Test file names start with `test_` (`test_file.c`)
+* Test functions start with `test_` (`void test_function()`)
+* Test suites can be skipped by returning `127` from `main()`
+* PASS, FAIL, and SKIP conditions are set by the assertion macros `STASIS_{ASSERT,ASSERT_FATAL,SKIP_IF}`
+* Parametrized tests should implement an array of `struct testcase`
+ * The `testcase` structure should be local to each `test_` function
+ * The `testcase` variables are freeform
+ * Example:
+ ```c
+ void test_function() {
+ struct testcase {
+ int your;
+ int variables;
+ int here;
+ };
+ struct testcase tc[] = {
+ {.your = 0, .variables = 1, .here = 2},
+ {.your = 3, .variables = 4, .here = 5},
+ // ...
+ };
+ for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) {
+ // STASIS_ASSERT()s here
+ }
+ }
+ ```
+
+## Regression test (RT)
+
+Rules:
+
+* Regression tests are shell scripts (BASH)
+* Use the boilerplate `_rt_boilerplate.sh`
+ * ```shell
+ cp _rt_boilerplate.sh rt_mynewtest.sh
+ ```
+* Test file names start with `rt_` (`rt_file.sh`)
+* Test function names are freeform, however they must be executed using `run_command()` (`run_command test_function`)
+* Test suites can be skipped by returning `127` from the shell script \ No newline at end of file
diff --git a/tests/_rt_boilerplate.sh b/tests/_rt_boilerplate.sh
new file mode 100644
index 0000000..22a2688
--- /dev/null
+++ b/tests/_rt_boilerplate.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+here="$(dirname ${BASH_SOURCE[0]})"
+source $here/setup.sh
+
+TEST_NAME=
+
+#test_fails() {
+# return 1
+#}
+#
+#test_passes() {
+# return 0
+#}
+#
+#test_skips() {
+# return 127
+#}
+
+setup_workspace "$TEST_NAME"
+
+#run_command test_fails
+#run_command test_passes
+#run_command test_skips
+#run_command false # fails
+#run_command true # passes
+
+teardown_workspace "$TEST_NAME" \ No newline at end of file
diff --git a/tests/_test_boilerplate.c b/tests/_test_boilerplate.c
index 1d7734b..b13568d 100644
--- a/tests/_test_boilerplate.c
+++ b/tests/_test_boilerplate.c
@@ -1,16 +1,24 @@
#include "testing.h"
+/*
void test_NAME() {
struct testcase {
};
- STASIS_ASSERT();
+ struct testcase tc[] = {
+ { // ... },
+ }
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) {
+ // STASIS_ASSERT();
+ }
}
+ */
int main(int argc, char *argv[]) {
STASIS_TEST_BEGIN_MAIN();
STASIS_TEST_FUNC *tests[] = {
- test_NAME,
+ //test_NAME,
};
STASIS_TEST_RUN(tests);
STASIS_TEST_END_MAIN();
diff --git a/tests/data/generic_based_on.ini b/tests/data/generic_based_on.ini
new file mode 100644
index 0000000..1c993ea
--- /dev/null
+++ b/tests/data/generic_based_on.ini
@@ -0,0 +1,65 @@
+[meta]
+mission = generic
+name = GENERIC
+version = 1.2.3
+rc = 1
+final = false
+based_on = {{ env:TEST_DATA }}/generic_based_on.yml
+python = 3.11
+
+
+[conda]
+installer_name = Miniforge3
+installer_version = 24.3.0-0
+installer_platform = {{env:STASIS_CONDA_PLATFORM}}
+installer_arch = {{env:STASIS_CONDA_ARCH}}
+installer_baseurl = https://github.com/conda-forge/miniforge/releases/download/{{conda.installer_version}}
+;conda_packages =
+pip_packages =
+ firewatch==0.0.4
+ tweakwcs==0.8.8
+
+
+[runtime]
+CPPFLAGS = ${CPPFLAGS} -fpermissive
+PYTHONUNBUFFERED = 1
+
+
+[test:firewatch]
+repository = https://github.com/astroconda/firewatch
+script_setup =
+ pip install -e '.'
+script =
+ firewatch -c conda-forge -p ${STASIS_CONDA_PLATFORM_SUBDIR} | grep -E ' python-[0-9]'
+
+
+[test:tweakwcs]
+repository = https://github.com/spacetelescope/tweakwcs
+script_setup =
+ pip install -e '.[test]'
+script =
+ pytest \
+ -r fEsx \
+ --basetemp="{{ func:basetemp_dir() }}" \
+ --junitxml="{{ func:junitxml_file() }}"
+
+
+[deploy:artifactory:delivery]
+files =
+ {{ storage.output_dir }}/**
+dest = {{ meta.mission }}/{{ info.build_name }}/
+
+
+[deploy:docker]
+registry = bytesalad.stsci.edu
+image_compression = zstd -v -9 -c
+build_args =
+ SNAPSHOT_INPUT={{ info.release_name }}.yml
+ SNAPSHOT_PKGDIR=packages
+tags =
+ {{ meta.name }}:{{ info.build_number }}-py{{ meta.python_compact }}
+ {{ deploy.docker.registry }}/{{ meta.name }}:{{ info.build_number }}-py{{ meta.python_compact }}
+test_script =
+ source /etc/profile
+ python -m pip freeze
+ mamba info
diff --git a/tests/data/generic_based_on.yml b/tests/data/generic_based_on.yml
new file mode 100644
index 0000000..3ab97a7
--- /dev/null
+++ b/tests/data/generic_based_on.yml
@@ -0,0 +1,9 @@
+channels:
+ - conda-forge
+dependencies:
+ - pip
+ - python
+ - setuptools
+ - pip:
+ - firewatch==0.0.3
+ - tweakwcs==0.8.7 \ No newline at end of file
diff --git a/tests/rt_generic.sh b/tests/rt_generic.sh
index 6e4454c..674f6f0 100644
--- a/tests/rt_generic.sh
+++ b/tests/rt_generic.sh
@@ -1,110 +1,31 @@
#!/usr/bin/env bash
-set -x
-unset STASIS_SYSCONFDIR
-if [ -n "$GITHUB_TOKEN" ] && [ -z "$STASIS_GH_TOKEN"]; then
- export STASIS_GH_TOKEN="$GITHUB_TOKEN"
-else
- export STASIS_GH_TOKEN="anonymous"
-fi
-python_versions=(
- 3.10
+here="$(dirname ${BASH_SOURCE[0]})"
+source $here/setup.sh
+
+TEST_NAME=generic
+PYTHON_VERSIONS=(
3.11
- 3.12
)
-topdir=$(pwd)
-
-ws="rt_workspace"
-rm -rf "$ws"
-mkdir -p "$ws"
-ws="$(realpath $ws)"
-
-prefix="$ws"/local
-mkdir -p "$prefix"
-
-bdir="$ws"/build
-mkdir -p "$bdir"
-
-pushd "$bdir"
-cmake -DCMAKE_INSTALL_PREFIX="$prefix" -DCMAKE_BUILD_TYPE=Debug "${topdir}"/../..
-make install
-export PATH="$prefix/bin:$PATH"
-popd
-
-pushd "$ws"
- type -P stasis
- type -P stasis_indexer
- retcode=0
-
- for py_version in "${python_versions[@]}"; do
- stasis --python "$py_version" --no-docker --no-artifactory --unbuffered -v "$topdir"/generic.ini
- retcode+=$?
- done
-
- set +x
-
- echo "#### Files ####"
- find stasis/*/output | sort
- echo
-
- echo "#### Contents ####"
- files=$(find stasis/*/output -type f \( -name '*.yml' -o -name '*.md' -o -name '*.stasis' -o -name '*.ini' \) | sort)
- for x in $files; do
- echo
- echo "FILENAME: $x"
- echo
- cat "$x"
- echo "[EOF]"
- echo
-
- fail_on_main=(
- "(null)"
- )
- for cond in "${fail_on_main[@]}"; do
- if grep --color -H -n "$cond" "$x" >&2; then
- echo "ERROR DETECTED IN $x!" >&2
- retcode+=1
- fi
- done
- done
-
- # Something above failed, so drop out. Don't bother indexing.
- # Don't clean up either.
- (( retcode )) && exit $retcode
-
- fail_on_indexer=(
- "(null)"
- )
- logfile="stasis_indexer.log"
- set -x
- stasis_indexer --web --unbuffered -v stasis/* 2>&1 | tee "$logfile"
- retcode=$?
-
- set +x
- echo "#### Files ####"
- find output
+setup_workspace "$TEST_NAME"
+run_command install_stasis
+for py_version in "${PYTHON_VERSIONS[@]}"; do
+ run_command run_stasis --python "$py_version" \
+ --no-docker \
+ --no-artifactory \
+ "$TEST_DATA"/"$TEST_NAME".ini
+done
- for cond in "${fail_on_indexer[@]}"; do
- if grep --color -H -n "$cond" "$logfile" >&2; then
- echo "ERROR DETECTED IN INDEX OPERATION!" >&2
- exit 1
- fi
- done
+check_output_add "(null)"
+run_command check_output_stasis_dir stasis/*/output
+check_output_reset
- echo "#### Contents ####"
- files=$(find output -type f \( -name '*.html' \) | sort)
- for x in $files; do
- echo
- echo "FILENAME: $x"
- echo
- cat "$x"
- echo "[EOF]"
- echo
- done
-popd
+# NOTE: indexer default output directory is "output"
+check_output_add "(null)"
+run_command run_stasis_indexer stasis
+run_command check_output_indexed_dir output
+check_output_reset
-if [ -z "$RT_KEEP_WORKSPACE" ]; then
- rm -rf "$ws"
-fi
+run_command assert_file_contains "$LOGFILE_STASIS" "USE EXTERNAL" "External packages should have been used"
-exit $retcode \ No newline at end of file
+teardown_workspace "$TEST_NAME" \ No newline at end of file
diff --git a/tests/rt_generic_based_on.sh b/tests/rt_generic_based_on.sh
new file mode 100644
index 0000000..7d78399
--- /dev/null
+++ b/tests/rt_generic_based_on.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+here="$(dirname ${BASH_SOURCE[0]})"
+source $here/setup.sh
+
+TEST_NAME=generic_based_on
+PYTHON_VERSIONS=(
+ 3.11
+)
+setup_workspace "$TEST_NAME"
+run_command install_stasis
+
+ln -s "$TEST_DATA"/"$TEST_NAME".yml
+for py_version in "${PYTHON_VERSIONS[@]}"; do
+ run_command run_stasis --python "$py_version" \
+ --no-docker \
+ --no-artifactory \
+ "$TEST_DATA"/"$TEST_NAME".ini
+done
+
+check_output_add "(null)"
+run_command check_output_stasis_dir stasis/*/output
+check_output_reset
+
+# NOTE: indexer default output directory is "output"
+check_output_add "(null)"
+run_command run_stasis_indexer stasis
+run_command check_output_indexed_dir output
+check_output_reset
+
+teardown_workspace "$TEST_NAME"
diff --git a/tests/setup.sh b/tests/setup.sh
new file mode 100644
index 0000000..0875cac
--- /dev/null
+++ b/tests/setup.sh
@@ -0,0 +1,267 @@
+#!/usr/bin/env bash
+set -o pipefail
+
+export LOGFILE_STASIS="stasis.log"
+export LOGFILE_INDEXER="stasis_indexer.log"
+export CHECK_OUTPUT_PATTERNS=()
+
+unset STASIS_SYSCONFDIR
+if [ -n "$GITHUB_TOKEN" ] && [ -z "$STASIS_GH_TOKEN"]; then
+ export STASIS_GH_TOKEN="$GITHUB_TOKEN"
+else
+ export STASIS_GH_TOKEN="anonymous"
+fi
+
+if [[ -z "$PYTHON_VERSIONS" ]]; then
+ PYTHON_VERSIONS=(
+ 3.10
+ 3.11
+ 3.12
+ )
+fi
+
+setup_script_dir="$(dirname ${BASH_SOURCE[0]})"
+export TOPDIR=$(pwd)
+export TEST_DATA="$TOPDIR"/data
+
+WS_DEFAULT=rt_workspace_
+setup_workspace() {
+ if [ -z "$1" ]; then
+ echo "setup_workspace requires a name argument" >&2
+ return 1
+ fi
+ WORKSPACE="${WS_DEFAULT}$1"
+ rm -rf "$WORKSPACE"
+ if ! mkdir -p "$WORKSPACE"; then
+ echo "directory creation failed. cannot continue" >&2
+ return 1;
+ fi
+ WORKSPACE="$(realpath $WORKSPACE)"
+
+ export PREFIX="$WORKSPACE"/local
+ if ! mkdir -p "$PREFIX"; then
+ echo "directory creation failed. cannot continue" >&2
+ return 1;
+ fi
+
+ export BUILD_DIR="$WORKSPACE"/build
+ if ! mkdir -p "$BUILD_DIR"; then
+ echo "directory creation failed. cannot continue" >&2
+ return 1;
+ fi
+
+ pushd "$WORKSPACE"
+ export LANG="C"
+ export HOME="$WORKSPACE"
+ . /etc/profile
+}
+
+teardown_workspace() {
+ if [ -z "$1" ]; then
+ echo "teardown_workspace requires a workspace path" >&2
+ return 1
+ elif ! [[ ${WS_DEFAULT}$1 =~ ${WS_DEFAULT}.* ]]; then
+ echo "$1 is not a valid workspace" >&2
+ return 1
+ fi
+ popd
+ clean_up
+}
+
+install_stasis() {
+ pushd "$BUILD_DIR"
+ if ! cmake -DCMAKE_INSTALL_PREFIX="$PREFIX" -DCMAKE_BUILD_TYPE=Debug "${TOPDIR}"/../..; then
+ echo "cmake failed" >&2
+ return 1
+ fi
+
+ if ! make install; then
+ echo "make failed" >&2
+ return 1
+ fi
+
+ export PATH="$PREFIX/bin:$PATH"
+ hash -r
+ if ! type -P stasis; then
+ echo "stasis program not on PATH" >&2
+ return 1
+ fi
+
+ if ! type -P stasis_indexer; then
+ echo "stasis_indexer program not on PATH" >&2
+ return 1
+ fi
+ popd
+}
+
+
+STASIS_TEST_RESULT_FAIL=0
+STASIS_TEST_RESULT_PASS=0
+STASIS_TEST_RESULT_SKIP=0
+run_command() {
+ local logfile="$(mktemp).log"
+ local cmd="${@}"
+ local lines_on_error=100
+ /bin/echo "Testing: $cmd "
+
+ $cmd &>"$logfile"
+ code=$?
+ if (( code )); then
+ if (( code == 127 )); then
+ echo "... SKIP"
+ (( STASIS_TEST_RESULT_SKIP++ ))
+ else
+ echo "... FAIL"
+ if (( $(wc -c "$logfile" | cut -d ' ' -f 1) > 1 )); then
+ echo "#"
+ echo "# Last $lines_on_error line(s) follow:"
+ echo "#"
+ tail -n $lines_on_error "$logfile"
+ fi
+ (( STASIS_TEST_RESULT_FAIL++ ))
+ fi
+ else
+ echo "... PASS"
+ (( STASIS_TEST_RESULT_PASS++ ))
+ fi
+ rm -f "$logfile"
+}
+
+run_summary() {
+ local total=$(( STASIS_TEST_RESULT_PASS + STASIS_TEST_RESULT_FAIL + STASIS_TEST_RESULT_SKIP))
+ echo
+ echo "[RT] ${STASIS_TEST_RESULT_PASS} tests passed, ${STASIS_TEST_RESULT_FAIL} failed, ${STASIS_TEST_RESULT_SKIP} skipped out of ${total}"
+ echo
+}
+
+run_stasis() {
+ local logfile="$LOGFILE_STASIS"
+ $(type -P stasis) --unbuffered -v $@ 2>&1 | tee "$logfile"
+}
+
+run_stasis_indexer() {
+ local logfile="$LOGFILE_INDEXER"
+ local root="$1"
+ if [ -z "$root" ]; then
+ echo "run_stasis_indexer root directory cannot be empty" >&2
+ exit 1
+ fi
+ $(type -P stasis_indexer) --web --unbuffered -v "$root"/* 2>&1 | tee "$logfile"
+}
+
+check_output_add() {
+ local pattern="$1"
+ CHECK_OUTPUT_PATTERNS+=("$pattern")
+}
+
+check_output_reset() {
+ CHECK_OUTPUT_PATTERNS=()
+}
+
+check_output_stasis_dir() {
+ local retcode=0
+ local startdir="$1"
+ local logfile="$LOGFILE_STASIS"
+
+ echo "#### Files ####"
+ find $startdir | sort
+ echo
+
+ echo "#### Contents ####"
+ files=$(find $startdir -type f \( -name "$logfile" -o -name '*.yml' -o -name '*.md' -o -name '*.stasis' -o -name '*.ini' \) | sort)
+ for x in $files; do
+ echo
+ echo "FILENAME: $x"
+ echo
+ if [ "$x" == "$logfile" ]; then
+ # do not print thousands of lines of output we _just_ sat through
+ echo "Output omitted"
+ else
+ cat "$x"
+ echo "[EOF]"
+ fi
+ echo
+
+ for cond in "${CHECK_OUTPUT_PATTERNS[@]}"; do
+ if grep --color -H -n "$cond" "$x" >&2; then
+ echo "ERROR DETECTED IN $x!" >&2
+ retcode+=1
+ fi
+ done
+ done
+
+ if (( retcode )); then
+ return 1
+ else
+ return 0
+ fi
+}
+
+check_output_indexed_dir() {
+ local retcode=0
+ local startdir="$1"
+ local logfile="$2"
+
+ echo "#### Files ####"
+ find $startdir | sort
+
+ for cond in "${CHECK_OUTPUT_PATTERNS[@]}"; do
+ if grep --color -H -n "$cond" "$logfile" >&2; then
+ echo "ERROR DETECTED IN INDEX OPERATION!" >&2
+ retcode+=1
+ fi
+ done
+
+ echo "#### Contents ####"
+ files=$(find $startdir -type f \( -name '*.html' \) | sort)
+ for x in $files; do
+ echo
+ echo "FILENAME: $x"
+ echo
+ cat "$x"
+ echo "[EOF]"
+ echo
+ done
+ if (( retcode )); then
+ return 1
+ else
+ return 0
+ fi
+}
+
+assert_eq() {
+ local a="$1"
+ local b="$2"
+ local msg="$3"
+ if [[ "$a" == "$b" ]]; then
+ return 0
+ else
+ [[ -n "$msg" ]] && echo "'$a' != '$b' :: $msg" >&2
+ return 1
+ fi
+}
+
+assert_file_contains() {
+ local file="$1"
+ local str="$2"
+ local msg="$3"
+ if grep -E "$str" "$file" &>/dev/null; then
+ return 0
+ else
+ [[ -n "$msg" ]] && echo "'$str' not in file '$file' :: $msg" >&2
+ return 1
+ fi
+}
+
+clean_up() {
+ if [ -z "$RT_KEEP_WORKSPACE" ] && [ -d "$WORKSPACE" ]; then
+ rm -rf "$WORKSPACE"
+ fi
+
+ run_summary
+ if (( STASIS_TEST_RESULT_FAIL )); then
+ exit 1
+ else
+ exit 0
+ fi
+} \ No newline at end of file
diff --git a/tests/test_download.c b/tests/test_download.c
index ad8724e..714e614 100644
--- a/tests/test_download.c
+++ b/tests/test_download.c
@@ -2,15 +2,20 @@
#include "download.h"
void test_download() {
+ enum MATCH_STYLE {
+ match_begins=0,
+ match_contains,
+ };
struct testcase {
const char *url;
long http_code;
+ enum MATCH_STYLE style;
const char *data;
const char *errmsg;
};
struct testcase tc[] = {
- {.url = "https://ssb.stsci.edu/jhunk/stasis_test/test_download.txt", .http_code = 200L, .data = "It works!\n", .errmsg = NULL},
- {.url = "https://ssb.stsci.edu/jhunk/stasis_test/test_download.broken", .http_code = 404L, .data = "<html", .errmsg = NULL},
+ {.url = "https://ssb.stsci.edu/jhunk/stasis_test/test_download.txt", .http_code = 200L, .data = "It works!\n", .style = match_begins, .errmsg = NULL},
+ {.url = "https://ssb.stsci.edu/jhunk/stasis_test/test_download.broken", .http_code = 404L, .data = "404", .style = match_contains, .errmsg = NULL},
{.url = "https://example.tld", .http_code = -1L, .data = NULL, .errmsg = "Couldn't resolve host name"},
};
@@ -28,10 +33,18 @@ void test_download() {
}
STASIS_ASSERT(http_code == tc[i].http_code, "expecting non-error HTTP code");
- char **data = file_readlines(filename, 0, 100, NULL);
+ //char **data = file_readlines(filename, 0, 100, NULL);
+ char *data = stasis_testing_read_ascii(filename);
if (http_code >= 0) {
STASIS_ASSERT(data != NULL, "data should not be null");
- STASIS_ASSERT(strncmp(data[0], tc[i].data, strlen(tc[i].data)) == 0, "data file does not match the expected contents");
+ printf("FILE: %s\nLOCAL: '%s'\nREMOTE: '%s'\n", tc[i].url, data, tc[i].data);
+ if (tc[i].style == match_begins) {
+ STASIS_ASSERT(strncmp(data, tc[i].data, strlen(tc[i].data)) == 0, "data file does not begin with the expected contents");
+ } else if (tc[i].style == match_contains) {
+ STASIS_ASSERT(strstr(data, tc[i].data) != NULL, "data file does not contain the expected contents");
+ } else {
+ STASIS_ASSERT(false, "Unrecognized matching mode");
+ }
} else {
STASIS_ASSERT(http_code == -1, "http_code should be -1 on fatal curl error");
STASIS_ASSERT(data == NULL, "data should be NULL on fatal curl error");
diff --git a/tests/test_junitxml.c b/tests/test_junitxml.c
index 7111249..e222b56 100644
--- a/tests/test_junitxml.c
+++ b/tests/test_junitxml.c
@@ -3,7 +3,7 @@
void test_junitxml_testsuite_read() {
struct JUNIT_Testsuite *testsuite;
- STASIS_ASSERT_FATAL((testsuite = junitxml_testsuite_read("result.xml")) != NULL, "failed to load testsuite data");
+ STASIS_ASSERT_FATAL((testsuite = junitxml_testsuite_read("data/result.xml")) != NULL, "failed to load testsuite data");
STASIS_ASSERT(testsuite->name != NULL, "Test suite must be named");
STASIS_ASSERT(testsuite->skipped > 0, "missed skipped tests");
STASIS_ASSERT(testsuite->failures > 0, "missed failed tests");
@@ -44,7 +44,7 @@ void test_junitxml_testsuite_read() {
void test_junitxml_testsuite_read_error() {
struct JUNIT_Testsuite *testsuite;
- STASIS_ASSERT_FATAL((testsuite = junitxml_testsuite_read("result_error.xml")) != NULL, "failed to load testsuite data");
+ STASIS_ASSERT_FATAL((testsuite = junitxml_testsuite_read("data/result_error.xml")) != NULL, "failed to load testsuite data");
STASIS_ASSERT(testsuite->name != NULL, "test suite must be named");
STASIS_ASSERT(testsuite->skipped == 0, "should not have any skipped tests");