Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor refactoring of testframe.c testing framework #4930

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions c++/test/testhdf5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
PerformTests() -- Perform requested testing
GetTestSummary() -- Retrieve Summary request value
TestSummary() -- Display test summary
GetTestCleanup() -- Retrieve Cleanup request value
TestCleanup() -- Clean up files from testing
GetTestNumErrs() -- Retrieve the number of testing errors

***************************************************************************/
Expand All @@ -57,7 +55,7 @@ main(int argc, char *argv[])
// caused deliberately and expected.
Exception::dontPrint();
/* Initialize testing framework */
TestInit(argv[0], NULL, NULL, 0);
TestInit(argv[0], NULL, NULL, NULL, NULL, 0);

// testing file creation and opening in tfile.cpp
AddTest("tfile", test_file, NULL, cleanup_file, NULL, 0, "File I/O Operations");
Expand Down Expand Up @@ -112,10 +110,6 @@ main(int argc, char *argv[])
if (GetTestSummary())
TestSummary(stdout);

/* Clean up test files, if allowed */
if (GetTestCleanup() && !getenv(HDF5_NOCLEANUP))
TestCleanup();

/* Release test infrastructure */
TestShutdown();

Expand Down
139 changes: 81 additions & 58 deletions test/testframe.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static unsigned TestCount = 0; /* Number of tests currently added to test
static const char *TestProgName = NULL;
static void (*TestPrivateUsage_g)(FILE *stream) = NULL;
static herr_t (*TestPrivateParser_g)(int argc, char *argv[]) = NULL;
static herr_t (*TestCleanupFunc_g)(void) = NULL;

static int TestNumErrs_g = 0; /* Total number of errors that occurred for whole test program */
static bool TestEnableErrorStack = true; /* Whether to show error stacks from the library */
Expand All @@ -65,21 +66,25 @@ AddTest(const char *TestName, void (*TestFunc)(const void *), void (*TestSetupFu
void *new_test_data = NULL;

if (*TestName == '\0') {
fprintf(stderr, "%s: empty string given for test name\n", __func__);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: empty string given for test name\n", __func__);
return FAIL;
}
if (strlen(TestName) >= MAXTESTNAME) {
fprintf(stderr, "%s: test name ('%s') too long, increase MAXTESTNAME(%d).\n", __func__, TestName,
MAXTESTNAME);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: test name ('%s') too long, increase MAXTESTNAME(%d).\n", __func__, TestName,
MAXTESTNAME);
return FAIL;
}
if (strlen(TestDescr) >= MAXTESTDESC) {
fprintf(stderr, "%s: test description ('%s') too long, increase MAXTESTDESC(%d).\n", __func__,
TestDescr, MAXTESTDESC);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: test description ('%s') too long, increase MAXTESTDESC(%d).\n", __func__,
TestDescr, MAXTESTDESC);
return FAIL;
}
if ((TestData && (0 == TestDataSize)) || (!TestData && (0 != TestDataSize))) {
fprintf(stderr, "%s: invalid test data size (%zu)\n", __func__, TestDataSize);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: invalid test data size (%zu)\n", __func__, TestDataSize);
return FAIL;
}

Expand All @@ -89,9 +94,10 @@ AddTest(const char *TestName, void (*TestFunc)(const void *), void (*TestSetupFu
unsigned newAlloc = MAX(1, TestAlloc * 2);

if (NULL == (newTest = realloc(TestArray, newAlloc * sizeof(TestStruct)))) {
fprintf(stderr,
"%s: couldn't reallocate test array, TestCount = %u, TestAlloc = %u, newAlloc = %u\n",
__func__, TestCount, TestAlloc, newAlloc);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr,
"%s: couldn't reallocate test array, TestCount = %u, TestAlloc = %u, newAlloc = %u\n",
__func__, TestCount, TestAlloc, newAlloc);
return FAIL;
}

Expand All @@ -113,7 +119,8 @@ AddTest(const char *TestName, void (*TestFunc)(const void *), void (*TestSetupFu
/* Make a copy of the additional test data given */
if (TestData) {
if (NULL == (new_test_data = malloc(TestDataSize))) {
fprintf(stderr, "%s: couldn't allocate space for additional test data\n", __func__);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: couldn't allocate space for additional test data\n", __func__);
return FAIL;
}

Expand All @@ -136,12 +143,14 @@ AddTest(const char *TestName, void (*TestFunc)(const void *), void (*TestSetupFu
*/
herr_t
TestInit(const char *ProgName, void (*TestPrivateUsage)(FILE *stream),
herr_t (*TestPrivateParser)(int argc, char *argv[]), int TestProcessID)
herr_t (*TestPrivateParser)(int argc, char *argv[]), herr_t (*TestSetupFunc)(void),
herr_t (*TestCleanupFunc)(void), int TestProcessID)
{
/* Turn off automatic error reporting if requested */
if (!TestEnableErrorStack) {
if (H5Eset_auto2(H5E_DEFAULT, NULL, NULL) < 0) {
fprintf(stderr, "%s: can't disable error stack\n", __func__);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: can't disable error stack\n", __func__);
return FAIL;
}
}
Expand All @@ -155,7 +164,9 @@ TestInit(const char *ProgName, void (*TestPrivateUsage)(FILE *stream),
TestPrivateUsage_g = TestPrivateUsage;
if (NULL != TestPrivateParser)
TestPrivateParser_g = TestPrivateParser;
TestCleanupFunc_g = TestCleanupFunc;

/* Set process ID for later use */
TestFrameworkProcessID_g = TestProcessID;

/* Set/reset global variables from h5test that may be used by
Expand All @@ -166,6 +177,13 @@ TestInit(const char *ProgName, void (*TestPrivateUsage)(FILE *stream),
n_tests_failed_g = 0;
n_tests_skipped_g = 0;

/* Call test framework setup callback if provided */
if (TestSetupFunc && TestSetupFunc() < 0) {
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: error occurred in test framework initialization callback\n", __func__);
return FAIL;
}

return SUCCEED;
}

Expand Down Expand Up @@ -337,21 +355,24 @@ TestParseCmdLine(int argc, char *argv[])
errno = 0;
max_threads = strtol(*argv, NULL, 10);
if (errno != 0) {
fprintf(stderr,
"error while parsing value (%s) specified for maximum number of threads\n",
*argv);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr,
"error while parsing value (%s) specified for maximum number of threads\n",
*argv);
ret_value = FAIL;
goto done;
}
if (max_threads <= 0) {
fprintf(stderr, "invalid value (%ld) specified for maximum number of threads\n",
max_threads);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "invalid value (%ld) specified for maximum number of threads\n",
max_threads);
ret_value = FAIL;
goto done;
}
else if (max_threads > (long)INT_MAX) {
fprintf(stderr, "value (%ld) specified for maximum number of threads too large\n",
max_threads);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "value (%ld) specified for maximum number of threads too large\n",
max_threads);
ret_value = FAIL;
goto done;
}
Expand Down Expand Up @@ -387,24 +408,23 @@ TestParseCmdLine(int argc, char *argv[])
/*
* Execute all tests that aren't being skipped
*/
void
herr_t
PerformTests(void)
{
for (unsigned Loop = 0; Loop < TestCount; Loop++) {
int old_num_errs = TestNumErrs_g;

if (TestArray[Loop].TestSkipFlag) {
if (TestFrameworkProcessID_g == 0)
MESSAGE(2, ("Skipping -- %s (%s) \n", TestArray[Loop].Description, TestArray[Loop].Name));
MESSAGE(2, ("Skipping -- %s (%s) \n", TestArray[Loop].Description, TestArray[Loop].Name));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MESSAGE macro includes the check for TestFrameworkProcessID_g of 0

continue;
}

if (TestFrameworkProcessID_g == 0) {
MESSAGE(2, ("Testing -- %s (%s) \n", TestArray[Loop].Description, TestArray[Loop].Name));
MESSAGE(5, ("===============================================\n"));
}
MESSAGE(2, ("Testing -- %s (%s) \n", TestArray[Loop].Description, TestArray[Loop].Name));
MESSAGE(5, ("===============================================\n"));

TestAlarmOn();
if (TestAlarmOn() < 0)
MESSAGE(5, ("Couldn't enable test alarm timer for test -- %s (%s) \n",
TestArray[Loop].Description, TestArray[Loop].Name));

if (TestArray[Loop].TestSetupFunc)
TestArray[Loop].TestSetupFunc(TestArray[Loop].TestParameters);
Expand All @@ -418,19 +438,17 @@ PerformTests(void)

TestArray[Loop].TestNumErrors = TestNumErrs_g - old_num_errs;

if (TestFrameworkProcessID_g == 0) {
MESSAGE(5, ("===============================================\n"));
MESSAGE(5, ("There were %d errors detected.\n\n", TestArray[Loop].TestNumErrors));
}
MESSAGE(5, ("===============================================\n"));
MESSAGE(5, ("There were %d errors detected.\n\n", TestArray[Loop].TestNumErrors));
}

if (TestFrameworkProcessID_g == 0) {
MESSAGE(2, ("\n\n"));
if (TestNumErrs_g)
MESSAGE(VERBO_NONE, ("!!! %d Error(s) were detected !!!\n\n", TestNumErrs_g));
else
MESSAGE(VERBO_NONE, ("All tests were successful. \n\n"));
}
MESSAGE(2, ("\n\n"));
if (TestNumErrs_g)
MESSAGE(VERBO_NONE, ("!!! %d Error(s) were detected !!!\n\n", TestNumErrs_g));
else
MESSAGE(VERBO_NONE, ("All tests were successful. \n\n"));

return SUCCEED;
}

/*
Expand Down Expand Up @@ -497,31 +515,26 @@ TestSummary(FILE *stream)
fprintf(stream, "\n\n");
}

/*
* Perform test cleanup
*/
void
TestCleanup(void)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestCleanup() was only used in a few places and is covered entirely by PerformTests() now

{
if (TestFrameworkProcessID_g == 0)
MESSAGE(2, ("\nCleaning Up temp files...\n\n"));

for (unsigned Loop = 0; Loop < TestCount; Loop++)
if (!TestArray[Loop].TestSkipFlag && TestArray[Loop].TestCleanupFunc != NULL)
TestArray[Loop].TestCleanupFunc(TestArray[Loop].TestParameters);
}

/*
* Shutdown the test infrastructure
*/
void
herr_t
TestShutdown(void)
{
/* Clean up test state first before tearing down testing framework */
if (TestCleanupFunc_g && TestCleanupFunc_g() < 0) {
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: error occurred in test framework initialization callback\n", __func__);
return FAIL;
}

if (TestArray)
for (unsigned Loop = 0; Loop < TestCount; Loop++)
free(TestArray[Loop].TestParameters);

free(TestArray);

return SUCCEED;
}

/*
Expand Down Expand Up @@ -585,6 +598,12 @@ GetTestSummary(void)
H5_ATTR_PURE bool
GetTestCleanup(void)
{
/* Don't cleanup files if the HDF5_NOCLEANUP environment
* variable is defined to anything
*/
if (getenv(HDF5_NOCLEANUP))
SetTestNoCleanup();

return TestDoCleanUp_g;
}

Expand Down Expand Up @@ -615,8 +634,9 @@ ParseTestVerbosity(char *argv)
errno = 0;
verb_level = strtol(argv, NULL, 10);
if (errno != 0) {
fprintf(stderr, "%s: error while parsing value (%s) specified for test verbosity\n", __func__,
argv);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: error while parsing value (%s) specified for test verbosity\n", __func__,
argv);
return FAIL;
}

Expand Down Expand Up @@ -770,12 +790,15 @@ TestAlarmOn(void)
errno = 0;
alarm_sec = strtoul(env_val, NULL, 10);
if (errno != 0) {
fprintf(stderr, "%s: error while parsing value (%s) specified for alarm timeout\n", __func__,
env_val);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: error while parsing value (%s) specified for alarm timeout\n", __func__,
env_val);
return FAIL;
}
else if (alarm_sec > (unsigned long)UINT_MAX) {
fprintf(stderr, "%s: value (%lu) specified for alarm timeout too large\n", __func__, alarm_sec);
if (TestFrameworkProcessID_g == 0)
fprintf(stderr, "%s: value (%lu) specified for alarm timeout too large\n", __func__,
alarm_sec);
return FAIL;
}
}
Expand Down
Loading
Loading