aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2024-11-06 08:55:52 -0500
committerGitHub <noreply@github.com>2024-11-06 08:55:52 -0500
commit52e6d0f495023c0aa939bf6b2170ca5ea853202b (patch)
tree897a87316c280b6824892368662afcb848de1cf6 /tests
parent6db1b15b5c62d6fb52825c1d833ac8dfa9a49fbb (diff)
parent46ae10e55603b8852612ebe12c7636c2b358bdd6 (diff)
downloadstasis-52e6d0f495023c0aa939bf6b2170ca5ea853202b.tar.gz
Merge pull request #67 from jhunkeler/safety-and-convenience
Safety and convenience
Diffstat (limited to 'tests')
-rw-r--r--tests/data/generic_based_on.ini2
-rw-r--r--tests/setup.sh22
-rw-r--r--tests/test_conda.c6
-rw-r--r--tests/test_junitxml.c9
-rw-r--r--tests/test_str.c8
-rw-r--r--tests/testing.h94
6 files changed, 123 insertions, 18 deletions
diff --git a/tests/data/generic_based_on.ini b/tests/data/generic_based_on.ini
index 1c993ea..1287933 100644
--- a/tests/data/generic_based_on.ini
+++ b/tests/data/generic_based_on.ini
@@ -1,6 +1,6 @@
[meta]
mission = generic
-name = GENERIC
+name = GENERIC_BASED_ON
version = 1.2.3
rc = 1
final = false
diff --git a/tests/setup.sh b/tests/setup.sh
index 0875cac..50209ae 100644
--- a/tests/setup.sh
+++ b/tests/setup.sh
@@ -24,7 +24,15 @@ setup_script_dir="$(dirname ${BASH_SOURCE[0]})"
export TOPDIR=$(pwd)
export TEST_DATA="$TOPDIR"/data
-WS_DEFAULT=rt_workspace_
+pushd() {
+ command pushd "$@" 1>/dev/null
+}
+
+popd() {
+ command popd 1>/dev/null
+}
+
+WS_DEFAULT="workspaces/rt_workspace_"
setup_workspace() {
if [ -z "$1" ]; then
echo "setup_workspace requires a name argument" >&2
@@ -253,8 +261,18 @@ assert_file_contains() {
fi
}
+clean_up_docker() {
+ CONTAINERS_DIR="$WORKSPACE/.local/share/containers"
+ # HOME points to the WORKSPACE. The only reason we'd have this directory is if docker/podman was executed
+ # Fair to assume if the directory exists, docker/podman is functional.
+ if [ -d "$CONTAINERS_DIR" ]; then
+ docker run --rm -it -v $CONTAINERS_DIR:/data alpine sh -c '/bin/rm -r -f /data/*'
+ fi
+}
+
clean_up() {
- if [ -z "$RT_KEEP_WORKSPACE" ] && [ -d "$WORKSPACE" ]; then
+ if ([ -z "$RT_KEEP_WORKSPACE" ] || [ -z "$KEEP_WORKSPACE" ]) && [ -d "$WORKSPACE" ]; then
+ clean_up_docker
rm -rf "$WORKSPACE"
fi
diff --git a/tests/test_conda.c b/tests/test_conda.c
index 84f98bc..63a2781 100644
--- a/tests/test_conda.c
+++ b/tests/test_conda.c
@@ -202,7 +202,11 @@ int main(int argc, char *argv[]) {
test_delivery_gather_tool_versions,
};
- const char *ws = "workspace";
+ char ws[] = "workspace_XXXXXX";
+ if (!mkdtemp(ws)) {
+ perror("mkdtemp");
+ exit(1);
+ }
getcwd(cwd_start, sizeof(cwd_start) - 1);
mkdir(ws, 0755);
chdir(ws);
diff --git a/tests/test_junitxml.c b/tests/test_junitxml.c
index e222b56..362cb32 100644
--- a/tests/test_junitxml.c
+++ b/tests/test_junitxml.c
@@ -3,7 +3,10 @@
void test_junitxml_testsuite_read() {
struct JUNIT_Testsuite *testsuite;
- STASIS_ASSERT_FATAL((testsuite = junitxml_testsuite_read("data/result.xml")) != NULL, "failed to load testsuite data");
+ char datafile[PATH_MAX] = {0};
+ snprintf(datafile, sizeof(datafile) - 1, "%s/result.xml", TEST_DATA_DIR);
+
+ STASIS_ASSERT_FATAL((testsuite = junitxml_testsuite_read(datafile)) != 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 +47,9 @@ void test_junitxml_testsuite_read() {
void test_junitxml_testsuite_read_error() {
struct JUNIT_Testsuite *testsuite;
- STASIS_ASSERT_FATAL((testsuite = junitxml_testsuite_read("data/result_error.xml")) != NULL, "failed to load testsuite data");
+ char datafile[PATH_MAX] = {0};
+ snprintf(datafile, sizeof(datafile) - 1, "%s/result_error.xml", TEST_DATA_DIR);
+ STASIS_ASSERT_FATAL((testsuite = junitxml_testsuite_read(datafile)) != 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");
diff --git a/tests/test_str.c b/tests/test_str.c
index 4991c1c..3aea50b 100644
--- a/tests/test_str.c
+++ b/tests/test_str.c
@@ -204,8 +204,7 @@ void test_split() {
{.data = NULL, .delim = NULL, NULL},
};
for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) {
- char **result;
- result = split(tc[i].data, tc[i].delim, tc[i].max_split);
+ char **result = split((char *) tc[i].data, tc[i].delim, tc[i].max_split);
STASIS_ASSERT(strcmp_array((const char **) result, tc[i].expected) == 0, "Split failed");
GENERIC_ARRAY_FREE(result);
}
@@ -243,8 +242,7 @@ void test_join_ex() {
{.delim = "\n\n", .expected = "a\n\nb\n\nc\n\nd\n\ne"},
};
for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) {
- char *result;
- result = join_ex((char *) tc[i].delim, "a", "b", "c", "d", "e", NULL);
+ char *result = join_ex((char *) tc[i].delim, "a", "b", "c", "d", "e", NULL);
STASIS_ASSERT(strcmp(result ? result : "", tc[i].expected) == 0, "failed to join array");
guard_free(result);
}
@@ -270,7 +268,7 @@ void test_substring_between() {
{.data = "nothing () here", .delim = "()", .expected = ""}, // nothing exists between delimiters
};
for (size_t i = 0; i < sizeof(tc) / sizeof(*tc); i++) {
- char *result = substring_between(tc[i].data, tc[i].delim);
+ char *result = substring_between((char *) tc[i].data, tc[i].delim);
STASIS_ASSERT(strcmp(result ? result : "", tc[i].expected) == 0, "unable to extract substring");
guard_free(result);
}
diff --git a/tests/testing.h b/tests/testing.h
index 15bd208..4c97bf2 100644
--- a/tests/testing.h
+++ b/tests/testing.h
@@ -21,14 +21,21 @@ struct stasis_test_result_t {
} stasis_test_results[STASIS_TEST_RUN_MAX];
size_t stasis_test_results_i = 0;
-void stasis_testing_record_result(struct stasis_test_result_t result);
-
-void stasis_testing_record_result(struct stasis_test_result_t result) {
+extern inline void stasis_testing_setup_workspace();
+extern inline void stasis_testing_clean_up_docker();
+extern inline void stasis_testing_teardown_workspace();
+extern inline void stasis_testing_record_result(struct stasis_test_result_t result);
+extern inline int stasis_testing_has_failed();
+extern inline void stasis_testing_record_result_summary();
+extern inline char *stasis_testing_read_ascii(const char *filename);
+extern inline int stasis_testing_write_ascii(const char *filename, const char *data);
+
+inline void stasis_testing_record_result(struct stasis_test_result_t result) {
memcpy(&stasis_test_results[stasis_test_results_i], &result, sizeof(result));
stasis_test_results_i++;
}
-int stasis_testing_has_failed() {
+inline int stasis_testing_has_failed() {
for (size_t i = 0; i < stasis_test_results_i; i++) {
if (stasis_test_results[i].status == false) {
return 1;
@@ -36,7 +43,8 @@ int stasis_testing_has_failed() {
}
return 0;
}
-void stasis_testing_record_result_summary() {
+
+inline void stasis_testing_record_result_summary() {
size_t failed = 0;
size_t skipped = 0;
size_t passed = 0;
@@ -70,7 +78,7 @@ void stasis_testing_record_result_summary() {
fprintf(stdout, "\n[UNIT] %zu tests passed, %zu tests failed, %zu tests skipped out of %zu\n", passed, failed, skipped, stasis_test_results_i);
}
-char *stasis_testing_read_ascii(const char *filename) {
+inline char *stasis_testing_read_ascii(const char *filename) {
struct stat st;
if (stat(filename, &st)) {
perror(filename);
@@ -96,7 +104,7 @@ char *stasis_testing_read_ascii(const char *filename) {
return result;
}
-int stasis_testing_write_ascii(const char *filename, const char *data) {
+inline int stasis_testing_write_ascii(const char *filename, const char *data) {
FILE *fp;
fp = fopen(filename, "w+");
if (!fp) {
@@ -114,13 +122,85 @@ int stasis_testing_write_ascii(const char *filename, const char *data) {
return 0;
}
+char TEST_DATA_DIR[PATH_MAX] = {0};
+char TEST_START_DIR[PATH_MAX] = {0};
+char TEST_WORKSPACE_DIR[PATH_MAX] = {0};
+inline void stasis_testing_setup_workspace() {
+ if (!realpath("data", TEST_DATA_DIR)) {
+ SYSERROR("%s", "Data directory is missing");
+ exit(1);
+ }
+
+ if (mkdir("workspaces", 0755) < 0) {
+ if (errno != EEXIST) {
+ SYSERROR("%s", "Unable to create workspaces directory");
+ exit(1);
+ }
+ }
+ char ws[] = "workspaces/workspace_XXXXXX";
+ if (mkdtemp(ws) == NULL) {
+ SYSERROR("Unable to create testing workspace: %s", ws);
+ exit(1);
+ }
+ if (!realpath(ws, TEST_WORKSPACE_DIR)) {
+ SYSERROR("%s", "Unable to determine absolute path to temporary workspace");
+ exit(1);
+ }
+ if (chdir(TEST_WORKSPACE_DIR) < 0) {
+ SYSERROR("Unable to enter workspace directory: '%s'", TEST_WORKSPACE_DIR);
+ exit(1);
+ }
+ if (setenv("HOME", TEST_WORKSPACE_DIR, 1) < 0) {
+ SYSERROR("Unable to reset HOME to '%s'", TEST_WORKSPACE_DIR);
+ }
+}
+
+inline void stasis_testing_clean_up_docker() {
+ char containers_dir[PATH_MAX] = {0};
+ snprintf(containers_dir, sizeof(containers_dir) - 1, "%s/.local/share/containers", TEST_WORKSPACE_DIR);
+
+ if (access(containers_dir, F_OK) == 0) {
+ char cmd[PATH_MAX] = {0};
+ snprintf(cmd, sizeof(cmd) - 1, "docker run --rm -it -v %s:/data alpine sh -c '/bin/rm -r -f /data/*' &>/dev/null", containers_dir);
+ // This command will "fail" due to podman's internal protection(s). However, this gets us close enough.
+ system(cmd);
+
+ // Podman seems to defer the rollback operation on-error for a short period.
+ // This buys time, so we can delete it.
+ sleep(1);
+ sync();
+ if (rmtree(containers_dir)) {
+ SYSERROR("WARNING: Unable to fully remove container directory: '%s'", containers_dir);
+ }
+ }
+}
+
+inline void stasis_testing_teardown_workspace() {
+ if (chdir(TEST_START_DIR) < 0) {
+ SYSERROR("Unable to re-enter test start directory from workspace directory: %s", TEST_START_DIR);
+ exit(1);
+ }
+ if (!getenv("KEEP_WORKSPACE")) {
+ if (strlen(TEST_WORKSPACE_DIR) > 1) {
+ stasis_testing_clean_up_docker();
+ rmtree(TEST_WORKSPACE_DIR);
+ }
+ }
+}
+
#define STASIS_TEST_BEGIN_MAIN() do { \
setenv("PYTHONUNBUFFERED", "1", 1); \
fflush(stdout); \
fflush(stderr); \
setvbuf(stdout, NULL, _IONBF, 0); \
setvbuf(stderr, NULL, _IONBF, 0); \
+ if (!getcwd(TEST_START_DIR, sizeof(TEST_START_DIR) - 1)) { \
+ SYSERROR("%s", "Unable to determine current working directory"); \
+ exit(1); \
+ } \
atexit(stasis_testing_record_result_summary); \
+ atexit(stasis_testing_teardown_workspace); \
+ stasis_testing_setup_workspace(); \
} while (0)
#define STASIS_TEST_END_MAIN() do { return stasis_testing_has_failed(); } while (0)