diff options
author | Joseph Hunkeler <jhunkeler@users.noreply.github.com> | 2024-08-12 15:11:17 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-12 15:11:17 -0400 |
commit | 95672b2e7a6cc0c07306893d5bb0b80ee3570f7a (patch) | |
tree | 7167084154e521b1c82945d7e0405dbe524074ad | |
parent | dd2768ddcd61172cc58311fa51138281144397ae (diff) | |
download | stasis-95672b2e7a6cc0c07306893d5bb0b80ee3570f7a.tar.gz |
More unit tests (and fixing bugs) (#23)
* Add test_artifactory.c to suite
* Add test_ini_getval_wrapper to ini.c
* basic ini_getval_TYPE() conversion checks
* bugfix: use strtof in INIVAL_TYPE_FLOAT case
* Include stdio.h to pull in FILE structure
* bugfix: free data at index during strlist_set operation
* Previous behavior of setting the pointer to NULL introduced a subtle memory leak
* Set strlist error when index it out of range
* Import private delivery functions required for mock context creation
* Remove static declaration
* populate_delivery_cfg()
* Add test_junitxml.c
* Fix duplicate define value for JUNIT_RESULT_STATE_ERROR
* Add static junit test data
* Copy test data to current test directory
-rw-r--r-- | include/ini.h | 1 | ||||
-rw-r--r-- | include/junitxml.h | 2 | ||||
-rw-r--r-- | src/delivery.c | 2 | ||||
-rw-r--r-- | src/ini.c | 3 | ||||
-rw-r--r-- | src/strlist.c | 3 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/data/result.xml | 10 | ||||
-rw-r--r-- | tests/data/result_error.xml | 24 | ||||
-rw-r--r-- | tests/test_artifactory.c | 129 | ||||
-rw-r--r-- | tests/test_ini.c | 99 | ||||
-rw-r--r-- | tests/test_junitxml.c | 82 |
11 files changed, 352 insertions, 5 deletions
diff --git a/include/ini.h b/include/ini.h index 2992a37..3d0565b 100644 --- a/include/ini.h +++ b/include/ini.h @@ -2,6 +2,7 @@ #ifndef STASIS_INI_H #define STASIS_INI_H +#include <stdio.h> #include <stddef.h> #include <stdbool.h> diff --git a/include/junitxml.h b/include/junitxml.h index 504b8e4..777ee27 100644 --- a/include/junitxml.h +++ b/include/junitxml.h @@ -6,7 +6,7 @@ #define JUNIT_RESULT_STATE_NONE 0 #define JUNIT_RESULT_STATE_FAILURE 1 #define JUNIT_RESULT_STATE_SKIPPED 2 -#define JUNIT_RESULT_STATE_ERROR 2 +#define JUNIT_RESULT_STATE_ERROR 3 /** * Represents a failed test case diff --git a/src/delivery.c b/src/delivery.c index eaa2b06..2b5e781 100644 --- a/src/delivery.c +++ b/src/delivery.c @@ -607,7 +607,7 @@ static int populate_delivery_ini(struct Delivery *ctx, int render_mode) { return 0; } -static int populate_delivery_cfg(struct Delivery *ctx, int render_mode) { +int populate_delivery_cfg(struct Delivery *ctx, int render_mode) { struct INIFILE *cfg = ctx->_stasis_ini_fp.cfg; if (!cfg) { return -1; @@ -170,7 +170,7 @@ int ini_getval(struct INIFILE *ini, char *section_name, char *key, int type, int result->as_double = (double) strtod(data_copy, NULL); break; case INIVAL_TYPE_FLOAT: - result->as_float = (float) strtod(data_copy, NULL); + result->as_float = strtof(data_copy, NULL); break; case INIVAL_TYPE_STR: result->as_char_p = strdup(data_copy); @@ -638,7 +638,6 @@ struct INIFILE *ini_open(const char *filename) { } if (isempty(value)) { //printf("%s is probably long raw data\n", key); - //ini_data_set_hint(&ini, current_section, key, INIVAL_TYPE_STR_ARRAY); hint = INIVAL_TYPE_STR_ARRAY; multiline_data = 1; no_data = 1; diff --git a/src/strlist.c b/src/strlist.c index d1bb926..de76744 100644 --- a/src/strlist.c +++ b/src/strlist.c @@ -315,11 +315,12 @@ size_t strlist_count(struct StrList *pStrList) { void strlist_set(struct StrList **pStrList, size_t index, char *value) { char *tmp = NULL; if (*pStrList == NULL || index > strlist_count(*pStrList)) { + strlist_errno = STRLIST_E_OUT_OF_RANGE; return; } if (value == NULL) { - (*pStrList)->data[index] = NULL; + guard_free((*pStrList)->data[index]); } else { tmp = realloc((*pStrList)->data[index], (strlen(value) + 1) * sizeof(char *)); if (!tmp) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f06638e..62f58a9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,6 +10,8 @@ set(nix_clang_cflags -Wno-unused-parameter -Wno-incompatible-pointer-types-disca 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 files "test_*.c") if (BASH_PROGRAM) diff --git a/tests/data/result.xml b/tests/data/result.xml new file mode 100644 index 0000000..81df70f --- /dev/null +++ b/tests/data/result.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="2" skipped="1" tests="4" time="0.022" timestamp="2024-08-12T13:52:02.624944-04:00" hostname="examplehost"><testcase classname="test_simple" name="test_skip" time="0.000"><skipped type="pytest.skip" message="unconditional skip">/example/test_simple.py:4: unconditional skip</skipped></testcase><testcase classname="test_simple" name="test_fail" time="0.000"><failure message="assert False">def test_fail(): + print("oh no, this test failed.", file=sys.stderr) +> assert False +E assert False + +test_simple.py:10: AssertionError</failure></testcase><testcase classname="test_simple" name="test_success" time="0.000" /><testcase classname="test_simple" name="test_error" time="0.000"><failure message="RuntimeError: uh oh, a runtime error">def test_error(): +> raise RuntimeError("uh oh, a runtime error") +E RuntimeError: uh oh, a runtime error + +test_simple.py:17: RuntimeError</failure></testcase></testsuite></testsuites> diff --git a/tests/data/result_error.xml b/tests/data/result_error.xml new file mode 100644 index 0000000..cbb7a86 --- /dev/null +++ b/tests/data/result_error.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="1" failures="0" skipped="0" tests="1" time="0.077" timestamp="2024-08-12T13:58:07.030762-04:00" hostname="examplehost"><testcase classname="" name="test_simple" time="0.000"><error message="collection failure">/example/miniforge3/envs/test/lib/python3.11/site-packages/_pytest/python.py:493: in importtestmodule + mod = import_path( +/example/miniforge3/envs/test/lib/python3.11/site-packages/_pytest/pathlib.py:582: in import_path + importlib.import_module(module_name) +/example/miniforge3/envs/test/lib/python3.11/importlib/__init__.py:126: in import_module + return _bootstrap._gcd_import(name[level:], package, level) +<frozen importlib._bootstrap>:1204: in _gcd_import + ??? +<frozen importlib._bootstrap>:1176: in _find_and_load + ??? +<frozen importlib._bootstrap>:1147: in _find_and_load_unlocked + ??? +<frozen importlib._bootstrap>:690: in _load_unlocked + ??? +/example/miniforge3/envs/test/lib/python3.11/site-packages/_pytest/assertion/rewrite.py:165: in exec_module + source_stat, co = _rewrite_test(fn, self.config) +/example/miniforge3/envs/test/lib/python3.11/site-packages/_pytest/assertion/rewrite.py:345: in _rewrite_test + tree = ast.parse(source, filename=strfn) +/example/miniforge3/envs/test/lib/python3.11/ast.py:50: in parse + return compile(source, filename, mode, flags, +E File "/tmp/bleh/test_simple.py", line 17 +E syntax error here +E ^^^^^ +E SyntaxError: invalid syntax</error></testcase></testsuite></testsuites> diff --git a/tests/test_artifactory.c b/tests/test_artifactory.c new file mode 100644 index 0000000..1a21f0e --- /dev/null +++ b/tests/test_artifactory.c @@ -0,0 +1,129 @@ +#include "testing.h" + +// Import private functions from core +extern int delivery_init_platform(struct Delivery *ctx); +extern int populate_delivery_cfg(struct Delivery *ctx, int render_mode); + +struct JFRT_Auth gauth; +struct JFRT_Auth gnoauth; +struct Delivery ctx; +const char *gbuild_name = "test_stasis_jf_build_collect_env"; +const char *gbuild_num = "1"; + +// Delete a build +// For now, I'm keeping these out of the core library. +static int jfrog_cli_rt_build_delete(struct JFRT_Auth *auth, char *build_name, char *build_num) { + char cmd[STASIS_BUFSIZ]; + memset(cmd, 0, sizeof(cmd)); + snprintf(cmd, sizeof(cmd) - 1, "--build \"%s/%s\"", build_name, build_num); + return jfrog_cli(auth, "rt", "delete", cmd); +} + +static int jfrog_cli_rt_delete(struct JFRT_Auth *auth, char *pattern) { + char cmd[STASIS_BUFSIZ]; + memset(cmd, 0, sizeof(cmd)); + snprintf(cmd, sizeof(cmd) - 1, "\"%s\"", pattern); + return jfrog_cli(auth, "rt", "delete", cmd); +} + +void test_jfrog_cli_rt_ping() { + STASIS_ASSERT_FATAL(jfrog_cli_rt_ping(&gauth) == 0, "server ping failed."); + STASIS_ASSERT(jfrog_cli_rt_ping(&gnoauth) != 0, "server ping should have failed; auth context is empty."); +} + +void test_jfrog_cli_rt_build_collect_publish() { + struct JFRT_Upload upload; + jfrt_upload_init(&upload); + + char *filename = "empty_file.txt"; + touch(filename); + upload.build_name = gbuild_name; + upload.build_number = gbuild_num; + STASIS_ASSERT(jfrog_cli_rt_upload(&gauth, &upload, filename, getenv("STASIS_JF_REPO")) == 0, "jf upload failed"); + STASIS_ASSERT(jfrog_cli_rt_build_collect_env(&gauth, gbuild_name, gbuild_num) == 0, "jf environment collection failed"); + STASIS_ASSERT(jfrog_cli_rt_build_publish(&gauth, gbuild_name, gbuild_num) == 0, "jf publish build failed"); + STASIS_ASSERT(jfrog_cli_rt_build_delete(&gauth, gbuild_name, gbuild_num) == 0, "jf delete build failed"); +} + +void test_jfrog_cli_rt_upload() { + struct JFRT_Upload upload; + jfrt_upload_init(&upload); + + char *filename = "empty_file_upload.txt"; + touch(filename); + STASIS_ASSERT(jfrog_cli_rt_upload(&gauth, &upload, filename, getenv("STASIS_JF_REPO")) == 0, "jf upload failed"); +} + +void test_jfrog_cli_rt_download() { + struct JFRT_Download dl; + memset(&dl, 0, sizeof(dl)); + + char *filename = "empty_file_upload.txt"; + char path[PATH_MAX] = {0}; + sprintf(path, "%s/%s", getenv("STASIS_JF_REPO"), filename); + STASIS_ASSERT(jfrog_cli_rt_download(&gauth, &dl, filename, ".") == 0, "jf download failed"); + STASIS_ASSERT(jfrog_cli_rt_delete(&gauth, path) == 0, "jf delete test artifact failed"); +} + +int main(int argc, char *argv[]) { + STASIS_TEST_BEGIN_MAIN(); + memset(&gauth, 0, sizeof(gauth)); + memset(&gnoauth, 0, sizeof(gnoauth)); + memset(&ctx, 0, sizeof(ctx)); + + const char *basedir = realpath(".", NULL); + const char *ws = "workspace"; + mkdir(ws, 0755); + if (pushd(ws)) { + SYSERROR("failed to change directory to %s", ws); + STASIS_ASSERT_FATAL(true, "workspace creation failed"); + } + + // enable messages from the jf tool + globals.verbose = true; + + // create a limited delivery context + path_store(&ctx.storage.tools_dir, PATH_MAX, ".", "tools"); + path_store(&ctx.storage.build_dir, PATH_MAX, ".", "build"); + path_store(&ctx.storage.tmpdir, PATH_MAX, ".", "tmp"); + const char *sysconfdir = getenv("STASIS_SYSCONFDIR"); + if (!sysconfdir) { + sysconfdir = STASIS_SYSCONFDIR; + } + + char path[PATH_MAX] = {0}; + sprintf(path, "%s/bin:%s", ctx.storage.tools_dir, getenv("PATH")); + setenv("PATH", path, 1); + + // The default config contains the URL information to download jfrog-cli + char cfg_path[PATH_MAX] = {0}; + if (strstr(sysconfdir, "..")) { + sprintf(cfg_path, "%s/%s/stasis.ini", basedir, sysconfdir); + } else { + sprintf(cfg_path, "%s/stasis.ini", sysconfdir); + } + ctx._stasis_ini_fp.cfg = ini_open(cfg_path); + if (!ctx._stasis_ini_fp.cfg) { + SYSERROR("%s: configuration is invalid", cfg_path); + return STASIS_TEST_SUITE_SKIP; + } + delivery_init_platform(&ctx); + populate_delivery_cfg(&ctx, INI_READ_RENDER); + delivery_init_artifactory(&ctx); + + // Skip this suite if we're not configured to use it + if (jfrt_auth_init(&gauth)) { + SYSERROR("%s", "Not configured to test Artifactory. Skipping."); + return STASIS_TEST_SUITE_SKIP; + } + + STASIS_TEST_FUNC *tests[] = { + test_jfrog_cli_rt_ping, + test_jfrog_cli_rt_build_collect_publish, + test_jfrog_cli_rt_upload, + test_jfrog_cli_rt_download, + }; + STASIS_TEST_RUN(tests); + popd(); + STASIS_TEST_END_MAIN(); +}
\ No newline at end of file diff --git a/tests/test_ini.c b/tests/test_ini.c index 7fb13a0..2579e21 100644 --- a/tests/test_ini.c +++ b/tests/test_ini.c @@ -95,6 +95,104 @@ void test_ini_setval_getval() { remove(filename); } +void test_ini_getval_wrappers() { + int render_mode = INI_READ_RENDER; + const char *filename = "ini_open.ini"; + const char *data = "[default]\n" + "char_01a=-1\n" + "char_01b=127\n" + "uchar_01a=0\n" + "uchar_01b=255\n" + "short_01a=-1\n" + "short_01b=1\n" + "ushort_01a=0\n" + "ushort_01b=1\n" + "int_01a=-1\n" + "int_01b=1\n" + "uint_01a=0\n" + "uint_01b=1\n" + "long_01a=-1\n" + "long_01b=1\n" + "ulong_01a=0\n" + "ulong_01b=1\n" + "llong_01a=-1\n" + "llong_01b=1\n" + "ullong_01a=0\n" + "ullong_01b=1\n" + "float_01a=-1.5\n" + "float_01b=1.5\n" + "double_01a=-1.5\n" + "double_01b=1.5\n"; + struct INIFILE *ini = NULL; + int err = 0; + + stasis_testing_write_ascii(filename, data); + ini = ini_open(filename); + STASIS_ASSERT_FATAL(ini != NULL, "could not open test data"); + + STASIS_ASSERT(ini_getval_char(ini, "default", "char_01a", render_mode, &err) == -1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: char"); + STASIS_ASSERT(ini_getval_char(ini, "default", "char_01b", render_mode, &err) == 127, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: char"); + + STASIS_ASSERT(ini_getval_uchar(ini, "default", "uchar_01a", render_mode, &err) == 0, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: uchar"); + STASIS_ASSERT(ini_getval_uchar(ini, "default", "uchar_01b", render_mode, &err) == 255, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: uchar"); + + STASIS_ASSERT(ini_getval_short(ini, "default", "short_01a", render_mode, &err) == -1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: short"); + STASIS_ASSERT(ini_getval_short(ini, "default", "short_01b", render_mode, &err) == 1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: short"); + + STASIS_ASSERT(ini_getval_ushort(ini, "default", "ushort_01a", render_mode, &err) == 0, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: ushort"); + STASIS_ASSERT(ini_getval_ushort(ini, "default", "ushort_01b", render_mode, &err) == 1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: ushort"); + + STASIS_ASSERT(ini_getval_int(ini, "default", "int_01a", render_mode, &err) == -1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: int"); + STASIS_ASSERT(ini_getval_int(ini, "default", "int_01b", render_mode, &err) == 1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: int"); + + STASIS_ASSERT(ini_getval_uint(ini, "default", "uint_01a", render_mode, &err) == 0, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: uint"); + STASIS_ASSERT(ini_getval_uint(ini, "default", "uint_01b", render_mode, &err) == 1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: uint"); + + STASIS_ASSERT(ini_getval_long(ini, "default", "long_01a", render_mode, &err) == -1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: long"); + STASIS_ASSERT(ini_getval_long(ini, "default", "long_01b", render_mode, &err) == 1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: long"); + + STASIS_ASSERT(ini_getval_ulong(ini, "default", "ulong_01a", render_mode, &err) == 0, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: ulong"); + STASIS_ASSERT(ini_getval_ulong(ini, "default", "ulong_01b", render_mode, &err) == 1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: ulong"); + + STASIS_ASSERT(ini_getval_llong(ini, "default", "llong_01a", render_mode, &err) == -1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: llong"); + STASIS_ASSERT(ini_getval_llong(ini, "default", "llong_01b", render_mode, &err) == 1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: llong"); + + STASIS_ASSERT(ini_getval_ullong(ini, "default", "ullong_01a", render_mode, &err) == 0, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: ullong"); + STASIS_ASSERT(ini_getval_ullong(ini, "default", "ullong_01b", render_mode, &err) == 1, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: ullong"); + + STASIS_ASSERT(ini_getval_float(ini, "default", "float_01a", render_mode, &err) == -1.5F, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: float"); + STASIS_ASSERT(ini_getval_float(ini, "default", "float_01b", render_mode, &err) == 1.5F, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: float"); + + STASIS_ASSERT(ini_getval_double(ini, "default", "double_01a", render_mode, &err) == -1.5L, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: double"); + STASIS_ASSERT(ini_getval_double(ini, "default", "double_01b", render_mode, &err) == 1.5L, "returned unexpected value"); + STASIS_ASSERT(err == 0, "failed to convert type: double"); + + ini_free(&ini); +} + int main(int argc, char *argv[]) { STASIS_TEST_BEGIN_MAIN(); STASIS_TEST_FUNC *tests[] = { @@ -103,6 +201,7 @@ int main(int argc, char *argv[]) { test_ini_section_search, test_ini_has_key, test_ini_setval_getval, + test_ini_getval_wrappers, }; STASIS_TEST_RUN(tests); STASIS_TEST_END_MAIN(); diff --git a/tests/test_junitxml.c b/tests/test_junitxml.c new file mode 100644 index 0000000..9b2181e --- /dev/null +++ b/tests/test_junitxml.c @@ -0,0 +1,82 @@ +#include "testing.h" + +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(testsuite->name != NULL, "Test suite must be named"); + STASIS_ASSERT(testsuite->skipped > 0, "missed skipped tests"); + STASIS_ASSERT(testsuite->failures > 0, "missed failed tests"); + STASIS_ASSERT(testsuite->errors == 0, "should not have errored tests"); + STASIS_ASSERT(testsuite->tests > 0, "missed tests"); + + for (size_t i = 0; i < testsuite->_tc_inuse; i++) { + struct JUNIT_Testcase *testcase = testsuite->testcase[i]; + STASIS_ASSERT_FATAL(testcase->name != NULL, "test case should not be NULL"); + STASIS_ASSERT(testcase->name != NULL, "name should not be NULL"); + STASIS_ASSERT(testcase->classname != NULL, "classname should not be NULL"); + + switch (testcase->tc_result_state_type) { + case JUNIT_RESULT_STATE_SKIPPED: + STASIS_ASSERT(testcase->result_state.skipped != NULL, "skipped state set, but data pointer was null"); + STASIS_ASSERT(testcase->result_state.skipped->message != NULL, "data pointer set, but message pointer was null"); + break; + case JUNIT_RESULT_STATE_FAILURE: + STASIS_ASSERT(testcase->result_state.failure != NULL, "failure state set, but data pointer was null"); + STASIS_ASSERT(testcase->result_state.failure->message != NULL, "data pointer set, but message pointer was null"); + break; + case JUNIT_RESULT_STATE_ERROR: + STASIS_ASSERT(testcase->result_state.error != NULL, "error state set, but data pointer was null"); + STASIS_ASSERT(testcase->result_state.error->message != NULL, "data pointer set, but message pointer was null"); + break; + case JUNIT_RESULT_STATE_NONE: + STASIS_ASSERT(testcase->result_state.failure == NULL, "success, but has an failure record"); + STASIS_ASSERT(testcase->result_state.skipped == NULL, "success, but has a skipped record "); + STASIS_ASSERT(testcase->result_state.error == NULL, "success, but has an error record"); + break; + default: + SYSERROR("unknown test case result type (%d)", testcase->tc_result_state_type); + break; + } + } + junitxml_testsuite_free(&testsuite); +} + +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(testsuite->name != NULL, "test suite must be named"); + STASIS_ASSERT(testsuite->skipped == 0, "should not have any skipped tests"); + STASIS_ASSERT(testsuite->failures == 0, "should not have any failures, only errors"); + STASIS_ASSERT(testsuite->errors > 0, "missed failed tests"); + STASIS_ASSERT(testsuite->tests > 0, "missed tests"); + STASIS_ASSERT(testsuite->timestamp != NULL, "Test suite must have a timestamp"); + + for (size_t i = 0; i < testsuite->_tc_inuse; i++) { + struct JUNIT_Testcase *testcase = testsuite->testcase[i]; + STASIS_ASSERT_FATAL(testcase->name != NULL, "test case should not be NULL"); + STASIS_ASSERT(testcase->name != NULL, "name should not be NULL"); + STASIS_ASSERT(testcase->classname != NULL, "classname should not be NULL"); + + switch (testcase->tc_result_state_type) { + case JUNIT_RESULT_STATE_ERROR: + STASIS_ASSERT(testcase->result_state.error != NULL, "error state set, but data pointer was null"); + STASIS_ASSERT(testcase->result_state.error->message != NULL, "data pointer set, but message pointer was null"); + break; + default: + SYSERROR("unexpected test case result type (%d)", testcase->tc_result_state_type); + break; + } + } + junitxml_testsuite_free(&testsuite); +} + +int main(int argc, char *argv[]) { + STASIS_TEST_BEGIN_MAIN(); + STASIS_TEST_FUNC *tests[] = { + test_junitxml_testsuite_read, + test_junitxml_testsuite_read_error, + }; + STASIS_TEST_RUN(tests); + STASIS_TEST_END_MAIN(); +}
\ No newline at end of file |