mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Add unit tests for the unit test build code.
When this code was migrated to C the unit tests were not included because there were more important priorities at the time. This also requires some adjustments to coverage because of the new code location.
This commit is contained in:
parent
a5499afabc
commit
4429bc82f5
@ -631,6 +631,19 @@ unit:
|
|||||||
- build/postgres/parse
|
- build/postgres/parse
|
||||||
- build/postgres/render
|
- build/postgres/render
|
||||||
|
|
||||||
|
# ********************************************************************************************************************************
|
||||||
|
- name: test
|
||||||
|
|
||||||
|
test:
|
||||||
|
# ----------------------------------------------------------------------------------------------------------------------------
|
||||||
|
- name: test
|
||||||
|
total: 3
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- test/command/test/build
|
||||||
|
- test/command/test/define
|
||||||
|
- test/command/test/test
|
||||||
|
|
||||||
# ********************************************************************************************************************************
|
# ********************************************************************************************************************************
|
||||||
- name: info
|
- name: info
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ sub coverageLCovConfigGenerate
|
|||||||
my $bCoverageSummary = shift;
|
my $bCoverageSummary = shift;
|
||||||
|
|
||||||
my $strBranchFilter =
|
my $strBranchFilter =
|
||||||
'OBJECT_DEFINE_[A-Z0-9_]+\(|\s{4}[A-Z][A-Z0-9_]+\([^\?]*\)|\s{4}(ASSERT|CHECK|assert|switch\s)\(|\{\+{0,1}' .
|
'OBJECT_DEFINE_[A-Z0-9_]+\(|\s{4}[A-Z][A-Z0-9_]+\([^\?]*\)|\s{4}(ASSERT|CHECK|CHECK_FMT|assert|switch\s)\(|\{\+{0,1}' .
|
||||||
($bCoverageSummary ? 'uncoverable_branch' : 'uncover(ed|able)_branch');
|
($bCoverageSummary ? 'uncoverable_branch' : 'uncover(ed|able)_branch');
|
||||||
my $strLineFilter =
|
my $strLineFilter =
|
||||||
'\{\+{0,1}' . ($bCoverageSummary ? 'uncoverable' : '(uncover(ed|able)' . ($bContainer ? '' : '|vm_covered') . ')') . '[^_]';
|
'\{\+{0,1}' . ($bCoverageSummary ? 'uncoverable' : '(uncover(ed|able)' . ($bContainer ? '' : '|vm_covered') . ')') . '[^_]';
|
||||||
@ -124,6 +124,12 @@ sub coverageExtract
|
|||||||
foreach my $strCoveredModule (@stryCoveredModule)
|
foreach my $strCoveredModule (@stryCoveredModule)
|
||||||
{
|
{
|
||||||
my $strModuleName = testRunName($strCoveredModule, false);
|
my $strModuleName = testRunName($strCoveredModule, false);
|
||||||
|
|
||||||
|
if ($strModuleName =~ /^test/mg)
|
||||||
|
{
|
||||||
|
$strModuleName =~ s/^test/src/mg;
|
||||||
|
}
|
||||||
|
|
||||||
my $strModuleOutName = $strModuleName;
|
my $strModuleOutName = $strModuleName;
|
||||||
my $bTest = false;
|
my $bTest = false;
|
||||||
|
|
||||||
@ -134,10 +140,21 @@ sub coverageExtract
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Generate lcov reports
|
# Generate lcov reports
|
||||||
my $strModulePath =
|
my $strModulePath = "${strWorkPath}/repo/";
|
||||||
"${strWorkPath}/repo/" .
|
|
||||||
(${strModuleOutName} =~ /^test\// ?
|
if (${strModuleOutName} =~ /^src\//)
|
||||||
'test/src/module/' . substr(${strModuleOutName}, 5) : "src/${strModuleOutName}");
|
{
|
||||||
|
$strModulePath .= 'test/src/' . substr(${strModuleOutName}, 4);
|
||||||
|
}
|
||||||
|
elsif (${strModuleOutName} =~ /^test\//)
|
||||||
|
{
|
||||||
|
$strModulePath .= 'test/src/module/' . substr(${strModuleOutName}, 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$strModulePath .= "src/${strModuleOutName}";
|
||||||
|
}
|
||||||
|
|
||||||
my $strLCovFile = "${strTestResultCoveragePath}/raw/${strModuleOutName}.lcov";
|
my $strLCovFile = "${strTestResultCoveragePath}/raw/${strModuleOutName}.lcov";
|
||||||
my $strLCovTotal = "${strWorkTmpPath}/all.lcov";
|
my $strLCovTotal = "${strWorkTmpPath}/all.lcov";
|
||||||
my $bInc = $strModuleName =~ '\.vendor$' || $strModuleName =~ '\.auto$';
|
my $bInc = $strModuleName =~ '\.vendor$' || $strModuleName =~ '\.auto$';
|
||||||
@ -297,6 +314,7 @@ sub coverageValidateAndGenerate
|
|||||||
foreach my $strCodeModule (sort(keys(%{$hCoverageActual})))
|
foreach my $strCodeModule (sort(keys(%{$hCoverageActual})))
|
||||||
{
|
{
|
||||||
my $strCoverageFile = $strCodeModule;
|
my $strCoverageFile = $strCodeModule;
|
||||||
|
$strCoverageFile =~ s/^test/src/mg;
|
||||||
$strCoverageFile =~ s/^module/test/mg;
|
$strCoverageFile =~ s/^module/test/mg;
|
||||||
$strCoverageFile = "${strTestResultCoveragePath}/raw/${strCoverageFile}.lcov";
|
$strCoverageFile = "${strTestResultCoveragePath}/raw/${strCoverageFile}.lcov";
|
||||||
|
|
||||||
|
@ -129,9 +129,13 @@ testBldShim(const String *const shimC, const StringList *const functionList)
|
|||||||
{
|
{
|
||||||
strCatChr(result, ' ');
|
strCatChr(result, ' ');
|
||||||
strCat(result, in);
|
strCat(result, in);
|
||||||
|
unsigned int scanIdx = inIdx + 1;
|
||||||
|
|
||||||
for (unsigned int scanIdx = inIdx + 1; scanIdx < strLstSize(inList); scanIdx++)
|
while (true)
|
||||||
{
|
{
|
||||||
|
// In a properly formatted C file the end of the list can never be reached
|
||||||
|
ASSERT(scanIdx < strLstSize(inList));
|
||||||
|
|
||||||
const String *const scan = strLstGet(inList, scanIdx);
|
const String *const scan = strLstGet(inList, scanIdx);
|
||||||
|
|
||||||
if (strEqZ(scan, "{"))
|
if (strEqZ(scan, "{"))
|
||||||
@ -141,6 +145,7 @@ testBldShim(const String *const shimC, const StringList *const functionList)
|
|||||||
strCatChr(result, ' ');
|
strCatChr(result, ' ');
|
||||||
|
|
||||||
strCat(result, strTrim(strDup(scan)));
|
strCat(result, strTrim(strDup(scan)));
|
||||||
|
scanIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
strCatZ(result, "; ");
|
strCatZ(result, "; ");
|
||||||
@ -198,8 +203,30 @@ testBldWrite(const Storage *const storage, StringList *const fileList, const cha
|
|||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Generate a relative path from the compare path to the base path
|
Generate a relative path from the compare path to the base path
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static String *
|
||||||
|
cmdBldPathModule(const String *const moduleName)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, moduleName);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
??? This function has not been hardened for edge cases, e.g. paths are equal. Probably this should he moved to the storage module.
|
String *const result = strNew();
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
if (strBeginsWithZ(moduleName, "test/"))
|
||||||
|
strCatFmt(result, "test/src%s", strZ(strSub(moduleName, 4)));
|
||||||
|
else
|
||||||
|
strCatFmt(result, "src/%s", strZ(moduleName));
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN(STRING, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Generate a relative path from the compare path to the base path
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
static String *
|
static String *
|
||||||
cmdBldPathRelative(const String *const base, const String *const compare)
|
cmdBldPathRelative(const String *const base, const String *const compare)
|
||||||
@ -211,6 +238,7 @@ cmdBldPathRelative(const String *const base, const String *const compare)
|
|||||||
|
|
||||||
ASSERT(base != NULL);
|
ASSERT(base != NULL);
|
||||||
ASSERT(compare != NULL);
|
ASSERT(compare != NULL);
|
||||||
|
ASSERT(!strEq(base, compare));
|
||||||
|
|
||||||
String *const result = strNew();
|
String *const result = strNew();
|
||||||
|
|
||||||
@ -243,7 +271,16 @@ cmdBldPathRelative(const String *const base, const String *const compare)
|
|||||||
|
|
||||||
// Add remaining path
|
// Add remaining path
|
||||||
for (unsigned int pathIdx = compareIdx; pathIdx < strLstSize(compareList); pathIdx++)
|
for (unsigned int pathIdx = compareIdx; pathIdx < strLstSize(compareList); pathIdx++)
|
||||||
strCatFmt(result, "/%s", strZ(strLstGet(compareList, pathIdx)));
|
{
|
||||||
|
// If first is still set then compare must be a subpath of base (i.e. there were no .. parts)
|
||||||
|
if (!first)
|
||||||
|
{
|
||||||
|
strCatChr(result, '/');
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
strCat(result, strLstGet(compareList, pathIdx));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MEM_CONTEXT_TEMP_END();
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
@ -279,7 +316,7 @@ testBldUnit(TestBuild *const this)
|
|||||||
for (unsigned int shimIdx = 0; shimIdx < lstSize(module->shimList); shimIdx++)
|
for (unsigned int shimIdx = 0; shimIdx < lstSize(module->shimList); shimIdx++)
|
||||||
{
|
{
|
||||||
const TestDefShim *const shim = lstGet(module->shimList, shimIdx);
|
const TestDefShim *const shim = lstGet(module->shimList, shimIdx);
|
||||||
const String *const shimFile = strNewFmt("src/%s.c", strZ(shim->name));
|
const String *const shimFile = strNewFmt("%s.c", strZ(cmdBldPathModule(shim->name)));
|
||||||
|
|
||||||
String *const shimC = strCatBuf(
|
String *const shimC = strCatBuf(
|
||||||
strNew(),
|
strNew(),
|
||||||
@ -309,8 +346,8 @@ testBldUnit(TestBuild *const this)
|
|||||||
const String *const include = strLstGet(harness->includeList, includeIdx);
|
const String *const include = strLstGet(harness->includeList, includeIdx);
|
||||||
|
|
||||||
strCatFmt(
|
strCatFmt(
|
||||||
includeReplace, "%s#include \"%s/src/%s.c\"", includeIdx == 0 ? "" : "\n",
|
includeReplace, "%s#include \"%s/%s.c\"", includeIdx == 0 ? "" : "\n",
|
||||||
lstExists(module->shimList, &include) ? strZ(pathUnit) : strZ(pathRepo), strZ(include));
|
lstExists(module->shimList, &include) ? strZ(pathUnit) : strZ(pathRepo), strZ(cmdBldPathModule(include)));
|
||||||
|
|
||||||
strLstAdd(harnessIncludeList, include);
|
strLstAdd(harnessIncludeList, include);
|
||||||
}
|
}
|
||||||
@ -396,7 +433,7 @@ testBldUnit(TestBuild *const this)
|
|||||||
if (strLstExists(harnessIncludeList, depend))
|
if (strLstExists(harnessIncludeList, depend))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strCatFmt(mesonBuild, " '%s/src/%s.c',\n", strZ(pathRepoRel), strZ(depend));
|
strCatFmt(mesonBuild, " '%s/%s.c',\n", strZ(pathRepoRel), strZ(cmdBldPathModule(depend)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add harnesses
|
// Add harnesses
|
||||||
@ -524,24 +561,19 @@ testBldUnit(TestBuild *const this)
|
|||||||
// Files to test/include
|
// Files to test/include
|
||||||
StringList *const testIncludeFileList = strLstNew();
|
StringList *const testIncludeFileList = strLstNew();
|
||||||
|
|
||||||
if (module->coverageList != NULL)
|
for (unsigned int coverageIdx = 0; coverageIdx < lstSize(module->coverageList); coverageIdx++)
|
||||||
{
|
{
|
||||||
for (unsigned int coverageIdx = 0; coverageIdx < lstSize(module->coverageList); coverageIdx++)
|
const TestDefCoverage *const coverage = lstGet(module->coverageList, coverageIdx);
|
||||||
{
|
|
||||||
const TestDefCoverage *const coverage = lstGet(module->coverageList, coverageIdx);
|
|
||||||
|
|
||||||
if (coverage->coverable && !coverage->included)
|
if (coverage->coverable && !coverage->included)
|
||||||
strLstAdd(testIncludeFileList, coverage->name);
|
strLstAdd(testIncludeFileList, coverage->name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module->includeList != NULL)
|
for (unsigned int includeIdx = 0; includeIdx < strLstSize(module->includeList); includeIdx++)
|
||||||
{
|
strLstAdd(testIncludeFileList, strLstGet(module->includeList, includeIdx));
|
||||||
for (unsigned int includeIdx = 0; includeIdx < strLstSize(module->includeList); includeIdx++)
|
|
||||||
strLstAdd(testIncludeFileList, strLstGet(module->includeList, includeIdx));
|
|
||||||
}
|
|
||||||
|
|
||||||
String *const testIncludeFile = strNew();
|
StringList *const testIncludeFile = strLstNew();
|
||||||
|
StringList *const harnessIncluded = strLstNew();
|
||||||
|
|
||||||
for (unsigned int testIncludeFileIdx = 0; testIncludeFileIdx < strLstSize(testIncludeFileList); testIncludeFileIdx++)
|
for (unsigned int testIncludeFileIdx = 0; testIncludeFileIdx < strLstSize(testIncludeFileList); testIncludeFileIdx++)
|
||||||
{
|
{
|
||||||
@ -556,16 +588,19 @@ testBldUnit(TestBuild *const this)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testIncludeFileIdx != 0)
|
|
||||||
strCatChr(testIncludeFile, '\n');
|
|
||||||
|
|
||||||
if (harnessIdx != lstSize(module->harnessList))
|
if (harnessIdx != lstSize(module->harnessList))
|
||||||
strCatFmt(testIncludeFile, "#include \"%s\"", strZ(strLstGet(harnessList, harnessIdx)));
|
{
|
||||||
|
if (!strLstExists(harnessIncluded, strLstGet(harnessList, harnessIdx)))
|
||||||
|
{
|
||||||
|
strLstAddFmt(testIncludeFile, "#include \"%s\"", strZ(strLstGet(harnessList, harnessIdx)));
|
||||||
|
strLstAdd(harnessIncluded, strLstGet(harnessList, harnessIdx));
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
strCatFmt(testIncludeFile, "#include \"%s/src/%s.c\"", strZ(pathRepoRel), strZ(include));
|
strLstAddFmt(testIncludeFile, "#include \"%s/%s.c\"", strZ(pathRepoRel), strZ(cmdBldPathModule(include)));
|
||||||
}
|
}
|
||||||
|
|
||||||
strReplace(testC, STRDEF("{[C_INCLUDE]}"), testIncludeFile);
|
strReplace(testC, STRDEF("{[C_INCLUDE]}"), strLstJoin(testIncludeFile, "\n"));
|
||||||
|
|
||||||
// Test path
|
// Test path
|
||||||
strReplace(testC, STRDEF("{[C_TEST_PATH]}"), storagePathP(storageTestId, NULL));
|
strReplace(testC, STRDEF("{[C_TEST_PATH]}"), storagePathP(storageTestId, NULL));
|
||||||
|
@ -47,8 +47,7 @@ testDefParseModuleList(Yaml *const yaml, List *const moduleList)
|
|||||||
// Check if next is db for integration tests
|
// Check if next is db for integration tests
|
||||||
bool pgRequired = false;
|
bool pgRequired = false;
|
||||||
|
|
||||||
if (type == testDefTypeIntegration && yamlEventPeek(yaml).type == yamlEventTypeScalar &&
|
if (type == testDefTypeIntegration && strEqZ(yamlEventPeek(yaml).value, "db"))
|
||||||
strEqZ(yamlEventPeek(yaml).value, "db"))
|
|
||||||
{
|
{
|
||||||
yamlScalarNextCheckZ(yaml, "db");
|
yamlScalarNextCheckZ(yaml, "db");
|
||||||
pgRequired = yamlBoolParse(yamlScalarNext(yaml));
|
pgRequired = yamlBoolParse(yamlScalarNext(yaml));
|
||||||
@ -99,8 +98,8 @@ testDefParseModuleList(Yaml *const yaml, List *const moduleList)
|
|||||||
{
|
{
|
||||||
testDefCoverage.coverable = true;
|
testDefCoverage.coverable = true;
|
||||||
}
|
}
|
||||||
else if (!strEqZ(type, "noCode"))
|
else
|
||||||
THROW_FMT(FormatError, "invalid coverage type '%s'", strZ(type));
|
CHECK_FMT(AssertError, strEqZ(type, "noCode"), "invalid coverage type %s", strZ(type));
|
||||||
}
|
}
|
||||||
YAML_MAP_END();
|
YAML_MAP_END();
|
||||||
}
|
}
|
||||||
@ -204,15 +203,14 @@ testDefParseModuleList(Yaml *const yaml, List *const moduleList)
|
|||||||
{
|
{
|
||||||
testDefModule.name = strNewFmt("%s/%s", strZ(moduleName), strZ(yamlScalarNext(yaml).value));
|
testDefModule.name = strNewFmt("%s/%s", strZ(moduleName), strZ(yamlScalarNext(yaml).value));
|
||||||
}
|
}
|
||||||
else if (strEqZ(subModuleDef.value, "total"))
|
|
||||||
{
|
|
||||||
testDefModule.total = cvtZToUInt(strZ(yamlScalarNext(yaml).value));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
THROW_FMT(
|
CHECK_FMT(
|
||||||
FormatError, "unexpected scalar '%s' at line %zu, column %zu", strZ(subModuleDef.value),
|
FormatError, strEqZ(subModuleDef.value, "total"),
|
||||||
subModuleDef.line, subModuleDef.column);
|
"unexpected keyword '%s' at line %zu, column %zu",
|
||||||
|
strZ(subModuleDef.value), subModuleDef.line, subModuleDef.column);
|
||||||
|
|
||||||
|
testDefModule.total = cvtZToUInt(strZ(yamlScalarNext(yaml).value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
YAML_MAP_END();
|
YAML_MAP_END();
|
||||||
@ -224,11 +222,8 @@ testDefParseModuleList(Yaml *const yaml, List *const moduleList)
|
|||||||
{
|
{
|
||||||
const String *const depend = strLstGet(globalDependList, dependIdx);
|
const String *const depend = strLstGet(globalDependList, dependIdx);
|
||||||
|
|
||||||
if ((coverageList == NULL || !lstExists(coverageList, &depend)) &&
|
if (!lstExists(coverageList, &depend) && !strLstExists(includeList, depend))
|
||||||
(includeList == NULL || !strLstExists(includeList, depend)))
|
|
||||||
{
|
|
||||||
strLstAdd(dependList, depend);
|
strLstAdd(dependList, depend);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add test module
|
// Add test module
|
||||||
|
@ -28,12 +28,11 @@ cmdTestExec(const String *const command)
|
|||||||
|
|
||||||
if (system(zNewFmt("%s > %s 2>&1", strZ(command), strZ(cmdTestExecLog))) != 0)
|
if (system(zNewFmt("%s > %s 2>&1", strZ(command), strZ(cmdTestExecLog))) != 0)
|
||||||
{
|
{
|
||||||
const Buffer *const buffer = storageGetP(
|
const Buffer *const buffer = storageGetP(storageNewReadP(storagePosixNewP(FSLASH_STR), cmdTestExecLog));
|
||||||
storageNewReadP(storagePosixNewP(FSLASH_STR), cmdTestExecLog, .ignoreMissing = true));
|
|
||||||
|
|
||||||
THROW_FMT(
|
THROW_FMT(
|
||||||
ExecuteError, "unable to execute: %s > %s 2>&1:%s", strZ(command), strZ(cmdTestExecLog),
|
ExecuteError, "unable to execute: %s > %s 2>&1:\n%s", strZ(command), strZ(cmdTestExecLog),
|
||||||
buffer == NULL || bufEmpty(buffer) ? " no log output" : zNewFmt("\n%s", strZ(strNewBuf(buffer))));
|
zNewFmt("\n%s", strZ(strTrim(strNewBuf(buffer)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
FUNCTION_LOG_RETURN_VOID();
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
@ -73,15 +72,15 @@ cmdTestPathCreate(const Storage *const storage, const String *const path)
|
|||||||
void
|
void
|
||||||
cmdTest(
|
cmdTest(
|
||||||
const String *const pathRepo, const String *const pathTest, const String *const vm, const unsigned int vmId,
|
const String *const pathRepo, const String *const pathTest, const String *const vm, const unsigned int vmId,
|
||||||
const StringList *moduleFilterList, const unsigned int test, const uint64_t scale, const LogLevel logLevel,
|
const String *moduleName, const unsigned int test, const uint64_t scale, const LogLevel logLevel, const bool logTime,
|
||||||
const bool logTime, const String *const timeZone, const bool coverage, const bool profile, const bool optimize)
|
const String *const timeZone, const bool coverage, const bool profile, const bool optimize)
|
||||||
{
|
{
|
||||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||||
FUNCTION_LOG_PARAM(STRING, pathRepo);
|
FUNCTION_LOG_PARAM(STRING, pathRepo);
|
||||||
FUNCTION_LOG_PARAM(STRING, pathTest);
|
FUNCTION_LOG_PARAM(STRING, pathTest);
|
||||||
FUNCTION_LOG_PARAM(STRING, vm);
|
FUNCTION_LOG_PARAM(STRING, vm);
|
||||||
FUNCTION_LOG_PARAM(UINT, vmId);
|
FUNCTION_LOG_PARAM(UINT, vmId);
|
||||||
FUNCTION_LOG_PARAM(STRING_LIST, moduleFilterList);
|
FUNCTION_LOG_PARAM(STRING, moduleName);
|
||||||
FUNCTION_LOG_PARAM(UINT, test);
|
FUNCTION_LOG_PARAM(UINT, test);
|
||||||
FUNCTION_LOG_PARAM(UINT64, scale);
|
FUNCTION_LOG_PARAM(UINT64, scale);
|
||||||
FUNCTION_LOG_PARAM(ENUM, logLevel);
|
FUNCTION_LOG_PARAM(ENUM, logLevel);
|
||||||
@ -98,14 +97,12 @@ cmdTest(
|
|||||||
cmdTestExecLog = strNewFmt("%s/exec-%u.log", strZ(pathTest), vmId);
|
cmdTestExecLog = strNewFmt("%s/exec-%u.log", strZ(pathTest), vmId);
|
||||||
|
|
||||||
// Find test
|
// Find test
|
||||||
ASSERT(!strLstEmpty(moduleFilterList));
|
ASSERT(moduleName != NULL);
|
||||||
|
|
||||||
const TestDef testDef = testDefParse(storagePosixNewP(pathRepo));
|
const TestDef testDef = testDefParse(storagePosixNewP(pathRepo));
|
||||||
const String *const moduleName = strLstGet(moduleFilterList, 0);
|
|
||||||
const TestDefModule *const module = lstFind(testDef.moduleList, &moduleName);
|
const TestDefModule *const module = lstFind(testDef.moduleList, &moduleName);
|
||||||
|
|
||||||
if (module == NULL)
|
CHECK_FMT(ParamInvalidError, module != NULL, "'%s' is not a valid test", strZ(moduleName));
|
||||||
THROW_FMT(ParamInvalidError, "'%s' is not a valid test", strZ(moduleName));
|
|
||||||
|
|
||||||
// Build test
|
// Build test
|
||||||
bool buildRetry = false;
|
bool buildRetry = false;
|
||||||
|
@ -13,7 +13,7 @@ Perform a test.
|
|||||||
Functions
|
Functions
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
void cmdTest(
|
void cmdTest(
|
||||||
const String *pathRepo, const String *pathTest, const String *const vm, unsigned int vmId, const StringList *moduleFilterList,
|
const String *pathRepo, const String *pathTest, const String *const vm, unsigned int vmId, const String *moduleName,
|
||||||
unsigned int test, uint64_t scale, LogLevel logLevel, bool logTime, const String *timeZone, bool coverage, bool profile,
|
unsigned int test, uint64_t scale, LogLevel logLevel, bool logTime, const String *timeZone, bool coverage, bool profile,
|
||||||
bool optimize);
|
bool optimize);
|
||||||
|
|
||||||
|
@ -72,10 +72,11 @@ main(int argListSize, const char *argList[])
|
|||||||
{
|
{
|
||||||
cmdTest(
|
cmdTest(
|
||||||
cfgOptionStr(cfgOptRepoPath), cfgOptionStr(cfgOptTestPath), cfgOptionStr(cfgOptVm),
|
cfgOptionStr(cfgOptRepoPath), cfgOptionStr(cfgOptTestPath), cfgOptionStr(cfgOptVm),
|
||||||
cfgOptionUInt(cfgOptVmId), cfgCommandParam(), cfgOptionTest(cfgOptTest) ? cfgOptionUInt(cfgOptTest) : 0,
|
cfgOptionUInt(cfgOptVmId), strLstGet(cfgCommandParam(), 0),
|
||||||
cfgOptionUInt64(cfgOptScale), logLevelEnum(cfgOptionStrId(cfgOptLogLevelTest)),
|
cfgOptionTest(cfgOptTest) ? cfgOptionUInt(cfgOptTest) : 0, cfgOptionUInt64(cfgOptScale),
|
||||||
cfgOptionBool(cfgOptLogTimestamp), cfgOptionStrNull(cfgOptTz), cfgOptionBool(cfgOptCoverage),
|
logLevelEnum(cfgOptionStrId(cfgOptLogLevelTest)), cfgOptionBool(cfgOptLogTimestamp),
|
||||||
cfgOptionBool(cfgOptProfile), cfgOptionBool(cfgOptOptimize));
|
cfgOptionStrNull(cfgOptTz), cfgOptionBool(cfgOptCoverage), cfgOptionBool(cfgOptProfile),
|
||||||
|
cfgOptionBool(cfgOptOptimize));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
872
test/src/module/test/testTest.c
Normal file
872
test/src/module/test/testTest.c
Normal file
@ -0,0 +1,872 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Test Command
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "storage/posix/storage.h"
|
||||||
|
|
||||||
|
#include "common/harnessStorage.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Build list of test files to compare
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static StringList *
|
||||||
|
testStorageList(const Storage *const storage)
|
||||||
|
{
|
||||||
|
StringList *const result = strLstNew();
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
StorageIterator *storageItr = storageNewItrP(storage, NULL, .sortOrder = sortOrderAsc, .recurse = true);
|
||||||
|
|
||||||
|
while (storageItrMore(storageItr))
|
||||||
|
{
|
||||||
|
const StorageInfo info = storageItrNext(storageItr);
|
||||||
|
|
||||||
|
if (info.type == storageTypeFile && !strBeginsWithZ(info.name, "build/"))
|
||||||
|
strLstAdd(result, info.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Copy a list of files from the repo to the test repo
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#define TEST_COPY(source, destination, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
const char *const copyList[] = {__VA_ARGS__}; \
|
||||||
|
\
|
||||||
|
for (unsigned int copyIdx = 0; copyIdx < LENGTH_OF(copyList); copyIdx++) \
|
||||||
|
{ \
|
||||||
|
HRN_STORAGE_PUT( \
|
||||||
|
destination, zNewFmt("repo/%s", copyList[copyIdx]), storageGetP(storageNewReadP(source, STR(copyList[copyIdx])))); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Run
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static void
|
||||||
|
testRun(void)
|
||||||
|
{
|
||||||
|
FUNCTION_HARNESS_VOID();
|
||||||
|
|
||||||
|
const Storage *const storageRepo = storagePosixNewP(STRDEF(HRN_PATH_REPO));
|
||||||
|
const Storage *const storageTest = storagePosixNewP(STRDEF(TEST_PATH), .write = true);
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("cmdBldPathRelative()"))
|
||||||
|
{
|
||||||
|
TEST_ERROR(cmdBldPathRelative(STRDEF("/tmp"), STRDEF("/tmp")), AssertError, "assertion '!strEq(base, compare)' failed");
|
||||||
|
|
||||||
|
TEST_RESULT_STR_Z(cmdBldPathRelative(STRDEF("/tmp/sub"), STRDEF("/tmp")), "..", "compare is sub of base");
|
||||||
|
TEST_RESULT_STR_Z(cmdBldPathRelative(STRDEF("/tmp"), STRDEF("/tmp/sub")), "sub", "base is sub of compare");
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("cmdTestExec()"))
|
||||||
|
{
|
||||||
|
cmdTestExecLog = STRDEF(TEST_PATH "/error.log");
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
|
// The error will vary by OS so just make sure an error was thrown
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
cmdTestExec(STRDEF("/bogus/bogus"));
|
||||||
|
}
|
||||||
|
CATCH(ExecuteError)
|
||||||
|
{
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
|
TEST_RESULT_BOOL(error, true, "an error should be thrown");
|
||||||
|
|
||||||
|
cmdTestExecLog = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("TestDef and TestBuild"))
|
||||||
|
{
|
||||||
|
// meson_options.txt
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
const char *const mesonOption = strZ(strNewBuf(storageGetP(storageNewReadP(storageRepo, STRDEF("meson_options.txt")))));
|
||||||
|
HRN_STORAGE_PUT_Z(storageTest, "repo/meson_options.txt", mesonOption);
|
||||||
|
|
||||||
|
// Root meson.build
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
String *const mesonBuildRoot = strCat(
|
||||||
|
strNew(), strNewBuf(storageGetP(storageNewReadP(storageRepo, STRDEF("meson.build")))));
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_Z(storageTest, "repo/meson.build", strZ(mesonBuildRoot));
|
||||||
|
strReplace(mesonBuildRoot, STRDEF("subdir('"), STRDEF("# subdir('"));
|
||||||
|
|
||||||
|
strCatZ(
|
||||||
|
mesonBuildRoot,
|
||||||
|
"\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"# Write configuration\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"configure_file(output: 'build.auto.h', configuration: configuration)\n"
|
||||||
|
"\n"
|
||||||
|
"add_global_arguments('-DFN_EXTERN=extern', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DVR_EXTERN_DECLARE=extern', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DVR_EXTERN_DEFINE=', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DERROR_MESSAGE_BUFFER_SIZE=131072', language : 'c')\n");
|
||||||
|
|
||||||
|
// harnessError.c
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
String *const harnessErrorC = strCat(
|
||||||
|
strNew(), strNewBuf(storageGetP(storageNewReadP(storageRepo, STRDEF("test/src/common/harnessError.c")))));
|
||||||
|
|
||||||
|
strReplace(harnessErrorC, STRDEF("{[SHIM_MODULE]}"), STRDEF("#include \"" TEST_PATH "/repo/src/common/error.c\""));
|
||||||
|
|
||||||
|
// Unit test harness
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
String *const testC = strCat(strNew(), strNewBuf(storageGetP(storageNewReadP(storageRepo, STRDEF("test/src/test.c")))));
|
||||||
|
|
||||||
|
strReplace(testC, STRDEF("{[C_HRN_PATH]}"), STRDEF(TEST_PATH "/test/data-3"));
|
||||||
|
strReplace(testC, STRDEF("{[C_HRN_PATH_REPO]}"), STRDEF(TEST_PATH "/repo"));
|
||||||
|
strReplace(testC, STRDEF("{[C_LOG_LEVEL_TEST]}"), STRDEF("logLevelDebug"));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_GROUP]}"), STRDEF(TEST_GROUP));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_GROUP_ID]}"), STRDEF(TEST_GROUP_ID_Z));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_GROUP_ID_Z]}"), STRDEF("\"" TEST_GROUP_ID_Z "\""));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_IDX]}"), STRDEF("3"));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_PATH]}"), STRDEF(TEST_PATH "/test/test-3"));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_PGB_PATH]}"), STRDEF("../../../../repo"));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_SCALE]}"), STRDEF("1"));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_TIMING]}"), STRDEF("true"));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_USER]}"), STRDEF(TEST_USER));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_USER_ID]}"), STRDEF(TEST_USER_ID_Z));
|
||||||
|
strReplace(testC, STRDEF("{[C_TEST_USER_ID_Z]}"), STRDEF("\"" TEST_USER_ID_Z "\""));
|
||||||
|
|
||||||
|
// Test definition
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
HRN_STORAGE_PUT_Z(
|
||||||
|
storageTest, "repo/test/define.yaml",
|
||||||
|
"unit:\n"
|
||||||
|
" - name: common\n"
|
||||||
|
" test:\n"
|
||||||
|
" - name: pre\n"
|
||||||
|
" total: 1\n"
|
||||||
|
"\n"
|
||||||
|
" - name: error\n"
|
||||||
|
" total: 9\n"
|
||||||
|
" feature: error\n"
|
||||||
|
" harness:\n"
|
||||||
|
" name: error\n"
|
||||||
|
" shim:\n"
|
||||||
|
" common/error: ~\n"
|
||||||
|
" coverage:\n"
|
||||||
|
" - common/error\n"
|
||||||
|
" - common/error.auto: noCode\n"
|
||||||
|
" - common/error.inc: included\n"
|
||||||
|
" depend:\n"
|
||||||
|
" - common/stackTrace\n"
|
||||||
|
"\n"
|
||||||
|
" - name: stack-trace\n"
|
||||||
|
" total: 4\n"
|
||||||
|
" feature: stackTrace\n"
|
||||||
|
" coverage:\n"
|
||||||
|
" - common/stackTrace\n"
|
||||||
|
" depend:\n"
|
||||||
|
" - common/debug\n"
|
||||||
|
"\n"
|
||||||
|
" - name: test\n"
|
||||||
|
" test:\n"
|
||||||
|
" - name: shim\n"
|
||||||
|
" binReq: true\n"
|
||||||
|
" containerReq: true\n"
|
||||||
|
" total: 1\n"
|
||||||
|
" define: -DNDEBUG\n"
|
||||||
|
" harness: noShim\n"
|
||||||
|
" harness:\n"
|
||||||
|
" name: shim\n"
|
||||||
|
" shim:\n"
|
||||||
|
" test/common/shim:\n"
|
||||||
|
" function:\n"
|
||||||
|
" - shimFunc\n"
|
||||||
|
" - shimFunc2\n"
|
||||||
|
" test/common/shim2: ~\n"
|
||||||
|
" coverage:\n"
|
||||||
|
" - test/common/shim\n"
|
||||||
|
" - test/common/shim2\n"
|
||||||
|
" include:\n"
|
||||||
|
" - common/error\n"
|
||||||
|
" - test/common/include\n"
|
||||||
|
"\n"
|
||||||
|
"integration:\n"
|
||||||
|
" - name: mock\n"
|
||||||
|
" test:\n"
|
||||||
|
" - name: all\n"
|
||||||
|
" total: 2\n"
|
||||||
|
"\n"
|
||||||
|
" - name: real\n"
|
||||||
|
" db: true\n"
|
||||||
|
" test:\n"
|
||||||
|
" - name: all\n"
|
||||||
|
" total: 2\n"
|
||||||
|
"\n"
|
||||||
|
"performance:\n"
|
||||||
|
" - name: performance\n"
|
||||||
|
" test:\n"
|
||||||
|
" - name: type\n"
|
||||||
|
" total: 1\n");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("Test common/stack-trace");
|
||||||
|
|
||||||
|
TEST_COPY(
|
||||||
|
storageRepo, storageTest,
|
||||||
|
"src/common/assert.h",
|
||||||
|
"src/common/debug.c",
|
||||||
|
"src/common/debug.h",
|
||||||
|
"src/common/error.auto.c.inc",
|
||||||
|
"src/common/error.auto.h",
|
||||||
|
"src/common/error.c",
|
||||||
|
"src/common/error.h",
|
||||||
|
"src/common/logLevel.h",
|
||||||
|
"src/common/macro.h",
|
||||||
|
"src/common/stackTrace.c",
|
||||||
|
"src/common/stackTrace.h",
|
||||||
|
"src/common/type/convert.h",
|
||||||
|
"src/common/type/param.h",
|
||||||
|
"src/common/type/stringZ.h",
|
||||||
|
"test/src/common/harnessDebug.h",
|
||||||
|
"test/src/common/harnessLog.h",
|
||||||
|
"test/src/common/harnessError.c",
|
||||||
|
"test/src/common/harnessError.h",
|
||||||
|
"test/src/common/harnessTest.c",
|
||||||
|
"test/src/common/harnessTest.h",
|
||||||
|
"test/src/common/harnessTest.intern.h",
|
||||||
|
"test/src/module/common/stackTraceTest.c",
|
||||||
|
"test/src/test.c");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(
|
||||||
|
cmdTest(
|
||||||
|
STRDEF(TEST_PATH "/repo"), storagePathP(storageTest, STRDEF("test")), STRDEF("none"), 3,
|
||||||
|
STRDEF("common/stack-trace"), 0, 1, logLevelDebug, true, NULL, false, false, false),
|
||||||
|
"new build");
|
||||||
|
|
||||||
|
const Storage *storageUnit = storagePosixNewP(STRDEF(TEST_PATH "/test/unit-3/none"));
|
||||||
|
StringList *fileList = testStorageList(storageUnit);
|
||||||
|
|
||||||
|
TEST_RESULT_STRLST_Z(
|
||||||
|
fileList,
|
||||||
|
"meson.build\n"
|
||||||
|
"meson_options.txt\n"
|
||||||
|
"test/src/common/harnessError.c\n"
|
||||||
|
"test.c\n",
|
||||||
|
"check files");
|
||||||
|
|
||||||
|
for (unsigned int fileIdx = 0; fileIdx < strLstSize(fileList); fileIdx++)
|
||||||
|
{
|
||||||
|
const String *const file = strLstGet(fileList, fileIdx);
|
||||||
|
|
||||||
|
if (strEqZ(file, "meson.build"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(
|
||||||
|
storageUnit, strZ(file),
|
||||||
|
zNewFmt(
|
||||||
|
"%s"
|
||||||
|
"add_global_arguments('-DHRN_INTEST_STACKTRACE', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DHRN_FEATURE_ERROR', language : 'c')\n"
|
||||||
|
"\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"# Unit test\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"src_unit = files(\n"
|
||||||
|
" '../../../repo/src/common/debug.c',\n"
|
||||||
|
" 'test/src/common/harnessError.c',\n"
|
||||||
|
" '../../../repo/test/src/common/harnessTest.c',\n"
|
||||||
|
" 'test.c',\n"
|
||||||
|
")\n"
|
||||||
|
"\n"
|
||||||
|
"executable(\n"
|
||||||
|
" 'test-unit',\n"
|
||||||
|
" sources: src_unit,\n"
|
||||||
|
" include_directories:\n"
|
||||||
|
" include_directories(\n"
|
||||||
|
" '.',\n"
|
||||||
|
" '../../../repo/src',\n"
|
||||||
|
" '../../../repo/test/src',\n"
|
||||||
|
" ),\n"
|
||||||
|
" dependencies: [\n"
|
||||||
|
" lib_bz2,\n"
|
||||||
|
" lib_openssl,\n"
|
||||||
|
" lib_lz4,\n"
|
||||||
|
" lib_pq,\n"
|
||||||
|
" lib_xml,\n"
|
||||||
|
" lib_yaml,\n"
|
||||||
|
" lib_z,\n"
|
||||||
|
" lib_zstd,\n"
|
||||||
|
" ],\n"
|
||||||
|
")\n",
|
||||||
|
strZ(mesonBuildRoot)));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "meson_options.txt"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), mesonOption);
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test/src/common/harnessError.c"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(harnessErrorC));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test.c"))
|
||||||
|
{
|
||||||
|
String *const testCDup = strCat(strNew(), testC);
|
||||||
|
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_CONTAINER]}"), STRDEF("false"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_DEBUG_TEST_TRACE]}"), STRDEF("#define DEBUG_TEST_TRACE"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PATH_BUILD]}"), STRDEF(TEST_PATH "/test/unit-3/none/build"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROFILE]}"), STRDEF("false"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROJECT_EXE]}"), STRDEF(TEST_PATH "/test/build/none/src/pgbackrest"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_TZ]}"), STRDEF("// No timezone specified"));
|
||||||
|
|
||||||
|
strReplace(testCDup, STRDEF("{[C_INCLUDE]}"), STRDEF("#include \"../../../repo/src/common/stackTrace.c\""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_INCLUDE]}"),
|
||||||
|
STRDEF("#include \"../../../repo/test/src/module/common/stackTraceTest.c\""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_LIST]}"),
|
||||||
|
STRDEF(
|
||||||
|
"hrnAdd( 1, true);\n"
|
||||||
|
" hrnAdd( 2, true);\n"
|
||||||
|
" hrnAdd( 3, true);\n"
|
||||||
|
" hrnAdd( 4, true);"));
|
||||||
|
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(testCDup));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
THROW_FMT(TestError, "no test for '%s'", strZ(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("Test common/error");
|
||||||
|
|
||||||
|
TEST_COPY(
|
||||||
|
storageRepo, storageTest,
|
||||||
|
"test/src/common/harnessFork.h",
|
||||||
|
"test/src/module/common/errorTest.c");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(
|
||||||
|
cmdTest(
|
||||||
|
STRDEF(TEST_PATH "/repo"), storagePathP(storageTest, STRDEF("test")), STRDEF("none"), 3,
|
||||||
|
STRDEF("common/error"), 5, 1, logLevelDebug, true, NULL, false, false, false),
|
||||||
|
"new build");
|
||||||
|
|
||||||
|
fileList = testStorageList(storageUnit);
|
||||||
|
|
||||||
|
TEST_RESULT_STRLST_Z(
|
||||||
|
fileList,
|
||||||
|
"meson.build\n"
|
||||||
|
"meson_options.txt\n"
|
||||||
|
"test/src/common/harnessError.c\n"
|
||||||
|
"test.c\n",
|
||||||
|
"check files");
|
||||||
|
|
||||||
|
for (unsigned int fileIdx = 0; fileIdx < strLstSize(fileList); fileIdx++)
|
||||||
|
{
|
||||||
|
const String *const file = strLstGet(fileList, fileIdx);
|
||||||
|
|
||||||
|
if (strEqZ(file, "meson.build"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(
|
||||||
|
storageUnit, strZ(file),
|
||||||
|
zNewFmt(
|
||||||
|
"%s"
|
||||||
|
"add_global_arguments('-DHRN_INTEST_ERROR', language : 'c')\n"
|
||||||
|
"\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"# Unit test\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"src_unit = files(\n"
|
||||||
|
" '../../../repo/src/common/stackTrace.c',\n"
|
||||||
|
" '../../../repo/test/src/common/harnessTest.c',\n"
|
||||||
|
" 'test.c',\n"
|
||||||
|
")\n"
|
||||||
|
"\n"
|
||||||
|
"executable(\n"
|
||||||
|
" 'test-unit',\n"
|
||||||
|
" sources: src_unit,\n"
|
||||||
|
" include_directories:\n"
|
||||||
|
" include_directories(\n"
|
||||||
|
" '.',\n"
|
||||||
|
" '../../../repo/src',\n"
|
||||||
|
" '../../../repo/test/src',\n"
|
||||||
|
" ),\n"
|
||||||
|
" dependencies: [\n"
|
||||||
|
" lib_bz2,\n"
|
||||||
|
" lib_openssl,\n"
|
||||||
|
" lib_lz4,\n"
|
||||||
|
" lib_pq,\n"
|
||||||
|
" lib_xml,\n"
|
||||||
|
" lib_yaml,\n"
|
||||||
|
" lib_z,\n"
|
||||||
|
" lib_zstd,\n"
|
||||||
|
" ],\n"
|
||||||
|
")\n",
|
||||||
|
strZ(mesonBuildRoot)));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "meson_options.txt"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), mesonOption);
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test/src/common/harnessError.c"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(harnessErrorC));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test.c"))
|
||||||
|
{
|
||||||
|
String *const testCDup = strCat(strNew(), testC);
|
||||||
|
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_CONTAINER]}"), STRDEF("false"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_DEBUG_TEST_TRACE]}"), STRDEF("#define DEBUG_TEST_TRACE"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PATH_BUILD]}"), STRDEF(TEST_PATH "/test/unit-3/none/build"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROFILE]}"), STRDEF("false"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROJECT_EXE]}"), STRDEF(TEST_PATH "/test/build/none/src/pgbackrest"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_TZ]}"), STRDEF("// No timezone specified"));
|
||||||
|
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_INCLUDE]}"),
|
||||||
|
STRDEF("#include \"test/src/common/harnessError.c\""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_INCLUDE]}"),
|
||||||
|
STRDEF("#include \"../../../repo/test/src/module/common/errorTest.c\""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_LIST]}"),
|
||||||
|
STRDEF(
|
||||||
|
"hrnAdd( 1, false);\n"
|
||||||
|
" hrnAdd( 2, false);\n"
|
||||||
|
" hrnAdd( 3, false);\n"
|
||||||
|
" hrnAdd( 4, false);\n"
|
||||||
|
" hrnAdd( 5, true);\n"
|
||||||
|
" hrnAdd( 6, false);\n"
|
||||||
|
" hrnAdd( 7, false);\n"
|
||||||
|
" hrnAdd( 8, false);\n"
|
||||||
|
" hrnAdd( 9, false);"));
|
||||||
|
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(testCDup));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
THROW_FMT(TestError, "no test for '%s'", strZ(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("Test test/shim");
|
||||||
|
|
||||||
|
String *const shimC = strCatZ(
|
||||||
|
strNew(),
|
||||||
|
"int\n"
|
||||||
|
"shimFunc(void)\n"
|
||||||
|
"{\n"
|
||||||
|
" return 777;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"static int\n"
|
||||||
|
"shimFunc2(\n"
|
||||||
|
" int param1,\n"
|
||||||
|
" int param2)\n"
|
||||||
|
"{\n"
|
||||||
|
" return 777 + param1 + param2;\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_Z(storageTest, "repo/test/src/common/shim.c", strZ(shimC));
|
||||||
|
HRN_STORAGE_PUT_Z(
|
||||||
|
storageTest, "repo/test/src/common/shim2.c",
|
||||||
|
"int noShimFunc3(void)\n"
|
||||||
|
"{\n"
|
||||||
|
" return 888;\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
strReplace(shimC, STRDEF("int\nshimFunc(void)"), STRDEF("int\nshimFunc_SHIMMED(void)"));
|
||||||
|
strReplace(
|
||||||
|
shimC, STRDEF("static int\nshimFunc2("),
|
||||||
|
STRDEF("static int shimFunc2(int param1, int param2); static int\nshimFunc2_SHIMMED("));
|
||||||
|
|
||||||
|
String *const harnessShimC = strCatZ(
|
||||||
|
strNew(),
|
||||||
|
"{[SHIM_MODULE]}\n"
|
||||||
|
"\n"
|
||||||
|
"static int\n"
|
||||||
|
"shimFunc(void)\n"
|
||||||
|
"{\n"
|
||||||
|
" return shimFunc_SHIMMED() + 1;\n"
|
||||||
|
" (void)shimFunc2; // To suppress unused warnings\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"static int\n"
|
||||||
|
"shimFunc2(int param1, int param2)\n"
|
||||||
|
"{\n"
|
||||||
|
" return shimFunc2_SHIMMED(param1, param2) + 2;\n"
|
||||||
|
" (void)shimFunc; // To suppress unused warnings\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_Z(storageTest, "repo/test/src/common/harnessShim.c", strZ(harnessShimC));
|
||||||
|
HRN_STORAGE_PUT_EMPTY(storageTest, "repo/test/src/common/harnessShim/sub.c");
|
||||||
|
HRN_STORAGE_PUT_EMPTY(storageTest, "repo/test/src/common/harnessNoShim.c");
|
||||||
|
HRN_STORAGE_PUT_EMPTY(storageTest, "repo/test/src/common/include.c");
|
||||||
|
|
||||||
|
strReplace(
|
||||||
|
harnessShimC, STRDEF("{[SHIM_MODULE]}"),
|
||||||
|
STRDEF(
|
||||||
|
"#include \"" TEST_PATH "/test/unit-3/uXX/test/src/common/shim.c\"\n"
|
||||||
|
"#include \"" TEST_PATH "/repo/test/src/common/shim2.c\""));
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_Z(
|
||||||
|
storageTest, "repo/test/src/module/test/shimTest.c",
|
||||||
|
"static void\n"
|
||||||
|
"testRun(void)\n"
|
||||||
|
"{\n"
|
||||||
|
" FUNCTION_HARNESS_VOID();\n"
|
||||||
|
"\n"
|
||||||
|
" if (testBegin(\"shims\"))\n"
|
||||||
|
" {\n"
|
||||||
|
" TEST_RESULT_INT(shimFunc_SHIMMED(), 777, \"shimFunc()\");\n"
|
||||||
|
" TEST_RESULT_INT(shimFunc(), 778, \"shimFunc()\");\n"
|
||||||
|
"\n"
|
||||||
|
" TEST_RESULT_INT(shimFunc2_SHIMMED(111, 112), 1000, \"shimFunc2()\");\n"
|
||||||
|
" TEST_RESULT_INT(shimFunc2(111, 112), 1002, \"shimFunc2()\");\n"
|
||||||
|
"\n"
|
||||||
|
" TEST_RESULT_INT(noShimFunc3(), 888, \"noShimFunc3()\");\n"
|
||||||
|
" }\n"
|
||||||
|
"\n"
|
||||||
|
" FUNCTION_HARNESS_RETURN_VOID();\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_EMPTY(storageTest, TEST_PATH "/test/unit-3/uXX/cleanme.txt");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(
|
||||||
|
cmdTest(
|
||||||
|
STRDEF(TEST_PATH "/repo"), storagePathP(storageTest, STRDEF("test")), STRDEF("uXX"), 3,
|
||||||
|
STRDEF("test/shim"), 0, 1, logLevelDebug, true, NULL, true, true, true),
|
||||||
|
"new build");
|
||||||
|
|
||||||
|
storageUnit = storagePosixNewP(STRDEF(TEST_PATH "/test/unit-3/uXX"));
|
||||||
|
fileList = testStorageList(storageUnit);
|
||||||
|
|
||||||
|
TEST_RESULT_STRLST_Z(
|
||||||
|
fileList,
|
||||||
|
"meson.build\n"
|
||||||
|
"meson_options.txt\n"
|
||||||
|
"test/src/common/harnessError.c\n"
|
||||||
|
"test/src/common/harnessShim.c\n"
|
||||||
|
"test/src/common/shim.c\n"
|
||||||
|
"test.c\n",
|
||||||
|
"check files");
|
||||||
|
|
||||||
|
for (unsigned int fileIdx = 0; fileIdx < strLstSize(fileList); fileIdx++)
|
||||||
|
{
|
||||||
|
const String *const file = strLstGet(fileList, fileIdx);
|
||||||
|
|
||||||
|
if (strEqZ(file, "meson.build"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(
|
||||||
|
storageUnit, strZ(file),
|
||||||
|
zNewFmt(
|
||||||
|
"%s"
|
||||||
|
"add_global_arguments('-DHRN_FEATURE_ERROR', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DHRN_FEATURE_STACKTRACE', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DNDEBUG', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DDEBUG_COVERAGE', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DTEST_CONTAINER_REQUIRED', language : 'c')\n"
|
||||||
|
"\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"# Unit test\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"src_unit = files(\n"
|
||||||
|
" '../../../repo/src/common/stackTrace.c',\n"
|
||||||
|
" '../../../repo/src/common/debug.c',\n"
|
||||||
|
" '../../../repo/test/src/common/harnessNoShim.c',\n"
|
||||||
|
" '../../../repo/test/src/common/harnessShim/sub.c',\n"
|
||||||
|
" '../../../repo/test/src/common/harnessTest.c',\n"
|
||||||
|
" 'test.c',\n"
|
||||||
|
")\n"
|
||||||
|
"\n"
|
||||||
|
"executable(\n"
|
||||||
|
" 'test-unit',\n"
|
||||||
|
" sources: src_unit,\n"
|
||||||
|
" c_args: [\n"
|
||||||
|
" '-O2',\n"
|
||||||
|
" '-pg',\n"
|
||||||
|
" '-no-pie',\n"
|
||||||
|
" ],\n"
|
||||||
|
" link_args: [\n"
|
||||||
|
" '-pg',\n"
|
||||||
|
" '-no-pie',\n"
|
||||||
|
" ],\n"
|
||||||
|
" include_directories:\n"
|
||||||
|
" include_directories(\n"
|
||||||
|
" '.',\n"
|
||||||
|
" '../../../repo/src',\n"
|
||||||
|
" '../../../repo/test/src',\n"
|
||||||
|
" ),\n"
|
||||||
|
" dependencies: [\n"
|
||||||
|
" lib_bz2,\n"
|
||||||
|
" lib_openssl,\n"
|
||||||
|
" lib_lz4,\n"
|
||||||
|
" lib_pq,\n"
|
||||||
|
" lib_xml,\n"
|
||||||
|
" lib_yaml,\n"
|
||||||
|
" lib_z,\n"
|
||||||
|
" lib_zstd,\n"
|
||||||
|
" ],\n"
|
||||||
|
")\n",
|
||||||
|
strZ(mesonBuildRoot)));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "meson_options.txt"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), mesonOption);
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test/src/common/harnessError.c"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(harnessErrorC));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test/src/common/harnessShim.c"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(harnessShimC));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test/src/common/shim.c"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(shimC));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test.c"))
|
||||||
|
{
|
||||||
|
String *const testCDup = strCat(strNew(), testC);
|
||||||
|
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_CONTAINER]}"), STRDEF("true"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_DEBUG_TEST_TRACE]}"), STRDEF("// Debug test trace not enabled"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PATH_BUILD]}"), STRDEF(TEST_PATH "/test/unit-3/uXX/build"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROFILE]}"), STRDEF("true"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROJECT_EXE]}"), STRDEF(TEST_PATH "/test/bin/uXX/pgbackrest"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_TZ]}"), STRDEF("// No timezone specified"));
|
||||||
|
|
||||||
|
strReplace(
|
||||||
|
testCDup,
|
||||||
|
STRDEF("{[C_INCLUDE]}"),
|
||||||
|
STRDEF(
|
||||||
|
"#include \"test/src/common/harnessShim.c\"\n"
|
||||||
|
"#include \"test/src/common/harnessError.c\"\n"
|
||||||
|
"#include \"../../../repo/test/src/common/include.c\""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_INCLUDE]}"), STRDEF("#include \"../../../repo/test/src/module/test/shimTest.c\""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_LIST]}"),
|
||||||
|
STRDEF(
|
||||||
|
"hrnAdd( 1, true);"));
|
||||||
|
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(testCDup));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
THROW_FMT(TestError, "no test for '%s'", strZ(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("Run test/shim and build again to cleanup coverage data");
|
||||||
|
|
||||||
|
HRN_SYSTEM(TEST_PATH "/test/unit-3/uXX/build/test-unit");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(
|
||||||
|
cmdTest(
|
||||||
|
STRDEF(TEST_PATH "/repo"), storagePathP(storageTest, STRDEF("test")), STRDEF("uXX"), 3,
|
||||||
|
STRDEF("test/shim"), 0, 1, logLevelDebug, true, NULL, true, true, true),
|
||||||
|
"new build");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("Test performance/type");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_Z(
|
||||||
|
storageTest, "repo/test/src/module/performance/typeTest.c",
|
||||||
|
"static void\n"
|
||||||
|
"testRun(void)\n"
|
||||||
|
"{\n"
|
||||||
|
" FUNCTION_HARNESS_VOID();\n"
|
||||||
|
"\n"
|
||||||
|
" if (testBegin(\"type\"))\n"
|
||||||
|
" {\n"
|
||||||
|
" }\n"
|
||||||
|
"\n"
|
||||||
|
" FUNCTION_HARNESS_RETURN_VOID();\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
HRN_SYSTEM("chmod 000 " TEST_PATH "/test/unit-3/uXX/build");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(
|
||||||
|
cmdTest(
|
||||||
|
STRDEF(TEST_PATH "/repo"), storagePathP(storageTest, STRDEF("test")), STRDEF("uXX"), 3,
|
||||||
|
STRDEF("performance/type"), 0, 1, logLevelDebug, true, STRDEF("America/New_York"), false, true, false),
|
||||||
|
"new build");
|
||||||
|
|
||||||
|
TEST_RESULT_LOG(
|
||||||
|
"P00 WARN: build failed for unit performance/type -- will retry: unable to list file info for path '" TEST_PATH
|
||||||
|
"/test/unit-3/uXX/build': [13] Permission denied");
|
||||||
|
|
||||||
|
storageUnit = storagePosixNewP(STRDEF(TEST_PATH "/test/unit-3/uXX"));
|
||||||
|
fileList = testStorageList(storageUnit);
|
||||||
|
|
||||||
|
TEST_RESULT_STRLST_Z(
|
||||||
|
fileList,
|
||||||
|
"meson.build\n"
|
||||||
|
"meson_options.txt\n"
|
||||||
|
"test/src/common/harnessError.c\n"
|
||||||
|
"test/src/common/harnessShim.c\n"
|
||||||
|
"test/src/common/shim.c\n"
|
||||||
|
"test.c\n",
|
||||||
|
"check files");
|
||||||
|
|
||||||
|
for (unsigned int fileIdx = 0; fileIdx < strLstSize(fileList); fileIdx++)
|
||||||
|
{
|
||||||
|
const String *const file = strLstGet(fileList, fileIdx);
|
||||||
|
|
||||||
|
if (strEqZ(file, "meson.build"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(
|
||||||
|
storageUnit, strZ(file),
|
||||||
|
zNewFmt(
|
||||||
|
"%s"
|
||||||
|
"add_global_arguments('-DHRN_FEATURE_ERROR', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DHRN_FEATURE_STACKTRACE', language : 'c')\n"
|
||||||
|
"add_global_arguments('-DTEST_CONTAINER_REQUIRED', language : 'c')\n"
|
||||||
|
"\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"# Unit test\n"
|
||||||
|
MESON_COMMENT_BLOCK "\n"
|
||||||
|
"src_unit = files(\n"
|
||||||
|
" '../../../repo/src/common/stackTrace.c',\n"
|
||||||
|
" '../../../repo/src/common/debug.c',\n"
|
||||||
|
" 'test/src/common/harnessError.c',\n"
|
||||||
|
" '../../../repo/test/src/common/harnessNoShim.c',\n"
|
||||||
|
" '../../../repo/test/src/common/harnessShim/sub.c',\n"
|
||||||
|
" 'test/src/common/harnessShim.c',\n"
|
||||||
|
" '../../../repo/test/src/common/harnessTest.c',\n"
|
||||||
|
" 'test.c',\n"
|
||||||
|
")\n"
|
||||||
|
"\n"
|
||||||
|
"executable(\n"
|
||||||
|
" 'test-unit',\n"
|
||||||
|
" sources: src_unit,\n"
|
||||||
|
" c_args: [\n"
|
||||||
|
" '-O2',\n"
|
||||||
|
" '-pg',\n"
|
||||||
|
" '-no-pie',\n"
|
||||||
|
" ],\n"
|
||||||
|
" link_args: [\n"
|
||||||
|
" '-pg',\n"
|
||||||
|
" '-no-pie',\n"
|
||||||
|
" ],\n"
|
||||||
|
" include_directories:\n"
|
||||||
|
" include_directories(\n"
|
||||||
|
" '.',\n"
|
||||||
|
" '../../../repo/src',\n"
|
||||||
|
" '../../../repo/test/src',\n"
|
||||||
|
" ),\n"
|
||||||
|
" dependencies: [\n"
|
||||||
|
" lib_bz2,\n"
|
||||||
|
" lib_openssl,\n"
|
||||||
|
" lib_lz4,\n"
|
||||||
|
" lib_pq,\n"
|
||||||
|
" lib_xml,\n"
|
||||||
|
" lib_yaml,\n"
|
||||||
|
" lib_z,\n"
|
||||||
|
" lib_zstd,\n"
|
||||||
|
" ],\n"
|
||||||
|
")\n",
|
||||||
|
strZ(mesonBuildRoot)));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "meson_options.txt"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), mesonOption);
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test/src/common/harnessError.c"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(harnessErrorC));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test/src/common/harnessShim.c"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(harnessShimC));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test/src/common/shim.c"))
|
||||||
|
{
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(shimC));
|
||||||
|
}
|
||||||
|
else if (strEqZ(file, "test.c"))
|
||||||
|
{
|
||||||
|
String *const testCDup = strCat(strNew(), testC);
|
||||||
|
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_CONTAINER]}"), STRDEF("true"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_DEBUG_TEST_TRACE]}"), STRDEF("// Debug test trace not enabled"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PATH_BUILD]}"), STRDEF(TEST_PATH "/test/unit-3/uXX/build"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROFILE]}"), STRDEF("true"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROJECT_EXE]}"), STRDEF(TEST_PATH "/test/bin/uXX/pgbackrest"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_TZ]}"), STRDEF("setenv(\"TZ\", \"America/New_York\", true);"));
|
||||||
|
|
||||||
|
strReplace(testCDup, STRDEF("{[C_INCLUDE]}"), STRDEF(""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_INCLUDE]}"),
|
||||||
|
STRDEF("#include \"../../../repo/test/src/module/performance/typeTest.c\""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_LIST]}"),
|
||||||
|
STRDEF(
|
||||||
|
"hrnAdd( 1, true);"));
|
||||||
|
|
||||||
|
TEST_STORAGE_GET(storageUnit, strZ(file), strZ(testCDup));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
THROW_FMT(TestError, "no test for '%s'", strZ(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("Test performance/type with profiling off for coverage");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(
|
||||||
|
cmdTest(
|
||||||
|
STRDEF(TEST_PATH "/repo"), storagePathP(storageTest, STRDEF("test")), STRDEF("uXX"), 3,
|
||||||
|
STRDEF("performance/type"), 0, 1, logLevelDebug, true, STRDEF("America/New_York"), false, false, false),
|
||||||
|
"new build");
|
||||||
|
|
||||||
|
storageUnit = storagePosixNewP(STRDEF(TEST_PATH "/test/unit-3/uXX"));
|
||||||
|
|
||||||
|
// Test one file to make sure profiling was not enabled
|
||||||
|
String *const testCDup = strCat(strNew(), testC);
|
||||||
|
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_CONTAINER]}"), STRDEF("true"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_DEBUG_TEST_TRACE]}"), STRDEF("// Debug test trace not enabled"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PATH_BUILD]}"), STRDEF(TEST_PATH "/test/unit-3/uXX/build"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROFILE]}"), STRDEF("false"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_PROJECT_EXE]}"), STRDEF(TEST_PATH "/test/bin/uXX/pgbackrest"));
|
||||||
|
strReplace(testCDup, STRDEF("{[C_TEST_TZ]}"), STRDEF("setenv(\"TZ\", \"America/New_York\", true);"));
|
||||||
|
|
||||||
|
strReplace(testCDup, STRDEF("{[C_INCLUDE]}"), STRDEF(""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_INCLUDE]}"),
|
||||||
|
STRDEF("#include \"../../../repo/test/src/module/performance/typeTest.c\""));
|
||||||
|
strReplace(
|
||||||
|
testCDup, STRDEF("{[C_TEST_LIST]}"),
|
||||||
|
STRDEF(
|
||||||
|
"hrnAdd( 1, true);"));
|
||||||
|
|
||||||
|
TEST_STORAGE_GET(storageUnit, "test.c", strZ(testCDup));
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("Fatal test error");
|
||||||
|
|
||||||
|
HRN_SYSTEM("chmod 000 " TEST_PATH "/repo/meson.build");
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
cmdTest(
|
||||||
|
STRDEF(TEST_PATH "/repo"), storagePathP(storageTest, STRDEF("test")), STRDEF("uXX"), 3,
|
||||||
|
STRDEF("performance/type"), 0, 1, logLevelDebug, true, STRDEF("America/New_York"), false, false, false),
|
||||||
|
FileOpenError,
|
||||||
|
"build failed for unit performance/type: unable to open file '" TEST_PATH "/repo/meson.build' for read: [13] Permission"
|
||||||
|
" denied");
|
||||||
|
|
||||||
|
TEST_RESULT_LOG(
|
||||||
|
"P00 WARN: build failed for unit performance/type -- will retry: unable to open file '" TEST_PATH "/repo/meson.build'"
|
||||||
|
" for read: [13] Permission denied");
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_HARNESS_RETURN_VOID();
|
||||||
|
}
|
@ -30,6 +30,7 @@ The test code is included directly so it can freely interact with the included C
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef HRN_FEATURE_ERROR
|
#ifdef HRN_FEATURE_ERROR
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user