1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-10-30 23:37:45 +02:00

C test harness refactor.

Consolidate setting configuration into hrnInit() and rename other functions for consistency.

Split out internal functions into a new header.
This commit is contained in:
David Steele
2019-10-16 15:48:33 +02:00
parent b4aeb217e6
commit 48bd9e22f1
5 changed files with 209 additions and 299 deletions

View File

@@ -413,7 +413,7 @@ sub run
$strTestInit .=
(defined($strTestInit) ? "\n " : '') .
sprintf("testAdd(%3d, %8s);" , $iTestIdx, ($bSelected ? 'true' : 'false'));
sprintf("hrnAdd(%3d, %8s);" , $iTestIdx, ($bSelected ? 'true' : 'false'));
}
$strTestC =~ s/\{\[C\_TEST\_LIST\]\}/$strTestInit/g;

View File

@@ -30,7 +30,12 @@ static bool testFirst = true;
static uint64_t timeMSecBegin;
static const char *testExeData = NULL;
static const char *testProjectExeData = NULL;
static bool testContainerData = false;
static unsigned int testIdxData = 0;
static uint64_t testScaleData = 1;
static const char *testPathData = NULL;
static const char *testDataPathData = NULL;
static const char *testRepoPathData = NULL;
static char testUserData[64];
@@ -44,268 +49,26 @@ Extern functions
void harnessLogFinal(void);
#endif
/***********************************************************************************************************************************
Is this test running in a container? i.e., can we use sudo and system paths with impunity?
***********************************************************************************************************************************/
static bool testContainerData = false;
bool
testContainer(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(BOOL, testContainerData);
}
void
testContainerSet(bool testContainer)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(BOOL, testContainer);
FUNCTION_HARNESS_END();
testContainerData = testContainer;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get and set the test exe
***********************************************************************************************************************************/
const char *
testExe(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testExeData);
}
void
testExeSet(const char *testExe)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, testExe);
FUNCTION_HARNESS_ASSERT(testExe != NULL);
FUNCTION_HARNESS_END();
testExeData = testExe;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get and set the project exe
***********************************************************************************************************************************/
static const char *testProjectExeData = NULL;
const char *
testProjectExe(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testProjectExeData);
}
void
testProjectExeSet(const char *testProjectExe)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, testProjectExe);
FUNCTION_HARNESS_END();
testProjectExeData = testProjectExe;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get and set the path for the pgbackrest repo
***********************************************************************************************************************************/
const char *
testRepoPath(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testRepoPathData);
}
void
testRepoPathSet(const char *testRepoPath)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, testRepoPath);
FUNCTION_HARNESS_ASSERT(testRepoPath != NULL);
FUNCTION_HARNESS_END();
testRepoPathData = testRepoPath;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get and set the test path, i.e., the path where this test should write its files
***********************************************************************************************************************************/
const char *
testPath(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testPathData);
}
void
testPathSet(const char *testPath)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, testPath);
FUNCTION_HARNESS_ASSERT(testPath != NULL);
FUNCTION_HARNESS_END();
testPathData = testPath;
FUNCTION_HARNESS_RESULT_VOID();
}
/**********************************************************************************************************************************/
static const char *testDataPathData = NULL;
const char *
testDataPath(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testDataPathData);
}
void
testDataPathSet(const char *testDataPath)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(STRINGZ, testDataPath);
FUNCTION_HARNESS_END();
testDataPathData = testDataPath;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get and set test index
***********************************************************************************************************************************/
static unsigned int testIdxData = 0;
unsigned int
testIdx(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(UINT, testIdxData);
}
void
testIdxSet(unsigned int testIdx)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(UINT, testIdx);
FUNCTION_HARNESS_END();
testIdxData = testIdx;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get and set scale for performance testing
***********************************************************************************************************************************/
static uint64_t testScaleData = 1;
uint64_t
testScale(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(UINT64, testScaleData);
}
void
testScaleSet(uint64_t testScale)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(UINT64, testScale);
FUNCTION_HARNESS_END();
testScaleData = testScale;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Get test user/group
***********************************************************************************************************************************/
const char *
testUser(void)
{
return testUserData;
}
const char *
testGroup(void)
{
return testGroupData;
}
/***********************************************************************************************************************************
Get the time in milliseconds
***********************************************************************************************************************************/
uint64_t
testTimeMSec(void)
{
FUNCTION_HARNESS_VOID();
struct timeval currentTime;
gettimeofday(&currentTime, NULL);
FUNCTION_HARNESS_RESULT(UINT64, ((uint64_t)currentTime.tv_sec * 1000) + (uint64_t)currentTime.tv_usec / 1000);
}
/***********************************************************************************************************************************
Get time at beginning of current run
***********************************************************************************************************************************/
uint64_t
testTimeMSecBegin(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(UINT64, timeMSecBegin);
}
/***********************************************************************************************************************************
testAdd - add a new test
***********************************************************************************************************************************/
void
testAdd(int run, bool selected)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(INT, run);
FUNCTION_HARNESS_PARAM(BOOL, selected);
FUNCTION_HARNESS_END();
if (run != testTotal + 1)
{
fprintf(stderr, "ERROR: test run %d is not in order\n", run);
fflush(stderr);
exit(255);
}
testList[testTotal].selected = selected;
testTotal++;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
Initialize harness
***********************************************************************************************************************************/
void
testInit(void)
hrnInit(
const char *testExe, const char *testProjectExe, bool testContainer, unsigned int testIdx, uint64_t testScale,
const char *testPath, const char *testDataPath, const char *testRepoPath)
{
FUNCTION_HARNESS_VOID();
// Set test configuration
testExeData = testExe;
testProjectExeData = testProjectExe;
testContainerData = testContainer;
testIdxData = testIdx;
testScaleData = testScale;
testPathData = testPath;
testDataPathData = testDataPath;
testRepoPathData = testRepoPath;
// Set test user
const char *testUserTemp = getpwuid(getuid())->pw_name;
@@ -333,6 +96,30 @@ testInit(void)
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
testAdd - add a new test
***********************************************************************************************************************************/
void
hrnAdd(int run, bool selected)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(INT, run);
FUNCTION_HARNESS_PARAM(BOOL, selected);
FUNCTION_HARNESS_END();
if (run != testTotal + 1)
{
fprintf(stderr, "ERROR: test run %d is not in order\n", run);
fflush(stderr);
exit(255);
}
testList[testTotal].selected = selected;
testTotal++;
FUNCTION_HARNESS_RESULT_VOID();
}
/***********************************************************************************************************************************
testBegin - should this test run?
***********************************************************************************************************************************/
@@ -404,7 +191,7 @@ testBegin(const char *name)
testComplete - make sure all expected tests ran
***********************************************************************************************************************************/
void
testComplete(void)
hrnComplete(void)
{
FUNCTION_HARNESS_VOID();
@@ -582,3 +369,104 @@ hrnDiff(const char *actual, const char *expected)
FUNCTION_HARNESS_RESULT(STRINGZ, harnessDiffBuffer);
}
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
const char *
testExe(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testExeData);
}
/**********************************************************************************************************************************/
const char *
testProjectExe(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testProjectExeData);
}
/**********************************************************************************************************************************/
bool
testContainer(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(BOOL, testContainerData);
}
/**********************************************************************************************************************************/
unsigned int
testIdx(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(UINT, testIdxData);
}
/**********************************************************************************************************************************/
uint64_t
testScale(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(UINT64, testScaleData);
}
/**********************************************************************************************************************************/
const char *
testPath(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testPathData);
}
/**********************************************************************************************************************************/
const char *
testDataPath(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testDataPathData);
}
/**********************************************************************************************************************************/
const char *
testRepoPath(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(STRINGZ, testRepoPathData);
}
/**********************************************************************************************************************************/
const char *
testUser(void)
{
return testUserData;
}
/**********************************************************************************************************************************/
const char *
testGroup(void)
{
return testGroupData;
}
/**********************************************************************************************************************************/
uint64_t
testTimeMSec(void)
{
FUNCTION_HARNESS_VOID();
struct timeval currentTime;
gettimeofday(&currentTime, NULL);
FUNCTION_HARNESS_RESULT(UINT64, ((uint64_t)currentTime.tv_sec * 1000) + (uint64_t)currentTime.tv_usec / 1000);
}
/**********************************************************************************************************************************/
uint64_t
testTimeMSecBegin(void)
{
FUNCTION_HARNESS_VOID();
FUNCTION_HARNESS_RESULT(UINT64, timeMSecBegin);
}

View File

@@ -17,22 +17,51 @@ Constants
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void testAdd(int run, bool selected);
// Begin a test if this function returns true, otherwise the user has skipped it
bool testBegin(const char *name);
void testComplete(void);
// Read a file (max 256k) into a buffer
void hrnFileRead(const char *fileName, unsigned char *buffer, size_t bufferSize);
// Write a buffer to a file
void hrnFileWrite(const char *fileName, const unsigned char *buffer, size_t bufferSize);
// Replace common test values in a string and return a buffer with the replacements.
//
// Note that the returned buffer will be overwritten with each call. Values that can be replaced are:
//
// {[path]} - the current test path
// {[path-data]} - the current test data path
// {[user]} - the current test user
// {[group]} - the current test group
// {[project-exe]} - the project exe
const char *hrnReplaceKey(const char *string);
// Diff two strings using command-line diff tool
const char *hrnDiff(const char *actual, const char *expected);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
// Time in MS
uint64_t testTimeMSec(void);
// Time in MS at the beginning of the test run (since testBegin() was called)
uint64_t testTimeMSecBegin(void);
// The path and name of the test executable
const char *testExe(void);
void testExeSet(const char *testExe);
// Path where test data is written
const char *testPath(void);
void testPathSet(const char *testPath);
const char *testRepoPath(void);
void testRepoPathSet(const char *testRepoPath);
// Path to a copy of the repository
const char *testRepoPath(void);
// Test OS user
const char *testUser(void);
// Test OS group
const char *testGroup(void);
// Is this test running in a container?
@@ -51,24 +80,6 @@ const char *testProjectExe(void);
// For scaling performance tests
uint64_t testScale(void);
// Read a file (max 256k) into a buffer
void hrnFileRead(const char *fileName, unsigned char *buffer, size_t bufferSize);
// Write a buffer to a file
void hrnFileWrite(const char *fileName, const unsigned char *buffer, size_t bufferSize);
// Replace common test values in a string and return a buffer with the replacements.
//
// Note that the returned buffer will be overwritten with each call. Values that can be replaced are:
//
// {[path]} - the current test path
// {[user]} - the current test user
// {[group]} - the current test group
const char *hrnReplaceKey(const char *string);
// Diff two strings using command-line diff tool
const char *hrnDiff(const char *actual, const char *expected);
/***********************************************************************************************************************************
Maximum size of a formatted result in the TEST_RESULT macro. Strings don't count as they are output directly, so this only applies
to the formatting of bools, ints, floats, etc. This should be plenty of room for any of those types.

View File

@@ -0,0 +1,18 @@
/***********************************************************************************************************************************
C Test Harness Internal
***********************************************************************************************************************************/
#ifndef TEST_COMMON_HARNESS_INTERN_H
#define TEST_COMMON_HARNESS_INTERN_H
#include "common/harnessTest.h"
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void hrnInit(
const char *testExe, const char *testProjectExe, bool testContainer, unsigned int testIdx, uint64_t testScale,
const char *testPath, const char *testDataPath, const char *testRepoPath);
void hrnAdd(int run, bool selected);
void hrnComplete(void);
#endif

View File

@@ -28,14 +28,7 @@ The test code is included directly so it can freely interact with the included C
#endif
#include "common/harnessDebug.h"
#include "common/harnessTest.h"
void testInit(void);
void testContainerSet(bool testContainer);
void testDataPathSet(const char *testDataPath);
void testIdxSet(unsigned int testIdx);
void testScaleSet(uint64_t testScale);
void testProjectExeSet(const char *testProjectExe);
#include "common/harnessTest.intern.h"
#ifndef NO_LOG
#include "common/harnessLog.h"
@@ -84,15 +77,15 @@ main(int argListSize, const char *argList[])
signal(SIGPIPE, SIG_IGN);
// Set globals
testInit();
testExeSet(argList[0]);
testProjectExeSet("{[C_TEST_PROJECT_EXE]}");
testContainerSet({[C_TEST_CONTAINER]});
testPathSet("{[C_TEST_PATH]}");
testRepoPathSet("{[C_TEST_REPO_PATH]}");
testDataPathSet("{[C_TEST_DATA_PATH]}");
testIdxSet({[C_TEST_IDX]});
testScaleSet({[C_TEST_SCALE]});
hrnInit(
argList[0], // Test exe
"{[C_TEST_PROJECT_EXE]}", // Project exe
{[C_TEST_CONTAINER]}, // Is this test running in a container?
{[C_TEST_IDX]}, // The 0-based index of this test
{[C_TEST_SCALE]}, // Scaling factor for performance tests
"{[C_TEST_PATH]}", // Path where tests write data
"{[C_TEST_DATA_PATH]}", // Path where the harness stores temp files (expect, diff, etc.)
"{[C_TEST_REPO_PATH]}"); // Path with a copy of the repository
// Set default test log level
#ifndef NO_LOG
@@ -111,7 +104,7 @@ main(int argListSize, const char *argList[])
testRun();
// End test run and make sure all tests completed
testComplete();
hrnComplete();
printf("\nTESTS COMPLETED SUCCESSFULLY\n");
fflush(stdout);