You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2026-05-22 10:15:16 +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:
@@ -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;
|
||||
|
||||
+144
-256
@@ -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(¤tTime, 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(¤tTime, 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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
+11
-18
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user